Documentation ordinal fixes.
[wine] / dlls / msvideo / drawdib.c
1 /* 
2  * Copyright 2000 Bradley Baetz
3  *
4  * Fixme: Some flags are ignored
5  *
6  * Handle palettes
7  */
8
9 #include <string.h>
10 #include "windef.h"
11 #include "winbase.h"
12 #include "wingdi.h"
13 #include "winuser.h"
14 #include "wine/winbase16.h"
15 #include "debugtools.h"
16 #include "vfw.h"
17 #include "vfw16.h"
18 #include "windef.h"
19
20 DEFAULT_DEBUG_CHANNEL(msvideo);
21
22 typedef struct {
23         HDC hdc;
24         INT dxDst;
25         INT dyDst;
26         LPBITMAPINFOHEADER lpbi;
27         INT dxSrc;
28         INT dySrc;
29         HPALETTE hpal;                          /* Palette to use for the DIB */
30         BOOL begun;                                     /* DrawDibBegin has been called */
31         LPBITMAPINFOHEADER lpbiOut;     /* Output format */
32         HIC hic;                                        /* HIC for decompression */
33         HDC hMemDC;                                     /* DC for buffering */
34         HBITMAP hOldDib;                        /* Original Dib */
35         HBITMAP hDib;                           /* DibSection */
36         LPVOID lpvbits;                         /* Buffer for holding decompressed dib */
37 } WINE_HDD;
38
39 /***********************************************************************
40  *              DrawDibOpen             [MSVFW32.@]
41  */
42 HDRAWDIB VFWAPI DrawDibOpen(void) {
43         HDRAWDIB hdd;
44
45         TRACE("(void)\n");
46         hdd = GlobalAlloc16(GHND,sizeof(WINE_HDD));
47         TRACE("=> %d\n",hdd);
48         return hdd;
49 }
50
51 /***********************************************************************
52  *              DrawDibOpen             [MSVIDEO.102]
53  */
54 HDRAWDIB16 VFWAPI DrawDibOpen16(void) {
55         return (HDRAWDIB16)DrawDibOpen();
56 }
57
58 /***********************************************************************
59  *              DrawDibClose            [MSVFW32.@]
60  */
61 BOOL VFWAPI DrawDibClose(HDRAWDIB hdd) {
62         WINE_HDD *whdd = GlobalLock16(hdd);
63
64         TRACE("(0x%08lx)\n",(DWORD)hdd);
65
66         if (!whdd)
67                 return FALSE;
68
69         if (whdd->begun)
70                 DrawDibEnd(hdd);
71
72         GlobalUnlock16(hdd);
73         GlobalFree16(hdd);
74         return TRUE;
75 }
76
77 /***********************************************************************
78  *              DrawDibClose            [MSVIDEO.103]
79  */
80 BOOL16 VFWAPI DrawDibClose16(HDRAWDIB16 hdd) {
81         return DrawDibClose(hdd);
82 }
83
84 /***********************************************************************
85  *              DrawDibEnd              [MSVFW32.@]
86  */
87 BOOL VFWAPI DrawDibEnd(HDRAWDIB hdd) {
88         BOOL ret = TRUE;
89         WINE_HDD *whdd = GlobalLock16(hdd);
90         
91         TRACE("(0x%08lx)\n",(DWORD)hdd);
92
93         whdd->hpal = 0; /* Do not free this */
94         whdd->hdc = 0;
95         if (whdd->lpbi) {
96                 HeapFree(GetProcessHeap(),0,whdd->lpbi);
97                 whdd->lpbi = NULL;
98         }
99         if (whdd->lpbiOut) {
100                 HeapFree(GetProcessHeap(),0,whdd->lpbiOut);
101                 whdd->lpbiOut = NULL;
102         }
103
104         whdd->begun = FALSE;
105
106         /*if (whdd->lpvbits)
107           HeapFree(GetProcessHeap(),0,whdd->lpvbuf);*/
108
109         if (whdd->hMemDC) {
110                 SelectObject(whdd->hMemDC,whdd->hOldDib);
111                 DeleteDC(whdd->hMemDC);
112         }
113
114         if (whdd->hDib)
115                 DeleteObject(whdd->hDib);
116         
117         if (whdd->hic) {
118                 ICDecompressEnd(whdd->hic);
119                 ICClose(whdd->hic);
120         }
121
122         whdd->lpvbits = NULL;
123
124         GlobalUnlock16(hdd);
125         return ret;
126 }
127
128 /***********************************************************************
129  *              DrawDibEnd              [MSVIDEO.105]
130  */
131 BOOL16 VFWAPI DrawDibEnd16(HDRAWDIB16 hdd) {
132         return DrawDibEnd(hdd);
133 }
134
135 /***********************************************************************
136  *              DrawDibBegin            [MSVFW32.@]
137  */
138 BOOL VFWAPI DrawDibBegin(HDRAWDIB hdd,
139                                                  HDC      hdc,
140                                                  INT      dxDst,
141                                                  INT      dyDst,
142                                                  LPBITMAPINFOHEADER lpbi,
143                                                  INT      dxSrc,
144                                                  INT      dySrc,
145                                                  UINT     wFlags) {
146         BOOL ret = TRUE;
147         WINE_HDD *whdd;
148
149         TRACE("(%d,0x%lx,%d,%d,%p,%d,%d,0x%08lx)\n",
150                 hdd,(DWORD)hdc,dxDst,dyDst,lpbi,dxSrc,dySrc,(DWORD)wFlags
151         );
152         TRACE("lpbi: %ld,%ld/%ld,%d,%d,%ld,%ld,%ld,%ld,%ld,%ld\n",
153                   lpbi->biSize, lpbi->biWidth, lpbi->biHeight, lpbi->biPlanes, 
154                   lpbi->biBitCount, lpbi->biCompression, lpbi->biSizeImage, 
155                   lpbi->biXPelsPerMeter, lpbi->biYPelsPerMeter, lpbi->biClrUsed, 
156                   lpbi->biClrImportant);
157
158         if (wFlags & ~(DDF_BUFFER))
159                 FIXME("wFlags == 0x%08x not handled\n", wFlags & ~(DDF_BUFFER));
160
161         whdd = (WINE_HDD*)GlobalLock16(hdd);
162         if (!whdd) return FALSE;
163
164         if (whdd->begun)
165                 DrawDibEnd(hdd);
166
167         if (lpbi->biCompression) {
168                 DWORD size = 0;
169
170                 whdd->hic = ICOpen(ICTYPE_VIDEO,lpbi->biCompression,ICMODE_DECOMPRESS);
171                 if (!whdd->hic) {
172                         WARN("Could not open IC. biCompression == 0x%08lx\n",lpbi->biCompression);
173                         ret = FALSE;
174                 }
175
176                 if (ret) {
177                         size = ICDecompressGetFormat(whdd->hic,lpbi,NULL);
178                         if (size == ICERR_UNSUPPORTED) {
179                                 WARN("Codec doesn't support GetFormat, giving up.\n");
180                                 ret = FALSE;
181                         }
182                 }
183
184                 if (ret) {
185                         whdd->lpbiOut = HeapAlloc(GetProcessHeap(),0,size);
186
187                         if (ICDecompressGetFormat(whdd->hic,lpbi,whdd->lpbiOut) != ICERR_OK)
188                                 ret = FALSE;
189                 }
190
191                 if (ret) {
192                         /* FIXME: Use Ex functions if available? */
193                         if (ICDecompressBegin(whdd->hic,lpbi,whdd->lpbiOut) != ICERR_OK)
194                                 ret = FALSE;
195
196                         TRACE("biSizeImage == %ld\n",whdd->lpbiOut->biSizeImage);
197                         TRACE("biCompression == %ld\n",whdd->lpbiOut->biCompression);
198                         TRACE("biBitCount == %d\n",whdd->lpbiOut->biBitCount);
199                 }
200         } else {
201                 DWORD dwSize;
202                 /* No compression */
203                 TRACE("Not compressed!\n");
204                 dwSize = lpbi->biSize + lpbi->biClrUsed*sizeof(RGBQUAD);
205                 whdd->lpbiOut = HeapAlloc(GetProcessHeap(),0,dwSize);
206                 memcpy(whdd->lpbiOut,lpbi,dwSize);
207         }
208
209         if (ret) {
210                 /*whdd->lpvbuf = HeapAlloc(GetProcessHeap(),0,whdd->lpbiOut->biSizeImage);*/
211                 
212                 whdd->hMemDC = CreateCompatibleDC(hdc);
213                 TRACE("Creating: %ld,%p\n",whdd->lpbiOut->biSize,whdd->lpvbits);
214                 whdd->hDib = CreateDIBSection(whdd->hMemDC,(BITMAPINFO *)whdd->lpbiOut,DIB_RGB_COLORS,&(whdd->lpvbits),0,0);
215                 if (!whdd->hDib) {
216                         TRACE("Error: %ld\n",GetLastError());
217                 }
218                 TRACE("Created: %d,%p\n",whdd->hDib,whdd->lpvbits);
219                 whdd->hOldDib = SelectObject(whdd->hMemDC,whdd->hDib);
220         }
221
222         if (ret) {
223                 whdd->hdc = hdc;
224                 whdd->dxDst = dxDst;
225                 whdd->dyDst = dyDst;
226                 whdd->lpbi = HeapAlloc(GetProcessHeap(),0,lpbi->biSize);
227                 memcpy(whdd->lpbi,lpbi,lpbi->biSize);
228                 whdd->dxSrc = dxSrc;
229                 whdd->dySrc = dySrc;
230                 whdd->begun = TRUE;
231                 whdd->hpal = 0;
232         } else {
233                 if (whdd->hic)
234                         ICClose(whdd->hic);
235                 if (whdd->lpbiOut) {
236                         HeapFree(GetProcessHeap(),0,whdd->lpbiOut);
237                         whdd->lpbiOut = NULL;
238                 }
239         }
240
241         GlobalUnlock16(hdd);
242
243         return ret;
244 }
245
246 /************************************************************************
247  *              DrawDibBegin            [MSVIDEO.104]
248  */
249 BOOL16 VFWAPI DrawDibBegin16(HDRAWDIB16 hdd,
250                                                    HDC16      hdc,
251                                                    INT16      dxDst,
252                                                    INT16      dyDst,
253                                                    LPBITMAPINFOHEADER lpbi,
254                                                    INT16      dxSrc,
255                                                    INT16      dySrc,
256                                                    UINT16     wFlags) {
257         return DrawDibBegin(hdd,hdc,dxDst,dyDst,lpbi,dxSrc,dySrc,wFlags);
258 }
259
260 /**********************************************************************
261  *              DrawDibDraw             [MSVFW32.@]
262  */
263 BOOL VFWAPI DrawDibDraw(HDRAWDIB hdd, HDC hdc,
264         INT xDst, INT yDst, INT dxDst, INT dyDst,
265         LPBITMAPINFOHEADER lpbi,
266         LPVOID lpBits,
267         INT xSrc, INT ySrc, INT dxSrc, INT dySrc,
268         UINT wFlags
269 ) {
270         WINE_HDD *whdd;
271         BOOL ret = TRUE;
272
273         TRACE("(%d,0x%lx,%d,%d,%d,%d,%p,%p,%d,%d,%d,%d,0x%08lx)\n",
274                   hdd,(DWORD)hdc,xDst,yDst,dxDst,dyDst,lpbi,lpBits,xSrc,ySrc,dxSrc,dySrc,(DWORD)wFlags
275         );
276
277         if (wFlags & ~(DDF_SAME_HDC | DDF_SAME_DRAW | DDF_NOTKEYFRAME | 
278                                    DDF_UPDATE | DDF_DONTDRAW))
279                 FIXME("wFlags == 0x%08lx not handled\n",(DWORD)wFlags);
280
281         if (!lpBits) {
282                 /* Undocumented? */
283                 lpBits = (LPSTR)lpbi + (WORD)(lpbi->biSize) + (WORD)(lpbi->biClrUsed*sizeof(RGBQUAD));
284         }
285
286         whdd = GlobalLock16(hdd);
287
288 #define CHANGED(x) (whdd->x != x)
289
290         if ((!whdd->begun) || (!(wFlags & DDF_SAME_HDC) && CHANGED(hdc)) || (!(wFlags & DDF_SAME_DRAW) &&
291                  (CHANGED(lpbi) || CHANGED(dxSrc) || CHANGED(dySrc) || CHANGED(dxDst) || CHANGED(dyDst)))) {
292                 TRACE("Something changed!\n");
293                 ret = DrawDibBegin(hdd,hdc,dxDst,dyDst,lpbi,dxSrc,dySrc,0);
294         }
295
296 #undef CHANGED
297
298         if ((dxDst == -1) && (dyDst == -1)) {
299                 dxDst = dxSrc;
300                 dyDst = dySrc;
301         }
302
303         if (!(wFlags & DDF_UPDATE)) {
304             /* biSizeImage may be set to 0 for BI_RGB (uncompressed) bitmaps */
305             if ((lpbi->biCompression == BI_RGB) && (lpbi->biSizeImage == 0))
306                     lpbi->biSizeImage = ((lpbi->biWidth * lpbi->biBitCount + 31) / 32) * 4 * lpbi->biHeight;
307
308                 if (lpbi->biCompression) {
309                     DWORD flags = 0;
310                 
311                         TRACE("Compression == 0x%08lx\n",lpbi->biCompression);
312                 
313                         if (wFlags & DDF_NOTKEYFRAME)
314                             flags |= ICDECOMPRESS_NOTKEYFRAME;
315                 
316                         ICDecompress(whdd->hic,flags,lpbi,lpBits,whdd->lpbiOut,whdd->lpvbits);
317                 } else {
318                     memcpy(whdd->lpvbits,lpBits,lpbi->biSizeImage);
319                 }       
320         }
321         if (!(wFlags & DDF_DONTDRAW) && whdd->hpal)
322             SelectPalette(hdc,whdd->hpal,FALSE);
323
324         if (!(StretchBlt(whdd->hdc,xDst,yDst,dxDst,dyDst,whdd->hMemDC,xSrc,ySrc,dxSrc,dySrc,SRCCOPY)))
325             ret = FALSE;
326
327         GlobalUnlock16(hdd);
328         return ret;
329 }
330
331 /**********************************************************************
332  *              DrawDibDraw             [MSVIDEO.106]
333  */
334 BOOL16 VFWAPI DrawDibDraw16(HDRAWDIB16 hdd,             
335                                                   HDC16 hdc,
336                                                   INT16 xDst,
337                                                   INT16 yDst,
338                                                   INT16 dxDst,
339                                                   INT16 dyDst,
340                                                   LPBITMAPINFOHEADER lpbi,
341                                                   LPVOID lpBits,
342                                                   INT16 xSrc,
343                                                   INT16 ySrc,
344                                                   INT16 dxSrc,
345                                                   INT16 dySrc,
346                                                   UINT16 wFlags) {
347         return DrawDibDraw(hdd,hdc,xDst,yDst,dxDst,dyDst,lpbi,lpBits,xSrc,ySrc,dxSrc,dySrc,wFlags);
348 }
349
350 /*************************************************************************
351  *              DrawDibStart            [MSVFW32.@]
352  */
353 BOOL VFWAPI DrawDibStart(HDRAWDIB hdd, DWORD rate) {
354         FIXME("(0x%08lx,%ld), stub\n",(DWORD)hdd,rate);
355         return TRUE;
356 }
357
358 /*************************************************************************
359  *              DrawDibStart            [MSVIDEO.118]
360  */
361 BOOL16 VFWAPI DrawDibStart16(HDRAWDIB16 hdd, DWORD rate) {
362         return DrawDibStart(hdd,rate);
363 }
364
365 /*************************************************************************
366  *              DrawDibStop             [MSVFW32.@]
367  */
368 BOOL VFWAPI DrawDibStop(HDRAWDIB hdd) {
369         FIXME("(0x%08lx), stub\n",(DWORD)hdd);
370         return TRUE;
371 }
372
373 /*************************************************************************
374  *              DrawDibStop             [MSVIDEO.119]
375  */
376 BOOL16 DrawDibStop16(HDRAWDIB16 hdd) {
377         return DrawDibStop(hdd);
378 }
379
380 /***********************************************************************
381  *              DrawDibSetPalette       [MSVFW32.@]
382  */
383 BOOL VFWAPI DrawDibSetPalette(HDRAWDIB hdd, HPALETTE hpal) {
384         WINE_HDD *whdd;
385
386         TRACE("(0x%08lx,0x%08lx)\n",(DWORD)hdd,(DWORD)hpal);
387
388         whdd = GlobalLock16(hdd);
389         whdd->hpal = hpal;
390         
391         if (whdd->begun) {
392                 SelectPalette(whdd->hdc,hpal,0);
393                 RealizePalette(whdd->hdc);
394         }
395         GlobalUnlock16(hdd);
396         return TRUE;
397 }
398
399 /***********************************************************************
400  *              DrawDibSetPalette       [MSVIDEO.110]
401  */
402 BOOL16 VFWAPI DrawDibSetPalette16(HDRAWDIB16 hdd, HPALETTE16 hpal) {
403         return DrawDibSetPalette(hdd,hpal);
404 }
405
406 /***********************************************************************
407  *              DrawDibGetPalette       [MSVFW32.@]
408  */
409 HPALETTE VFWAPI DrawDibGetPalette(HDRAWDIB hdd) {
410         WINE_HDD *whdd;
411         HPALETTE ret;
412
413         TRACE("(0x%08lx)\n",(DWORD)hdd);
414
415         whdd = GlobalLock16(hdd);
416         ret = whdd->hpal;
417         GlobalUnlock16(hdd);
418         return ret;
419 }
420
421 /***********************************************************************
422  *              DrawDibGetPalette       [MSVIDEO.108]]   
423  */
424 HPALETTE16 VFWAPI DrawDibGetPalette16(HDRAWDIB16 hdd) {
425         return (HPALETTE16)DrawDibGetPalette(hdd);
426 }
427
428 /***********************************************************************
429  *              DrawDibRealize          [MSVFW32.@]
430  */
431 UINT VFWAPI DrawDibRealize(HDRAWDIB hdd, HDC hdc, BOOL fBackground) {
432         WINE_HDD *whdd;
433         HPALETTE oldPal;
434         UINT ret = 0;
435
436         FIXME("(%d,0x%08lx,%d), stub\n",hdd,(DWORD)hdc,fBackground);
437         
438         whdd = GlobalLock16(hdd);
439
440         if (!whdd || !(whdd->begun)) {
441                 ret = 0;
442                 goto out;
443         }
444         
445         if (!whdd->hpal)
446                 whdd->hpal = CreateHalftonePalette(hdc);
447
448         oldPal = SelectPalette(hdc,whdd->hpal,fBackground);
449         ret = RealizePalette(hdc);
450         
451  out:
452         GlobalUnlock16(hdd);
453
454         TRACE("=> %u\n",ret);
455         return ret;
456 }
457
458 /***********************************************************************
459  *              DrawDibRealize          [MSVIDEO.112]
460  */
461 UINT16 VFWAPI DrawDibRealize16(HDRAWDIB16 hdd, HDC16 hdc, BOOL16 fBackground) {
462         return (UINT16)DrawDibRealize(hdd,hdc,fBackground);
463 }