2 * Copyright 2000 Bradley Baetz
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 * FIXME: Some flags are ignored
33 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(msvideo);
37 typedef struct tagWINE_HDD {
41 LPBITMAPINFOHEADER lpbi;
44 HPALETTE hpal; /* Palette to use for the DIB */
45 BOOL begun; /* DrawDibBegin has been called */
46 LPBITMAPINFOHEADER lpbiOut; /* Output format */
47 HIC hic; /* HIC for decompression */
48 HDC hMemDC; /* DC for buffering */
49 HBITMAP hOldDib; /* Original Dib */
50 HBITMAP hDib; /* DibSection */
51 LPVOID lpvbits; /* Buffer for holding decompressed dib */
53 struct tagWINE_HDD* next;
56 static int num_colours(const BITMAPINFOHEADER *lpbi)
59 return lpbi->biClrUsed;
60 if(lpbi->biBitCount<=8)
61 return 1<<lpbi->biBitCount;
65 static WINE_HDD* HDD_FirstHdd /* = NULL */;
67 static WINE_HDD* MSVIDEO_GetHddPtr(HDRAWDIB hd)
71 for (hdd = HDD_FirstHdd; hdd != NULL && hdd->hSelf != hd; hdd = hdd->next);
75 static DWORD HDD_HandleRef = 1;
77 /***********************************************************************
78 * DrawDibOpen [MSVFW32.@]
80 HDRAWDIB VFWAPI DrawDibOpen(void)
86 whdd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_HDD));
87 TRACE("=> %p\n", whdd);
89 while (MSVIDEO_GetHddPtr((HDRAWDIB)HDD_HandleRef) != NULL) HDD_HandleRef++;
90 whdd->hSelf = (HDRAWDIB)HDD_HandleRef++;
92 whdd->next = HDD_FirstHdd;
98 /***********************************************************************
99 * DrawDibClose [MSVFW32.@]
101 BOOL VFWAPI DrawDibClose(HDRAWDIB hdd)
103 WINE_HDD* whdd = MSVIDEO_GetHddPtr(hdd);
106 TRACE("(%p)\n", hdd);
108 if (!whdd) return FALSE;
110 if (whdd->begun) DrawDibEnd(hdd);
112 for (p = &HDD_FirstHdd; *p != NULL; p = &((*p)->next))
121 HeapFree(GetProcessHeap(), 0, whdd);
126 /***********************************************************************
127 * DrawDibEnd [MSVFW32.@]
129 BOOL VFWAPI DrawDibEnd(HDRAWDIB hdd)
132 WINE_HDD *whdd = MSVIDEO_GetHddPtr(hdd);
134 TRACE("(%p)\n", hdd);
136 if (!whdd) return FALSE;
138 whdd->hpal = 0; /* Do not free this */
140 HeapFree(GetProcessHeap(), 0, whdd->lpbi);
142 HeapFree(GetProcessHeap(), 0, whdd->lpbiOut);
143 whdd->lpbiOut = NULL;
148 HeapFree(GetProcessHeap(), 0, whdd->lpvbuf);*/
152 SelectObject(whdd->hMemDC, whdd->hOldDib);
153 DeleteDC(whdd->hMemDC);
157 if (whdd->hDib) DeleteObject(whdd->hDib);
162 ICDecompressEnd(whdd->hic);
167 whdd->lpvbits = NULL;
172 /***********************************************************************
173 * DrawDibBegin [MSVFW32.@]
175 BOOL VFWAPI DrawDibBegin(HDRAWDIB hdd,
179 LPBITMAPINFOHEADER lpbi,
187 TRACE("(%p,%p,%d,%d,%p,%d,%d,0x%08x)\n",
188 hdd, hdc, dxDst, dyDst, lpbi, dxSrc, dySrc, wFlags);
190 TRACE("lpbi: %d,%d/%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
191 lpbi->biSize, lpbi->biWidth, lpbi->biHeight, lpbi->biPlanes,
192 lpbi->biBitCount, lpbi->biCompression, lpbi->biSizeImage,
193 lpbi->biXPelsPerMeter, lpbi->biYPelsPerMeter, lpbi->biClrUsed,
194 lpbi->biClrImportant);
196 if (wFlags & ~(DDF_BUFFER))
197 FIXME("wFlags == 0x%08x not handled\n", wFlags & ~(DDF_BUFFER));
199 whdd = MSVIDEO_GetHddPtr(hdd);
200 if (!whdd) return FALSE;
202 if (whdd->begun) DrawDibEnd(hdd);
204 if (lpbi->biCompression)
208 whdd->hic = ICOpen(ICTYPE_VIDEO, lpbi->biCompression, ICMODE_DECOMPRESS);
211 WARN("Could not open IC. biCompression == 0x%08x\n", lpbi->biCompression);
217 size = ICDecompressGetFormat(whdd->hic, lpbi, NULL);
218 if (size == ICERR_UNSUPPORTED)
220 WARN("Codec doesn't support GetFormat, giving up.\n");
227 whdd->lpbiOut = HeapAlloc(GetProcessHeap(), 0, size);
229 if (ICDecompressGetFormat(whdd->hic, lpbi, whdd->lpbiOut) != ICERR_OK)
235 /* FIXME: Use Ex functions if available? */
236 if (ICDecompressBegin(whdd->hic, lpbi, whdd->lpbiOut) != ICERR_OK)
239 TRACE("biSizeImage == %d\n", whdd->lpbiOut->biSizeImage);
240 TRACE("biCompression == %d\n", whdd->lpbiOut->biCompression);
241 TRACE("biBitCount == %d\n", whdd->lpbiOut->biBitCount);
248 TRACE("Not compressed!\n");
249 dwSize = lpbi->biSize + num_colours(lpbi)*sizeof(RGBQUAD);
250 whdd->lpbiOut = HeapAlloc(GetProcessHeap(), 0, dwSize);
251 memcpy(whdd->lpbiOut, lpbi, dwSize);
256 /*whdd->lpvbuf = HeapAlloc(GetProcessHeap(), 0, whdd->lpbiOut->biSizeImage);*/
258 whdd->hMemDC = CreateCompatibleDC(hdc);
259 TRACE("Creating: %d, %p\n", whdd->lpbiOut->biSize, whdd->lpvbits);
260 whdd->hDib = CreateDIBSection(whdd->hMemDC, (BITMAPINFO *)whdd->lpbiOut, DIB_RGB_COLORS, &(whdd->lpvbits), 0, 0);
263 TRACE("Created: %p,%p\n", whdd->hDib, whdd->lpvbits);
268 TRACE("Error: %d\n", GetLastError());
270 whdd->hOldDib = SelectObject(whdd->hMemDC, whdd->hDib);
278 whdd->lpbi = HeapAlloc(GetProcessHeap(), 0, lpbi->biSize);
279 memcpy(whdd->lpbi, lpbi, lpbi->biSize);
289 HeapFree(GetProcessHeap(), 0, whdd->lpbiOut);
290 whdd->lpbiOut = NULL;
296 /**********************************************************************
297 * DrawDibDraw [MSVFW32.@]
299 BOOL VFWAPI DrawDibDraw(HDRAWDIB hdd, HDC hdc,
300 INT xDst, INT yDst, INT dxDst, INT dyDst,
301 LPBITMAPINFOHEADER lpbi,
303 INT xSrc, INT ySrc, INT dxSrc, INT dySrc,
309 TRACE("(%p,%p,%d,%d,%d,%d,%p,%p,%d,%d,%d,%d,0x%08x)\n",
310 hdd, hdc, xDst, yDst, dxDst, dyDst, lpbi, lpBits, xSrc, ySrc, dxSrc, dySrc, wFlags);
312 whdd = MSVIDEO_GetHddPtr(hdd);
313 if (!whdd) return FALSE;
315 TRACE("whdd=%p\n", whdd);
317 if (wFlags & ~(DDF_SAME_HDC | DDF_SAME_DRAW | DDF_NOTKEYFRAME | DDF_UPDATE | DDF_DONTDRAW | DDF_BACKGROUNDPAL))
318 FIXME("wFlags == 0x%08x not handled\n", wFlags);
323 lpBits = (LPSTR)lpbi + (WORD)(lpbi->biSize) + (WORD)(num_colours(lpbi)*sizeof(RGBQUAD));
327 #define CHANGED(x) (whdd->x != x)
329 if ((!whdd->begun) ||
330 (!(wFlags & DDF_SAME_HDC) && CHANGED(hdc)) ||
331 (!(wFlags & DDF_SAME_DRAW) && (CHANGED(lpbi) || CHANGED(dxSrc) || CHANGED(dySrc) || CHANGED(dxDst) || CHANGED(dyDst))))
333 TRACE("Something changed!\n");
334 ret = DrawDibBegin(hdd, hdc, dxDst, dyDst, lpbi, dxSrc, dySrc, 0);
339 if ((dxDst == -1) && (dyDst == -1))
345 if (!(wFlags & DDF_UPDATE))
347 DWORD biSizeImage = lpbi->biSizeImage;
349 /* biSizeImage may be set to 0 for BI_RGB (uncompressed) bitmaps */
350 if ((lpbi->biCompression == BI_RGB) && (biSizeImage == 0))
351 biSizeImage = ((lpbi->biWidth * lpbi->biBitCount + 31) / 32) * 4 * lpbi->biHeight;
353 if (lpbi->biCompression)
357 TRACE("Compression == 0x%08x\n", lpbi->biCompression);
359 if (wFlags & DDF_NOTKEYFRAME)
360 flags |= ICDECOMPRESS_NOTKEYFRAME;
362 ICDecompress(whdd->hic, flags, lpbi, lpBits, whdd->lpbiOut, whdd->lpvbits);
366 memcpy(whdd->lpvbits, lpBits, biSizeImage);
369 if (!(wFlags & DDF_DONTDRAW) && whdd->hpal)
371 if ((wFlags & DDF_BACKGROUNDPAL) && ! (wFlags & DDF_SAME_HDC))
372 SelectPalette(hdc, whdd->hpal, TRUE);
374 SelectPalette(hdc, whdd->hpal, FALSE);
377 if (!(StretchBlt(whdd->hdc, xDst, yDst, dxDst, dyDst, whdd->hMemDC, xSrc, ySrc, dxSrc, dySrc, SRCCOPY)))
383 /*************************************************************************
384 * DrawDibStart [MSVFW32.@]
386 BOOL VFWAPI DrawDibStart(HDRAWDIB hdd, DWORD rate) {
387 FIXME("(%p, %d), stub\n", hdd, rate);
391 /*************************************************************************
392 * DrawDibStop [MSVFW32.@]
394 BOOL VFWAPI DrawDibStop(HDRAWDIB hdd) {
395 FIXME("(%p), stub\n", hdd);
399 /***********************************************************************
400 * DrawDibChangePalette [MSVFW32.@]
402 BOOL VFWAPI DrawDibChangePalette(HDRAWDIB hdd, int iStart, int iLen, LPPALETTEENTRY lppe)
404 FIXME("(%p, 0x%08x, 0x%08x, %p), stub\n", hdd, iStart, iLen, lppe);
408 /***********************************************************************
409 * DrawDibSetPalette [MSVFW32.@]
411 BOOL VFWAPI DrawDibSetPalette(HDRAWDIB hdd, HPALETTE hpal)
415 TRACE("(%p, %p)\n", hdd, hpal);
417 whdd = MSVIDEO_GetHddPtr(hdd);
418 if (!whdd) return FALSE;
424 SelectPalette(whdd->hdc, hpal, 0);
425 RealizePalette(whdd->hdc);
431 /***********************************************************************
432 * DrawDibGetBuffer [MSVFW32.@]
434 LPVOID VFWAPI DrawDibGetBuffer(HDRAWDIB hdd, LPBITMAPINFOHEADER lpbi, DWORD dwSize, DWORD dwFlags)
436 FIXME("(%p, %p, 0x%08x, 0x%08x), stub\n", hdd, lpbi, dwSize, dwFlags);
440 /***********************************************************************
441 * DrawDibGetPalette [MSVFW32.@]
443 HPALETTE VFWAPI DrawDibGetPalette(HDRAWDIB hdd)
447 TRACE("(%p)\n", hdd);
449 whdd = MSVIDEO_GetHddPtr(hdd);
450 if (!whdd) return FALSE;
455 /***********************************************************************
456 * DrawDibRealize [MSVFW32.@]
458 UINT VFWAPI DrawDibRealize(HDRAWDIB hdd, HDC hdc, BOOL fBackground)
463 FIXME("(%p, %p, %d), stub\n", hdd, hdc, fBackground);
465 whdd = MSVIDEO_GetHddPtr(hdd);
466 if (!whdd) return FALSE;
468 if (!whdd || !(whdd->begun))
475 whdd->hpal = CreateHalftonePalette(hdc);
477 SelectPalette(hdc, whdd->hpal, fBackground);
478 ret = RealizePalette(hdc);
481 TRACE("=> %u\n", ret);
485 /***********************************************************************
486 * DrawDibTime [MSVFW32.@]
488 BOOL VFWAPI DrawDibTime(HDRAWDIB hdd, LPDRAWDIBTIME lpddtime)
490 FIXME("(%p, %p) stub\n", hdd, lpddtime);
494 /***********************************************************************
495 * DrawDibProfileDisplay [MSVFW32.@]
497 DWORD VFWAPI DrawDibProfileDisplay(LPBITMAPINFOHEADER lpbi)
499 FIXME("(%p) stub\n", lpbi);
501 return PD_CAN_DRAW_DIB;