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
28 #include "wine/winbase16.h"
29 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(msvideo);
40 LPBITMAPINFOHEADER lpbi;
43 HPALETTE hpal; /* Palette to use for the DIB */
44 BOOL begun; /* DrawDibBegin has been called */
45 LPBITMAPINFOHEADER lpbiOut; /* Output format */
46 HIC hic; /* HIC for decompression */
47 HDC hMemDC; /* DC for buffering */
48 HBITMAP hOldDib; /* Original Dib */
49 HBITMAP hDib; /* DibSection */
50 LPVOID lpvbits; /* Buffer for holding decompressed dib */
53 int num_colours(LPBITMAPINFOHEADER lpbi)
56 return lpbi->biClrUsed;
57 if(lpbi->biBitCount<=8)
58 return 1<<lpbi->biBitCount;
62 /***********************************************************************
63 * DrawDibOpen [MSVFW32.@]
65 HDRAWDIB VFWAPI DrawDibOpen(void) {
69 hdd = GlobalAlloc16(GHND,sizeof(WINE_HDD));
74 /***********************************************************************
75 * DrawDibClose [MSVFW32.@]
77 BOOL VFWAPI DrawDibClose(HDRAWDIB hdd) {
78 WINE_HDD *whdd = GlobalLock16(hdd);
80 TRACE("(0x%08lx)\n",(DWORD)hdd);
93 /***********************************************************************
94 * DrawDibEnd [MSVFW32.@]
96 BOOL VFWAPI DrawDibEnd(HDRAWDIB hdd) {
98 WINE_HDD *whdd = GlobalLock16(hdd);
100 TRACE("(0x%08lx)\n",(DWORD)hdd);
102 whdd->hpal = 0; /* Do not free this */
105 HeapFree(GetProcessHeap(),0,whdd->lpbi);
109 HeapFree(GetProcessHeap(),0,whdd->lpbiOut);
110 whdd->lpbiOut = NULL;
116 HeapFree(GetProcessHeap(),0,whdd->lpvbuf);*/
119 SelectObject(whdd->hMemDC,whdd->hOldDib);
120 DeleteDC(whdd->hMemDC);
124 DeleteObject(whdd->hDib);
127 ICDecompressEnd(whdd->hic);
131 whdd->lpvbits = NULL;
137 /***********************************************************************
138 * DrawDibBegin [MSVFW32.@]
140 BOOL VFWAPI DrawDibBegin(HDRAWDIB hdd,
144 LPBITMAPINFOHEADER lpbi,
151 TRACE("(%d,0x%lx,%d,%d,%p,%d,%d,0x%08lx)\n",
152 hdd,(DWORD)hdc,dxDst,dyDst,lpbi,dxSrc,dySrc,(DWORD)wFlags
154 TRACE("lpbi: %ld,%ld/%ld,%d,%d,%ld,%ld,%ld,%ld,%ld,%ld\n",
155 lpbi->biSize, lpbi->biWidth, lpbi->biHeight, lpbi->biPlanes,
156 lpbi->biBitCount, lpbi->biCompression, lpbi->biSizeImage,
157 lpbi->biXPelsPerMeter, lpbi->biYPelsPerMeter, lpbi->biClrUsed,
158 lpbi->biClrImportant);
160 if (wFlags & ~(DDF_BUFFER))
161 FIXME("wFlags == 0x%08x not handled\n", wFlags & ~(DDF_BUFFER));
163 whdd = (WINE_HDD*)GlobalLock16(hdd);
164 if (!whdd) return FALSE;
169 if (lpbi->biCompression) {
172 whdd->hic = ICOpen(ICTYPE_VIDEO,lpbi->biCompression,ICMODE_DECOMPRESS);
174 WARN("Could not open IC. biCompression == 0x%08lx\n",lpbi->biCompression);
179 size = ICDecompressGetFormat(whdd->hic,lpbi,NULL);
180 if (size == ICERR_UNSUPPORTED) {
181 WARN("Codec doesn't support GetFormat, giving up.\n");
187 whdd->lpbiOut = HeapAlloc(GetProcessHeap(),0,size);
189 if (ICDecompressGetFormat(whdd->hic,lpbi,whdd->lpbiOut) != ICERR_OK)
194 /* FIXME: Use Ex functions if available? */
195 if (ICDecompressBegin(whdd->hic,lpbi,whdd->lpbiOut) != ICERR_OK)
198 TRACE("biSizeImage == %ld\n",whdd->lpbiOut->biSizeImage);
199 TRACE("biCompression == %ld\n",whdd->lpbiOut->biCompression);
200 TRACE("biBitCount == %d\n",whdd->lpbiOut->biBitCount);
205 TRACE("Not compressed!\n");
206 dwSize = lpbi->biSize + num_colours(lpbi)*sizeof(RGBQUAD);
207 whdd->lpbiOut = HeapAlloc(GetProcessHeap(),0,dwSize);
208 memcpy(whdd->lpbiOut,lpbi,dwSize);
212 /*whdd->lpvbuf = HeapAlloc(GetProcessHeap(),0,whdd->lpbiOut->biSizeImage);*/
214 whdd->hMemDC = CreateCompatibleDC(hdc);
215 TRACE("Creating: %ld,%p\n",whdd->lpbiOut->biSize,whdd->lpvbits);
216 whdd->hDib = CreateDIBSection(whdd->hMemDC,(BITMAPINFO *)whdd->lpbiOut,DIB_RGB_COLORS,&(whdd->lpvbits),0,0);
218 TRACE("Error: %ld\n",GetLastError());
220 TRACE("Created: %d,%p\n",whdd->hDib,whdd->lpvbits);
221 whdd->hOldDib = SelectObject(whdd->hMemDC,whdd->hDib);
228 whdd->lpbi = HeapAlloc(GetProcessHeap(),0,lpbi->biSize);
229 memcpy(whdd->lpbi,lpbi,lpbi->biSize);
238 HeapFree(GetProcessHeap(),0,whdd->lpbiOut);
239 whdd->lpbiOut = NULL;
248 /**********************************************************************
249 * DrawDibDraw [MSVFW32.@]
251 BOOL VFWAPI DrawDibDraw(HDRAWDIB hdd, HDC hdc,
252 INT xDst, INT yDst, INT dxDst, INT dyDst,
253 LPBITMAPINFOHEADER lpbi,
255 INT xSrc, INT ySrc, INT dxSrc, INT dySrc,
261 TRACE("(%d,0x%lx,%d,%d,%d,%d,%p,%p,%d,%d,%d,%d,0x%08lx)\n",
262 hdd,(DWORD)hdc,xDst,yDst,dxDst,dyDst,lpbi,lpBits,xSrc,ySrc,dxSrc,dySrc,(DWORD)wFlags
265 if (wFlags & ~(DDF_SAME_HDC | DDF_SAME_DRAW | DDF_NOTKEYFRAME |
266 DDF_UPDATE | DDF_DONTDRAW))
267 FIXME("wFlags == 0x%08lx not handled\n",(DWORD)wFlags);
271 lpBits = (LPSTR)lpbi + (WORD)(lpbi->biSize) + (WORD)(num_colours(lpbi)*sizeof(RGBQUAD));
274 whdd = GlobalLock16(hdd);
276 #define CHANGED(x) (whdd->x != x)
278 if ((!whdd->begun) || (!(wFlags & DDF_SAME_HDC) && CHANGED(hdc)) || (!(wFlags & DDF_SAME_DRAW) &&
279 (CHANGED(lpbi) || CHANGED(dxSrc) || CHANGED(dySrc) || CHANGED(dxDst) || CHANGED(dyDst)))) {
280 TRACE("Something changed!\n");
281 ret = DrawDibBegin(hdd,hdc,dxDst,dyDst,lpbi,dxSrc,dySrc,0);
286 if ((dxDst == -1) && (dyDst == -1)) {
291 if (!(wFlags & DDF_UPDATE)) {
292 /* biSizeImage may be set to 0 for BI_RGB (uncompressed) bitmaps */
293 if ((lpbi->biCompression == BI_RGB) && (lpbi->biSizeImage == 0))
294 lpbi->biSizeImage = ((lpbi->biWidth * lpbi->biBitCount + 31) / 32) * 4 * lpbi->biHeight;
296 if (lpbi->biCompression) {
299 TRACE("Compression == 0x%08lx\n",lpbi->biCompression);
301 if (wFlags & DDF_NOTKEYFRAME)
302 flags |= ICDECOMPRESS_NOTKEYFRAME;
304 ICDecompress(whdd->hic,flags,lpbi,lpBits,whdd->lpbiOut,whdd->lpvbits);
306 memcpy(whdd->lpvbits,lpBits,lpbi->biSizeImage);
309 if (!(wFlags & DDF_DONTDRAW) && whdd->hpal)
310 SelectPalette(hdc,whdd->hpal,FALSE);
312 if (!(StretchBlt(whdd->hdc,xDst,yDst,dxDst,dyDst,whdd->hMemDC,xSrc,ySrc,dxSrc,dySrc,SRCCOPY)))
319 /*************************************************************************
320 * DrawDibStart [MSVFW32.@]
322 BOOL VFWAPI DrawDibStart(HDRAWDIB hdd, DWORD rate) {
323 FIXME("(0x%08lx,%ld), stub\n",(DWORD)hdd,rate);
327 /*************************************************************************
328 * DrawDibStop [MSVFW32.@]
330 BOOL VFWAPI DrawDibStop(HDRAWDIB hdd) {
331 FIXME("(0x%08lx), stub\n",(DWORD)hdd);
335 /***********************************************************************
336 * DrawDibSetPalette [MSVFW32.@]
338 BOOL VFWAPI DrawDibSetPalette(HDRAWDIB hdd, HPALETTE hpal) {
341 TRACE("(0x%08lx,0x%08lx)\n",(DWORD)hdd,(DWORD)hpal);
343 whdd = GlobalLock16(hdd);
347 SelectPalette(whdd->hdc,hpal,0);
348 RealizePalette(whdd->hdc);
354 /***********************************************************************
355 * DrawDibGetPalette [MSVFW32.@]
357 HPALETTE VFWAPI DrawDibGetPalette(HDRAWDIB hdd) {
361 TRACE("(0x%08lx)\n",(DWORD)hdd);
363 whdd = GlobalLock16(hdd);
369 /***********************************************************************
370 * DrawDibRealize [MSVFW32.@]
372 UINT VFWAPI DrawDibRealize(HDRAWDIB hdd, HDC hdc, BOOL fBackground) {
377 FIXME("(%d,0x%08lx,%d), stub\n",hdd,(DWORD)hdc,fBackground);
379 whdd = GlobalLock16(hdd);
381 if (!whdd || !(whdd->begun)) {
387 whdd->hpal = CreateHalftonePalette(hdc);
389 oldPal = SelectPalette(hdc,whdd->hpal,fBackground);
390 ret = RealizePalette(hdc);
395 TRACE("=> %u\n",ret);