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