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