Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendrawdib.c
Go to the documentation of this file.
00001 /* 00002 * Copyright 2000 Bradley Baetz 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00017 * 00018 * FIXME: Some flags are ignored 00019 * 00020 * Handle palettes 00021 */ 00022 00023 #include <stdarg.h> 00024 #include <stdio.h> 00025 #include <string.h> 00026 00027 #include "windef.h" 00028 #include "winbase.h" 00029 #include "wingdi.h" 00030 #include "winuser.h" 00031 #include "vfw.h" 00032 00033 #include "wine/debug.h" 00034 00035 WINE_DEFAULT_DEBUG_CHANNEL(msvideo); 00036 00037 typedef struct tagWINE_HDD { 00038 HDC hdc; 00039 INT dxDst; 00040 INT dyDst; 00041 LPBITMAPINFOHEADER lpbi; 00042 INT dxSrc; 00043 INT dySrc; 00044 HPALETTE hpal; /* Palette to use for the DIB */ 00045 BOOL begun; /* DrawDibBegin has been called */ 00046 LPBITMAPINFOHEADER lpbiOut; /* Output format */ 00047 HIC hic; /* HIC for decompression */ 00048 HDC hMemDC; /* DC for buffering */ 00049 HBITMAP hOldDib; /* Original Dib */ 00050 HBITMAP hDib; /* DibSection */ 00051 LPVOID lpvbits; /* Buffer for holding decompressed dib */ 00052 HDRAWDIB hSelf; 00053 struct tagWINE_HDD* next; 00054 } WINE_HDD; 00055 00056 static int num_colours(const BITMAPINFOHEADER *lpbi) 00057 { 00058 if(lpbi->biClrUsed) 00059 return lpbi->biClrUsed; 00060 if(lpbi->biBitCount<=8) 00061 return 1<<lpbi->biBitCount; 00062 return 0; 00063 } 00064 00065 static WINE_HDD* HDD_FirstHdd /* = NULL */; 00066 00067 static WINE_HDD* MSVIDEO_GetHddPtr(HDRAWDIB hd) 00068 { 00069 WINE_HDD* hdd; 00070 00071 for (hdd = HDD_FirstHdd; hdd != NULL && hdd->hSelf != hd; hdd = hdd->next); 00072 return hdd; 00073 } 00074 00075 static UINT_PTR HDD_HandleRef = 1; 00076 00077 /*********************************************************************** 00078 * DrawDibOpen [MSVFW32.@] 00079 */ 00080 HDRAWDIB VFWAPI DrawDibOpen(void) 00081 { 00082 WINE_HDD* whdd; 00083 00084 TRACE("(void)\n"); 00085 00086 whdd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_HDD)); 00087 TRACE("=> %p\n", whdd); 00088 00089 while (MSVIDEO_GetHddPtr((HDRAWDIB)HDD_HandleRef) != NULL) HDD_HandleRef++; 00090 whdd->hSelf = (HDRAWDIB)HDD_HandleRef++; 00091 00092 whdd->next = HDD_FirstHdd; 00093 HDD_FirstHdd = whdd; 00094 00095 return whdd->hSelf; 00096 } 00097 00098 /*********************************************************************** 00099 * DrawDibClose [MSVFW32.@] 00100 */ 00101 BOOL VFWAPI DrawDibClose(HDRAWDIB hdd) 00102 { 00103 WINE_HDD* whdd = MSVIDEO_GetHddPtr(hdd); 00104 WINE_HDD** p; 00105 00106 TRACE("(%p)\n", hdd); 00107 00108 if (!whdd) return FALSE; 00109 00110 if (whdd->begun) DrawDibEnd(hdd); 00111 00112 for (p = &HDD_FirstHdd; *p != NULL; p = &((*p)->next)) 00113 { 00114 if (*p == whdd) 00115 { 00116 *p = whdd->next; 00117 break; 00118 } 00119 } 00120 00121 HeapFree(GetProcessHeap(), 0, whdd); 00122 00123 return TRUE; 00124 } 00125 00126 /*********************************************************************** 00127 * DrawDibEnd [MSVFW32.@] 00128 */ 00129 BOOL VFWAPI DrawDibEnd(HDRAWDIB hdd) 00130 { 00131 BOOL ret = TRUE; 00132 WINE_HDD *whdd = MSVIDEO_GetHddPtr(hdd); 00133 00134 TRACE("(%p)\n", hdd); 00135 00136 if (!whdd) return FALSE; 00137 00138 whdd->hpal = 0; /* Do not free this */ 00139 whdd->hdc = 0; 00140 HeapFree(GetProcessHeap(), 0, whdd->lpbi); 00141 whdd->lpbi = NULL; 00142 HeapFree(GetProcessHeap(), 0, whdd->lpbiOut); 00143 whdd->lpbiOut = NULL; 00144 00145 whdd->begun = FALSE; 00146 00147 /*if (whdd->lpvbits) 00148 HeapFree(GetProcessHeap(), 0, whdd->lpvbuf);*/ 00149 00150 if (whdd->hMemDC) 00151 { 00152 SelectObject(whdd->hMemDC, whdd->hOldDib); 00153 DeleteDC(whdd->hMemDC); 00154 whdd->hMemDC = 0; 00155 } 00156 00157 if (whdd->hDib) DeleteObject(whdd->hDib); 00158 whdd->hDib = 0; 00159 00160 if (whdd->hic) 00161 { 00162 ICDecompressEnd(whdd->hic); 00163 ICClose(whdd->hic); 00164 whdd->hic = 0; 00165 } 00166 00167 whdd->lpvbits = NULL; 00168 00169 return ret; 00170 } 00171 00172 /*********************************************************************** 00173 * DrawDibBegin [MSVFW32.@] 00174 */ 00175 BOOL VFWAPI DrawDibBegin(HDRAWDIB hdd, 00176 HDC hdc, 00177 INT dxDst, 00178 INT dyDst, 00179 LPBITMAPINFOHEADER lpbi, 00180 INT dxSrc, 00181 INT dySrc, 00182 UINT wFlags) 00183 { 00184 BOOL ret = TRUE; 00185 WINE_HDD *whdd; 00186 00187 TRACE("(%p,%p,%d,%d,%p,%d,%d,0x%08x)\n", 00188 hdd, hdc, dxDst, dyDst, lpbi, dxSrc, dySrc, wFlags); 00189 00190 TRACE("lpbi: %d,%d/%d,%d,%d,%d,%d,%d,%d,%d,%d\n", 00191 lpbi->biSize, lpbi->biWidth, lpbi->biHeight, lpbi->biPlanes, 00192 lpbi->biBitCount, lpbi->biCompression, lpbi->biSizeImage, 00193 lpbi->biXPelsPerMeter, lpbi->biYPelsPerMeter, lpbi->biClrUsed, 00194 lpbi->biClrImportant); 00195 00196 if (wFlags & ~(DDF_BUFFER)) 00197 FIXME("wFlags == 0x%08x not handled\n", wFlags & ~(DDF_BUFFER)); 00198 00199 whdd = MSVIDEO_GetHddPtr(hdd); 00200 if (!whdd) return FALSE; 00201 00202 if (whdd->begun) DrawDibEnd(hdd); 00203 00204 if (lpbi->biCompression) 00205 { 00206 DWORD size = 0; 00207 00208 whdd->hic = ICOpen(ICTYPE_VIDEO, lpbi->biCompression, ICMODE_DECOMPRESS); 00209 if (!whdd->hic) 00210 { 00211 WARN("Could not open IC. biCompression == 0x%08x\n", lpbi->biCompression); 00212 ret = FALSE; 00213 } 00214 00215 if (ret) 00216 { 00217 size = ICDecompressGetFormat(whdd->hic, lpbi, NULL); 00218 if (size == ICERR_UNSUPPORTED) 00219 { 00220 WARN("Codec doesn't support GetFormat, giving up.\n"); 00221 ret = FALSE; 00222 } 00223 } 00224 00225 if (ret) 00226 { 00227 whdd->lpbiOut = HeapAlloc(GetProcessHeap(), 0, size); 00228 00229 if (ICDecompressGetFormat(whdd->hic, lpbi, whdd->lpbiOut) != ICERR_OK) 00230 ret = FALSE; 00231 } 00232 00233 if (ret) 00234 { 00235 /* FIXME: Use Ex functions if available? */ 00236 if (ICDecompressBegin(whdd->hic, lpbi, whdd->lpbiOut) != ICERR_OK) 00237 ret = FALSE; 00238 00239 TRACE("biSizeImage == %d\n", whdd->lpbiOut->biSizeImage); 00240 TRACE("biCompression == %d\n", whdd->lpbiOut->biCompression); 00241 TRACE("biBitCount == %d\n", whdd->lpbiOut->biBitCount); 00242 } 00243 } 00244 else 00245 { 00246 DWORD dwSize; 00247 /* No compression */ 00248 TRACE("Not compressed!\n"); 00249 dwSize = lpbi->biSize + num_colours(lpbi)*sizeof(RGBQUAD); 00250 whdd->lpbiOut = HeapAlloc(GetProcessHeap(), 0, dwSize); 00251 memcpy(whdd->lpbiOut, lpbi, dwSize); 00252 } 00253 00254 if (ret) 00255 { 00256 /*whdd->lpvbuf = HeapAlloc(GetProcessHeap(), 0, whdd->lpbiOut->biSizeImage);*/ 00257 00258 whdd->hMemDC = CreateCompatibleDC(hdc); 00259 TRACE("Creating: %d, %p\n", whdd->lpbiOut->biSize, whdd->lpvbits); 00260 whdd->hDib = CreateDIBSection(whdd->hMemDC, (BITMAPINFO *)whdd->lpbiOut, DIB_RGB_COLORS, &(whdd->lpvbits), 0, 0); 00261 if (whdd->hDib) 00262 { 00263 TRACE("Created: %p,%p\n", whdd->hDib, whdd->lpvbits); 00264 } 00265 else 00266 { 00267 ret = FALSE; 00268 TRACE("Error: %d\n", GetLastError()); 00269 } 00270 whdd->hOldDib = SelectObject(whdd->hMemDC, whdd->hDib); 00271 } 00272 00273 if (ret) 00274 { 00275 whdd->hdc = hdc; 00276 whdd->dxDst = dxDst; 00277 whdd->dyDst = dyDst; 00278 whdd->lpbi = HeapAlloc(GetProcessHeap(), 0, lpbi->biSize); 00279 memcpy(whdd->lpbi, lpbi, lpbi->biSize); 00280 whdd->dxSrc = dxSrc; 00281 whdd->dySrc = dySrc; 00282 whdd->begun = TRUE; 00283 whdd->hpal = 0; 00284 } 00285 else 00286 { 00287 if (whdd->hic) 00288 ICClose(whdd->hic); 00289 HeapFree(GetProcessHeap(), 0, whdd->lpbiOut); 00290 whdd->lpbiOut = NULL; 00291 } 00292 00293 return ret; 00294 } 00295 00296 /********************************************************************** 00297 * DrawDibDraw [MSVFW32.@] 00298 */ 00299 BOOL VFWAPI DrawDibDraw(HDRAWDIB hdd, HDC hdc, 00300 INT xDst, INT yDst, INT dxDst, INT dyDst, 00301 LPBITMAPINFOHEADER lpbi, 00302 LPVOID lpBits, 00303 INT xSrc, INT ySrc, INT dxSrc, INT dySrc, 00304 UINT wFlags) 00305 { 00306 WINE_HDD *whdd; 00307 BOOL ret = TRUE; 00308 00309 TRACE("(%p,%p,%d,%d,%d,%d,%p,%p,%d,%d,%d,%d,0x%08x)\n", 00310 hdd, hdc, xDst, yDst, dxDst, dyDst, lpbi, lpBits, xSrc, ySrc, dxSrc, dySrc, wFlags); 00311 00312 whdd = MSVIDEO_GetHddPtr(hdd); 00313 if (!whdd) return FALSE; 00314 00315 TRACE("whdd=%p\n", whdd); 00316 00317 if (wFlags & ~(DDF_SAME_HDC | DDF_SAME_DRAW | DDF_NOTKEYFRAME | DDF_UPDATE | DDF_DONTDRAW | DDF_BACKGROUNDPAL)) 00318 FIXME("wFlags == 0x%08x not handled\n", wFlags); 00319 00320 if (!lpBits) 00321 { 00322 /* Undocumented? */ 00323 lpBits = (LPSTR)lpbi + (WORD)(lpbi->biSize) + (WORD)(num_colours(lpbi)*sizeof(RGBQUAD)); 00324 } 00325 00326 00327 #define CHANGED(x) (whdd->x != x) 00328 00329 if ((!whdd->begun) || 00330 (!(wFlags & DDF_SAME_HDC) && CHANGED(hdc)) || 00331 (!(wFlags & DDF_SAME_DRAW) && (CHANGED(lpbi) || CHANGED(dxSrc) || CHANGED(dySrc) || CHANGED(dxDst) || CHANGED(dyDst)))) 00332 { 00333 TRACE("Something changed!\n"); 00334 ret = DrawDibBegin(hdd, hdc, dxDst, dyDst, lpbi, dxSrc, dySrc, 0); 00335 } 00336 00337 #undef CHANGED 00338 00339 if ((dxDst == -1) && (dyDst == -1)) 00340 { 00341 dxDst = dxSrc; 00342 dyDst = dySrc; 00343 } 00344 00345 if (!(wFlags & DDF_UPDATE)) 00346 { 00347 DWORD biSizeImage = lpbi->biSizeImage; 00348 00349 /* biSizeImage may be set to 0 for BI_RGB (uncompressed) bitmaps */ 00350 if ((lpbi->biCompression == BI_RGB) && (biSizeImage == 0)) 00351 biSizeImage = ((lpbi->biWidth * lpbi->biBitCount + 31) / 32) * 4 * lpbi->biHeight; 00352 00353 if (lpbi->biCompression) 00354 { 00355 DWORD flags = 0; 00356 00357 TRACE("Compression == 0x%08x\n", lpbi->biCompression); 00358 00359 if (wFlags & DDF_NOTKEYFRAME) 00360 flags |= ICDECOMPRESS_NOTKEYFRAME; 00361 00362 ICDecompress(whdd->hic, flags, lpbi, lpBits, whdd->lpbiOut, whdd->lpvbits); 00363 } 00364 else 00365 { 00366 memcpy(whdd->lpvbits, lpBits, biSizeImage); 00367 } 00368 } 00369 if (!(wFlags & DDF_DONTDRAW) && whdd->hpal) 00370 { 00371 if ((wFlags & DDF_BACKGROUNDPAL) && ! (wFlags & DDF_SAME_HDC)) 00372 SelectPalette(hdc, whdd->hpal, TRUE); 00373 else 00374 SelectPalette(hdc, whdd->hpal, FALSE); 00375 } 00376 00377 if (!(StretchBlt(whdd->hdc, xDst, yDst, dxDst, dyDst, whdd->hMemDC, xSrc, ySrc, dxSrc, dySrc, SRCCOPY))) 00378 ret = FALSE; 00379 00380 return ret; 00381 } 00382 00383 /************************************************************************* 00384 * DrawDibStart [MSVFW32.@] 00385 */ 00386 BOOL VFWAPI DrawDibStart(HDRAWDIB hdd, DWORD rate) { 00387 FIXME("(%p, %d), stub\n", hdd, rate); 00388 return TRUE; 00389 } 00390 00391 /************************************************************************* 00392 * DrawDibStop [MSVFW32.@] 00393 */ 00394 BOOL VFWAPI DrawDibStop(HDRAWDIB hdd) { 00395 FIXME("(%p), stub\n", hdd); 00396 return TRUE; 00397 } 00398 00399 /*********************************************************************** 00400 * DrawDibChangePalette [MSVFW32.@] 00401 */ 00402 BOOL VFWAPI DrawDibChangePalette(HDRAWDIB hdd, int iStart, int iLen, LPPALETTEENTRY lppe) 00403 { 00404 FIXME("(%p, 0x%08x, 0x%08x, %p), stub\n", hdd, iStart, iLen, lppe); 00405 return TRUE; 00406 } 00407 00408 /*********************************************************************** 00409 * DrawDibSetPalette [MSVFW32.@] 00410 */ 00411 BOOL VFWAPI DrawDibSetPalette(HDRAWDIB hdd, HPALETTE hpal) 00412 { 00413 WINE_HDD *whdd; 00414 00415 TRACE("(%p, %p)\n", hdd, hpal); 00416 00417 whdd = MSVIDEO_GetHddPtr(hdd); 00418 if (!whdd) return FALSE; 00419 00420 whdd->hpal = hpal; 00421 00422 if (whdd->begun) 00423 { 00424 SelectPalette(whdd->hdc, hpal, 0); 00425 RealizePalette(whdd->hdc); 00426 } 00427 00428 return TRUE; 00429 } 00430 00431 /*********************************************************************** 00432 * DrawDibGetBuffer [MSVFW32.@] 00433 */ 00434 LPVOID VFWAPI DrawDibGetBuffer(HDRAWDIB hdd, LPBITMAPINFOHEADER lpbi, DWORD dwSize, DWORD dwFlags) 00435 { 00436 FIXME("(%p, %p, 0x%08x, 0x%08x), stub\n", hdd, lpbi, dwSize, dwFlags); 00437 return NULL; 00438 } 00439 00440 /*********************************************************************** 00441 * DrawDibGetPalette [MSVFW32.@] 00442 */ 00443 HPALETTE VFWAPI DrawDibGetPalette(HDRAWDIB hdd) 00444 { 00445 WINE_HDD *whdd; 00446 00447 TRACE("(%p)\n", hdd); 00448 00449 whdd = MSVIDEO_GetHddPtr(hdd); 00450 if (!whdd) return FALSE; 00451 00452 return whdd->hpal; 00453 } 00454 00455 /*********************************************************************** 00456 * DrawDibRealize [MSVFW32.@] 00457 */ 00458 UINT VFWAPI DrawDibRealize(HDRAWDIB hdd, HDC hdc, BOOL fBackground) 00459 { 00460 WINE_HDD *whdd; 00461 UINT ret = 0; 00462 00463 FIXME("(%p, %p, %d), stub\n", hdd, hdc, fBackground); 00464 00465 whdd = MSVIDEO_GetHddPtr(hdd); 00466 if (!whdd) return FALSE; 00467 00468 if (!whdd || !(whdd->begun)) 00469 { 00470 ret = 0; 00471 goto out; 00472 } 00473 00474 if (!whdd->hpal) 00475 whdd->hpal = CreateHalftonePalette(hdc); 00476 00477 SelectPalette(hdc, whdd->hpal, fBackground); 00478 ret = RealizePalette(hdc); 00479 00480 out: 00481 TRACE("=> %u\n", ret); 00482 return ret; 00483 } 00484 00485 /*********************************************************************** 00486 * DrawDibTime [MSVFW32.@] 00487 */ 00488 BOOL VFWAPI DrawDibTime(HDRAWDIB hdd, LPDRAWDIBTIME lpddtime) 00489 { 00490 FIXME("(%p, %p) stub\n", hdd, lpddtime); 00491 return FALSE; 00492 } 00493 00494 /*********************************************************************** 00495 * DrawDibProfileDisplay [MSVFW32.@] 00496 */ 00497 DWORD VFWAPI DrawDibProfileDisplay(LPBITMAPINFOHEADER lpbi) 00498 { 00499 FIXME("(%p) stub\n", lpbi); 00500 00501 return PD_CAN_DRAW_DIB; 00502 } Generated on Sat May 26 2012 04:23:53 for ReactOS by
1.7.6.1
|