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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * FIXME: Some flags are ignored
24 #include "msvideo_private.h"
29 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(msvideo);
33 typedef struct tagWINE_HDD {
37 LPBITMAPINFOHEADER lpbi;
40 HPALETTE hpal; /* Palette to use for the DIB */
41 BOOL begun; /* DrawDibBegin has been called */
42 LPBITMAPINFOHEADER lpbiOut; /* Output format */
43 HIC hic; /* HIC for decompression */
44 HDC hMemDC; /* DC for buffering */
45 HBITMAP hOldDib; /* Original Dib */
46 HBITMAP hDib; /* DibSection */
47 LPVOID lpvbits; /* Buffer for holding decompressed dib */
49 struct tagWINE_HDD* next;
52 int num_colours(LPBITMAPINFOHEADER lpbi)
55 return lpbi->biClrUsed;
56 if(lpbi->biBitCount<=8)
57 return 1<<lpbi->biBitCount;
61 static WINE_HDD* HDD_FirstHdd /* = NULL */;
63 static WINE_HDD* MSVIDEO_GetHddPtr(HDRAWDIB hd)
67 for (hdd = HDD_FirstHdd; hdd != NULL && hdd->hSelf != hdd; hdd = hdd->next);
71 static DWORD HDD_HandleRef = 1;
73 /***********************************************************************
74 * DrawDibOpen [MSVFW32.@]
76 HDRAWDIB VFWAPI DrawDibOpen(void)
82 whdd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_HDD));
83 TRACE("=> %p\n", whdd);
85 while (MSVIDEO_GetHddPtr((HDRAWDIB)HDD_HandleRef) != NULL) HDD_HandleRef++;
86 whdd->hSelf = (HDRAWDIB)HDD_HandleRef++;
88 whdd->next = HDD_FirstHdd;
94 /***********************************************************************
95 * DrawDibClose [MSVFW32.@]
97 BOOL VFWAPI DrawDibClose(HDRAWDIB hdd)
99 WINE_HDD* whdd = MSVIDEO_GetHddPtr(hdd);
101 TRACE("(%p)\n", hdd);
103 if (!whdd) return FALSE;
105 if (whdd->begun) DrawDibEnd(hdd);
107 HeapFree(GetProcessHeap(), 0, whdd);
112 /***********************************************************************
113 * DrawDibEnd [MSVFW32.@]
115 BOOL VFWAPI DrawDibEnd(HDRAWDIB hdd)
118 WINE_HDD *whdd = MSVIDEO_GetHddPtr(hdd);
120 TRACE("(%p)\n", hdd);
122 whdd->hpal = 0; /* Do not free this */
126 HeapFree(GetProcessHeap(), 0, whdd->lpbi);
131 HeapFree(GetProcessHeap(), 0, whdd->lpbiOut);
132 whdd->lpbiOut = NULL;
138 HeapFree(GetProcessHeap(), 0, whdd->lpvbuf);*/
142 SelectObject(whdd->hMemDC, whdd->hOldDib);
143 DeleteDC(whdd->hMemDC);
147 if (whdd->hDib) DeleteObject(whdd->hDib);
152 ICDecompressEnd(whdd->hic);
157 whdd->lpvbits = NULL;
162 /***********************************************************************
163 * DrawDibBegin [MSVFW32.@]
165 BOOL VFWAPI DrawDibBegin(HDRAWDIB hdd,
169 LPBITMAPINFOHEADER lpbi,
177 TRACE("(%p,%p,%d,%d,%p,%d,%d,0x%08lx)\n",
178 hdd, hdc, dxDst, dyDst, lpbi, dxSrc, dySrc, (DWORD)wFlags);
180 TRACE("lpbi: %ld,%ld/%ld,%d,%d,%ld,%ld,%ld,%ld,%ld,%ld\n",
181 lpbi->biSize, lpbi->biWidth, lpbi->biHeight, lpbi->biPlanes,
182 lpbi->biBitCount, lpbi->biCompression, lpbi->biSizeImage,
183 lpbi->biXPelsPerMeter, lpbi->biYPelsPerMeter, lpbi->biClrUsed,
184 lpbi->biClrImportant);
186 if (wFlags & ~(DDF_BUFFER))
187 FIXME("wFlags == 0x%08x not handled\n", wFlags & ~(DDF_BUFFER));
189 whdd = MSVIDEO_GetHddPtr(hdd);
190 if (!whdd) return FALSE;
192 if (whdd->begun) DrawDibEnd(hdd);
194 if (lpbi->biCompression)
198 whdd->hic = ICOpen(ICTYPE_VIDEO, lpbi->biCompression, ICMODE_DECOMPRESS);
201 WARN("Could not open IC. biCompression == 0x%08lx\n", lpbi->biCompression);
207 size = ICDecompressGetFormat(whdd->hic, lpbi, NULL);
208 if (size == ICERR_UNSUPPORTED)
210 WARN("Codec doesn't support GetFormat, giving up.\n");
217 whdd->lpbiOut = HeapAlloc(GetProcessHeap(), 0, size);
219 if (ICDecompressGetFormat(whdd->hic, lpbi, whdd->lpbiOut) != ICERR_OK)
225 /* FIXME: Use Ex functions if available? */
226 if (ICDecompressBegin(whdd->hic, lpbi, whdd->lpbiOut) != ICERR_OK)
229 TRACE("biSizeImage == %ld\n", whdd->lpbiOut->biSizeImage);
230 TRACE("biCompression == %ld\n", whdd->lpbiOut->biCompression);
231 TRACE("biBitCount == %d\n", whdd->lpbiOut->biBitCount);
238 TRACE("Not compressed!\n");
239 dwSize = lpbi->biSize + num_colours(lpbi)*sizeof(RGBQUAD);
240 whdd->lpbiOut = HeapAlloc(GetProcessHeap(), 0, dwSize);
241 memcpy(whdd->lpbiOut, lpbi, dwSize);
246 /*whdd->lpvbuf = HeapAlloc(GetProcessHeap(), 0, whdd->lpbiOut->biSizeImage);*/
248 whdd->hMemDC = CreateCompatibleDC(hdc);
249 TRACE("Creating: %ld, %p\n", whdd->lpbiOut->biSize, whdd->lpvbits);
250 whdd->hDib = CreateDIBSection(whdd->hMemDC, (BITMAPINFO *)whdd->lpbiOut, DIB_RGB_COLORS, &(whdd->lpvbits), 0, 0);
253 TRACE("Error: %ld\n", GetLastError());
255 TRACE("Created: %p,%p\n", whdd->hDib, whdd->lpvbits);
256 whdd->hOldDib = SelectObject(whdd->hMemDC, whdd->hDib);
264 whdd->lpbi = HeapAlloc(GetProcessHeap(), 0, lpbi->biSize);
265 memcpy(whdd->lpbi, lpbi, lpbi->biSize);
277 HeapFree(GetProcessHeap(), 0, whdd->lpbiOut);
278 whdd->lpbiOut = NULL;
285 /**********************************************************************
286 * DrawDibDraw [MSVFW32.@]
288 BOOL VFWAPI DrawDibDraw(HDRAWDIB hdd, HDC hdc,
289 INT xDst, INT yDst, INT dxDst, INT dyDst,
290 LPBITMAPINFOHEADER lpbi,
292 INT xSrc, INT ySrc, INT dxSrc, INT dySrc,
298 TRACE("(%p,%p,%d,%d,%d,%d,%p,%p,%d,%d,%d,%d,0x%08lx)\n",
299 hdd, hdc, xDst, yDst, dxDst, dyDst, lpbi, lpBits, xSrc, ySrc, dxSrc, dySrc, (DWORD)wFlags);
301 whdd = MSVIDEO_GetHddPtr(hdd);
302 if (whdd) return FALSE;
304 if (wFlags & ~(DDF_SAME_HDC | DDF_SAME_DRAW | DDF_NOTKEYFRAME | DDF_UPDATE | DDF_DONTDRAW))
305 FIXME("wFlags == 0x%08lx not handled\n", (DWORD)wFlags);
310 lpBits = (LPSTR)lpbi + (WORD)(lpbi->biSize) + (WORD)(num_colours(lpbi)*sizeof(RGBQUAD));
314 #define CHANGED(x) (whdd->x != x)
316 if ((!whdd->begun) ||
317 (!(wFlags & DDF_SAME_HDC) && CHANGED(hdc)) ||
318 (!(wFlags & DDF_SAME_DRAW) && (CHANGED(lpbi) || CHANGED(dxSrc) || CHANGED(dySrc) || CHANGED(dxDst) || CHANGED(dyDst))))
320 TRACE("Something changed!\n");
321 ret = DrawDibBegin(hdd, hdc, dxDst, dyDst, lpbi, dxSrc, dySrc, 0);
326 if ((dxDst == -1) && (dyDst == -1))
332 if (!(wFlags & DDF_UPDATE))
334 /* biSizeImage may be set to 0 for BI_RGB (uncompressed) bitmaps */
335 if ((lpbi->biCompression == BI_RGB) && (lpbi->biSizeImage == 0))
336 lpbi->biSizeImage = ((lpbi->biWidth * lpbi->biBitCount + 31) / 32) * 4 * lpbi->biHeight;
338 if (lpbi->biCompression)
342 TRACE("Compression == 0x%08lx\n", lpbi->biCompression);
344 if (wFlags & DDF_NOTKEYFRAME)
345 flags |= ICDECOMPRESS_NOTKEYFRAME;
347 ICDecompress(whdd->hic, flags, lpbi, lpBits, whdd->lpbiOut, whdd->lpvbits);
351 memcpy(whdd->lpvbits, lpBits, lpbi->biSizeImage);
354 if (!(wFlags & DDF_DONTDRAW) && whdd->hpal)
355 SelectPalette(hdc, whdd->hpal, FALSE);
357 if (!(StretchBlt(whdd->hdc, xDst, yDst, dxDst, dyDst, whdd->hMemDC, xSrc, ySrc, dxSrc, dySrc, SRCCOPY)))
363 /*************************************************************************
364 * DrawDibStart [MSVFW32.@]
366 BOOL VFWAPI DrawDibStart(HDRAWDIB hdd, DWORD rate) {
367 FIXME("(%p, %ld), stub\n", hdd, rate);
371 /*************************************************************************
372 * DrawDibStop [MSVFW32.@]
374 BOOL VFWAPI DrawDibStop(HDRAWDIB hdd) {
375 FIXME("(%p), stub\n", hdd);
379 /***********************************************************************
380 * DrawDibSetPalette [MSVFW32.@]
382 BOOL VFWAPI DrawDibSetPalette(HDRAWDIB hdd, HPALETTE hpal)
386 TRACE("(%p, %p)\n", hdd, hpal);
388 whdd = MSVIDEO_GetHddPtr(hdd);
389 if (!whdd) return FALSE;
395 SelectPalette(whdd->hdc, hpal, 0);
396 RealizePalette(whdd->hdc);
402 /***********************************************************************
403 * DrawDibGetPalette [MSVFW32.@]
405 HPALETTE VFWAPI DrawDibGetPalette(HDRAWDIB hdd)
409 TRACE("(%p)\n", hdd);
411 whdd = MSVIDEO_GetHddPtr(hdd);
412 if (!whdd) return FALSE;
417 /***********************************************************************
418 * DrawDibRealize [MSVFW32.@]
420 UINT VFWAPI DrawDibRealize(HDRAWDIB hdd, HDC hdc, BOOL fBackground)
426 FIXME("(%p, %p, %d), stub\n", hdd, hdc, fBackground);
428 whdd = MSVIDEO_GetHddPtr(hdd);
429 if (!whdd) return FALSE;
431 if (!whdd || !(whdd->begun))
438 whdd->hpal = CreateHalftonePalette(hdc);
440 oldPal = SelectPalette(hdc, whdd->hpal, fBackground);
441 ret = RealizePalette(hdc);
444 TRACE("=> %u\n", ret);