Repaired shared PE data sections.
[wine/multimedia.git] / dlls / msvideo / drawdib.c
blob826a71a131c2105de3bb64bc9e47f48d2c856127
1 /*
2 * Copyright 2000 Bradley Baetz
4 * Fixme: Some flags are ignored
6 * Handle palettes
7 */
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"
20 DEFAULT_DEBUG_CHANNEL(msvideo);
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;
39 /***********************************************************************
40 * DrawDibOpen [MSVFW32.10]
42 HDRAWDIB VFWAPI DrawDibOpen(void) {
43 HDRAWDIB hdd;
45 TRACE("(void)\n");
46 hdd = GlobalAlloc16(GHND,sizeof(WINE_HDD));
47 TRACE("=> %d\n",hdd);
48 return hdd;
51 /***********************************************************************
52 * DrawDibOpen [MSVIDEO.102]
54 HDRAWDIB16 VFWAPI DrawDibOpen16(void) {
55 return (HDRAWDIB16)DrawDibOpen();
58 /***********************************************************************
59 * DrawDibClose [MSVFW32.5]
61 BOOL VFWAPI DrawDibClose(HDRAWDIB hdd) {
62 WINE_HDD *whdd = GlobalLock16(hdd);
64 TRACE("(0x%08lx)\n",(DWORD)hdd);
66 if (!whdd)
67 return FALSE;
69 if (whdd->begun)
70 DrawDibEnd(hdd);
72 GlobalUnlock16(hdd);
73 GlobalFree16(hdd);
74 return TRUE;
77 /***********************************************************************
78 * DrawDibClose [MSVIDEO.103]
80 BOOL16 VFWAPI DrawDibClose16(HDRAWDIB16 hdd) {
81 return DrawDibClose(hdd);
84 /***********************************************************************
85 * DrawDibEnd [MSVFW32.7]
87 BOOL VFWAPI DrawDibEnd(HDRAWDIB hdd) {
88 BOOL ret = TRUE;
89 WINE_HDD *whdd = GlobalLock16(hdd);
91 TRACE("(0x%08lx)\n",(DWORD)hdd);
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;
99 if (whdd->lpbiOut) {
100 HeapFree(GetProcessHeap(),0,whdd->lpbiOut);
101 whdd->lpbiOut = NULL;
104 whdd->begun = FALSE;
106 /*if (whdd->lpvbits)
107 HeapFree(GetProcessHeap(),0,whdd->lpvbuf);*/
109 if (whdd->hMemDC) {
110 SelectObject(whdd->hMemDC,whdd->hOldDib);
111 DeleteDC(whdd->hMemDC);
114 if (whdd->hDib)
115 DeleteObject(whdd->hDib);
117 if (whdd->hic) {
118 ICDecompressEnd(whdd->hic);
119 ICClose(whdd->hic);
122 whdd->lpvbits = NULL;
124 GlobalUnlock16(hdd);
125 return ret;
128 /***********************************************************************
129 * DrawDibEnd [MSVIDEO.105]
131 BOOL16 VFWAPI DrawDibEnd16(HDRAWDIB16 hdd) {
132 return DrawDibEnd(hdd);
135 /***********************************************************************
136 * DrawDibBegin [MSVFW32.3]
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;
149 TRACE("(%d,0x%lx,%d,%d,%p,%d,%d,0x%08lx)\n",
150 hdd,(DWORD)hdc,dxDst,dyDst,lpbi,dxSrc,dySrc,(DWORD)wFlags
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);
158 if (wFlags & ~(DDF_BUFFER))
159 FIXME("wFlags == 0x%08x not handled\n", wFlags & ~(DDF_BUFFER));
161 whdd = (WINE_HDD*)GlobalLock16(hdd);
162 if (!whdd) return FALSE;
164 if (whdd->begun)
165 DrawDibEnd(hdd);
167 if (lpbi->biCompression) {
168 DWORD size = 0;
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;
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;
184 if (ret) {
185 whdd->lpbiOut = HeapAlloc(GetProcessHeap(),0,size);
187 if (ICDecompressGetFormat(whdd->hic,lpbi,whdd->lpbiOut) != ICERR_OK)
188 ret = FALSE;
191 if (ret) {
192 /* FIXME: Use Ex functions if available? */
193 if (ICDecompressBegin(whdd->hic,lpbi,whdd->lpbiOut) != ICERR_OK)
194 ret = FALSE;
196 TRACE("biSizeImage == %ld\n",whdd->lpbiOut->biSizeImage);
197 TRACE("biCompression == %ld\n",whdd->lpbiOut->biCompression);
198 TRACE("biBitCount == %d\n",whdd->lpbiOut->biBitCount);
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);
209 if (ret) {
210 /*whdd->lpvbuf = HeapAlloc(GetProcessHeap(),0,whdd->lpbiOut->biSizeImage);*/
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());
218 TRACE("Created: %d,%p\n",whdd->hDib,whdd->lpvbits);
219 whdd->hOldDib = SelectObject(whdd->hMemDC,whdd->hDib);
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;
241 GlobalUnlock16(hdd);
243 return ret;
246 /************************************************************************
247 * DrawDibBegin [MSVIDEO.104]
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);
260 /**********************************************************************
261 * DrawDibDraw [MSVFW32.6]
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
270 WINE_HDD *whdd;
271 BOOL ret = TRUE;
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
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);
281 if (!lpBits) {
282 /* Undocumented? */
283 lpBits = (LPSTR)lpbi + (WORD)(lpbi->biSize) + (WORD)(lpbi->biClrUsed*sizeof(RGBQUAD));
286 whdd = GlobalLock16(hdd);
288 #define CHANGED(x) (whdd->x != x)
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);
296 #undef CHANGED
298 if ((dxDst == -1) && (dyDst == -1)) {
299 dxDst = dxSrc;
300 dyDst = dySrc;
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;
308 if (lpbi->biCompression) {
309 DWORD flags = 0;
311 TRACE("Compression == 0x%08lx\n",lpbi->biCompression);
313 if (wFlags & DDF_NOTKEYFRAME)
314 flags |= ICDECOMPRESS_NOTKEYFRAME;
316 ICDecompress(whdd->hic,flags,lpbi,lpBits,whdd->lpbiOut,whdd->lpvbits);
317 } else {
318 memcpy(whdd->lpvbits,lpBits,lpbi->biSizeImage);
321 if (!(wFlags & DDF_DONTDRAW) && whdd->hpal)
322 SelectPalette(hdc,whdd->hpal,FALSE);
324 if (!(StretchBlt(whdd->hdc,xDst,yDst,dxDst,dyDst,whdd->hMemDC,xSrc,ySrc,dxSrc,dySrc,SRCCOPY)))
325 ret = FALSE;
327 GlobalUnlock16(hdd);
328 return ret;
331 /**********************************************************************
332 * DrawDibDraw [MSVIDEO.106]
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);
350 /*************************************************************************
351 * DrawDibStart [MSVFW32.14]
353 BOOL VFWAPI DrawDibStart(HDRAWDIB hdd, DWORD rate) {
354 FIXME("(0x%08lx,%ld), stub\n",(DWORD)hdd,rate);
355 return TRUE;
358 /*************************************************************************
359 * DrawDibStart [MSVIDEO.118]
361 BOOL16 VFWAPI DrawDibStart16(HDRAWDIB16 hdd, DWORD rate) {
362 return DrawDibStart(hdd,rate);
365 /*************************************************************************
366 * DrawDibStop [MSVFW32.15]
368 BOOL VFWAPI DrawDibStop(HDRAWDIB hdd) {
369 FIXME("(0x%08lx), stub\n",(DWORD)hdd);
370 return TRUE;
373 /*************************************************************************
374 * DrawDibStop [MSVIDEO.119]
376 BOOL16 DrawDibStop16(HDRAWDIB16 hdd) {
377 return DrawDibStop(hdd);
380 /***********************************************************************
381 * DrawDibSetPalette [MSVFW32.13]
383 BOOL VFWAPI DrawDibSetPalette(HDRAWDIB hdd, HPALETTE hpal) {
384 WINE_HDD *whdd;
386 TRACE("(0x%08lx,0x%08lx)\n",(DWORD)hdd,(DWORD)hpal);
388 whdd = GlobalLock16(hdd);
389 whdd->hpal = hpal;
391 if (whdd->begun) {
392 SelectPalette(whdd->hdc,hpal,0);
393 RealizePalette(whdd->hdc);
395 GlobalUnlock16(hdd);
396 return TRUE;
399 /***********************************************************************
400 * DrawDibSetPalette [MSVIDEO.110]
402 BOOL16 VFWAPI DrawDibSetPalette16(HDRAWDIB16 hdd, HPALETTE16 hpal) {
403 return DrawDibSetPalette(hdd,hpal);
406 /***********************************************************************
407 * DrawDibGetPalette [MSVFW32.9]
409 HPALETTE VFWAPI DrawDibGetPalette(HDRAWDIB hdd) {
410 WINE_HDD *whdd;
411 HPALETTE ret;
413 TRACE("(0x%08lx)\n",(DWORD)hdd);
415 whdd = GlobalLock16(hdd);
416 ret = whdd->hpal;
417 GlobalUnlock16(hdd);
418 return ret;
421 /***********************************************************************
422 * DrawDibGetPalette [MSVIDEO.108]]
424 HPALETTE16 VFWAPI DrawDibGetPalette16(HDRAWDIB16 hdd) {
425 return (HPALETTE16)DrawDibGetPalette(hdd);
428 /***********************************************************************
429 * DrawDibRealize [MSVFW32.12]
431 UINT VFWAPI DrawDibRealize(HDRAWDIB hdd, HDC hdc, BOOL fBackground) {
432 WINE_HDD *whdd;
433 HPALETTE oldPal;
434 UINT ret = 0;
436 FIXME("(%d,0x%08lx,%d), stub\n",hdd,(DWORD)hdc,fBackground);
438 whdd = GlobalLock16(hdd);
440 if (!whdd || !(whdd->begun)) {
441 ret = 0;
442 goto out;
445 if (!whdd->hpal)
446 whdd->hpal = CreateHalftonePalette(hdc);
448 oldPal = SelectPalette(hdc,whdd->hpal,fBackground);
449 ret = RealizePalette(hdc);
451 out:
452 GlobalUnlock16(hdd);
454 TRACE("=> %u\n",ret);
455 return ret;
458 /***********************************************************************
459 * DrawDibRealize [MSVIDEO.112]
461 UINT16 VFWAPI DrawDibRealize16(HDRAWDIB16 hdd, HDC16 hdc, BOOL16 fBackground) {
462 return (UINT16)DrawDibRealize(hdd,hdc,fBackground);