Improved a bit the folder browsing implementation.
[wine.git] / dlls / msvideo / drawdib.c
blob1777f772b952d44982dddd6fbd8927f261c04390
1 /*
2 * Copyright 2000 Bradley Baetz
4 * Fixme: Some flags are ignored
5 * Should be doing buffering when requested
6 * Handle palettes
7 */
9 #include "windef.h"
10 #include "wingdi.h"
11 #include "winuser.h"
12 #include "winbase.h"
13 #include "debugtools.h"
14 #include "vfw.h"
15 #include "windef.h"
17 DEFAULT_DEBUG_CHANNEL(msvideo);
18 typedef struct {
19 HDC hdc;
20 INT dxDst;
21 INT dyDst;
22 LPBITMAPINFOHEADER lpbi;
23 INT dxSrc;
24 INT dySrc;
25 HPALETTE hpal; /* Palette to use for the DIB */
26 BOOL begun; /* DrawDibBegin has been called */
27 LPBITMAPINFOHEADER lpbiOut; /* Output format */
28 HIC hic; /* HIC for decompression */
29 HDC hMemDC; /* DC for buffering */
30 HBITMAP hOldDib; /* Original Dib */
31 HBITMAP hDib; /* DibSection */
32 LPVOID lpvbits; /* Buffer for holding decompressed dib */
33 } WINE_HDD;
35 /***********************************************************************
36 * DrawDibOpen [MSVFW32.10]
38 HDRAWDIB VFWAPI DrawDibOpen(void) {
39 HDRAWDIB hdd;
41 TRACE("(void)\n");
42 hdd = GlobalAlloc16(GHND,sizeof(WINE_HDD));
43 TRACE("=> %d\n",hdd);
44 return hdd;
47 /***********************************************************************
48 * DrawDibOpen [MSVIDEO.102]
50 HDRAWDIB16 VFWAPI DrawDibOpen16(void) {
51 return (HDRAWDIB16)DrawDibOpen();
54 /***********************************************************************
55 * DrawDibClose [MSVFW32.5]
57 BOOL VFWAPI DrawDibClose(HDRAWDIB hdd) {
58 WINE_HDD *whdd = GlobalLock16(hdd);
60 TRACE("(0x%08lx)\n",(DWORD)hdd);
62 if (!whdd)
63 return FALSE;
65 if (whdd->begun)
66 DrawDibEnd(hdd);
68 GlobalUnlock16(hdd);
69 GlobalFree16(hdd);
70 return TRUE;
73 /***********************************************************************
74 * DrawDibClose [MSVIDEO.103]
76 BOOL16 VFWAPI DrawDibClose16(HDRAWDIB16 hdd) {
77 return DrawDibClose(hdd);
80 /***********************************************************************
81 * DrawDibEnd [MSVFW32.7]
83 BOOL VFWAPI DrawDibEnd(HDRAWDIB hdd) {
84 BOOL ret = TRUE;
85 WINE_HDD *whdd = GlobalLock16(hdd);
87 TRACE("(0x%08lx)\n",(DWORD)hdd);
89 whdd->hpal = 0; /* Do not free this */
90 whdd->hdc = 0;
91 if (whdd->lpbi) {
92 HeapFree(GetProcessHeap(),0,whdd->lpbi);
93 whdd->lpbi = NULL;
95 if (whdd->lpbiOut) {
96 HeapFree(GetProcessHeap(),0,whdd->lpbiOut);
97 whdd->lpbiOut = NULL;
100 whdd->begun = FALSE;
102 /*if (whdd->lpvbits)
103 HeapFree(GetProcessHeap(),0,whdd->lpvbuf);*/
105 if (whdd->hMemDC) {
106 SelectObject(whdd->hMemDC,whdd->hOldDib);
107 DeleteDC(whdd->hMemDC);
110 if (whdd->hDib)
111 DeleteObject(whdd->hDib);
113 if (whdd->hic) {
114 ICDecompressEnd(whdd->hic);
115 ICClose(whdd->hic);
118 whdd->lpvbits = NULL;
120 GlobalUnlock16(hdd);
121 return ret;
124 /***********************************************************************
125 * DrawDibEnd [MSVIDEO.105]
127 BOOL16 VFWAPI DrawDibEnd16(HDRAWDIB16 hdd) {
128 return DrawDibEnd(hdd);
131 /***********************************************************************
132 * DrawDibBegin [MSVFW32.3]
134 BOOL VFWAPI DrawDibBegin(HDRAWDIB hdd,
135 HDC hdc,
136 INT dxDst,
137 INT dyDst,
138 LPBITMAPINFOHEADER lpbi,
139 INT dxSrc,
140 INT dySrc,
141 UINT wFlags) {
142 BOOL ret = TRUE;
143 WINE_HDD *whdd;
145 TRACE("(%d,0x%lx,%d,%d,%p,%d,%d,0x%08lx)\n",
146 hdd,(DWORD)hdc,dxDst,dyDst,lpbi,dxSrc,dySrc,(DWORD)wFlags
149 if (wFlags)
150 FIXME("wFlags == 0x%08lx not handled\n",(DWORD)wFlags);
152 whdd = (WINE_HDD*)GlobalLock16(hdd);
154 if (whdd->begun)
155 DrawDibEnd(hdd);
157 if (lpbi->biCompression) {
158 DWORD size;
160 whdd->hic = ICOpen(ICTYPE_VIDEO,lpbi->biCompression,ICMODE_DECOMPRESS);
161 if (!whdd->hic) {
162 ERR("Could not open IC. biCompression == 0x%08lx\n",lpbi->biCompression);
163 ret = FALSE;
166 if (ret) {
167 size = ICDecompressGetFormat(whdd->hic,lpbi,NULL);
168 if (size == ICERR_UNSUPPORTED) {
169 FIXME("Codec doesn't support GetFormat, giving up.\n");
170 ret = FALSE;
174 if (ret) {
175 whdd->lpbiOut = HeapAlloc(GetProcessHeap(),0,size);
177 if (ICDecompressGetFormat(whdd->hic,lpbi,whdd->lpbiOut) != ICERR_OK)
178 ret = FALSE;
181 if (ret) {
182 /* FIXME: Use Ex functions if available? */
183 if (ICDecompressBegin(whdd->hic,lpbi,whdd->lpbiOut) != ICERR_OK)
184 ret = FALSE;
186 TRACE("biSizeImage == %ld\n",whdd->lpbiOut->biSizeImage);
187 TRACE("biCompression == %ld\n",whdd->lpbiOut->biCompression);
188 TRACE("biBitCount == %d\n",whdd->lpbiOut->biBitCount);
190 } else {
191 /* No compression */
192 TRACE("Not compressed!\n");
193 whdd->lpbiOut = HeapAlloc(GetProcessHeap(),0,lpbi->biSize);
194 memcpy(whdd->lpbiOut,lpbi,lpbi->biSize);
197 if (ret) {
198 /*whdd->lpvbuf = HeapAlloc(GetProcessHeap(),0,whdd->lpbiOut->biSizeImage);*/
200 whdd->hMemDC = CreateCompatibleDC(hdc);
201 TRACE("Creating: %ld,%p\n",whdd->lpbiOut->biSize,whdd->lpvbits);
202 whdd->hDib = CreateDIBSection(whdd->hMemDC,(BITMAPINFO *)whdd->lpbiOut,DIB_RGB_COLORS,&(whdd->lpvbits),0,0);
203 if (!whdd->hDib) {
204 TRACE("Error: %ld\n",GetLastError());
206 TRACE("Created: %d,%p\n",whdd->hDib,whdd->lpvbits);
207 whdd->hOldDib = SelectObject(whdd->hMemDC,whdd->hDib);
210 if (ret) {
211 whdd->hdc = hdc;
212 whdd->dxDst = dxDst;
213 whdd->dyDst = dyDst;
214 whdd->lpbi = HeapAlloc(GetProcessHeap(),0,lpbi->biSize);
215 memcpy(whdd->lpbi,lpbi,lpbi->biSize);
216 whdd->dxSrc = dxSrc;
217 whdd->dySrc = dySrc;
218 whdd->begun = TRUE;
219 whdd->hpal = 0;
220 } else {
221 if (whdd->hic)
222 ICClose(whdd->hic);
223 if (whdd->lpbiOut) {
224 HeapFree(GetProcessHeap(),0,whdd->lpbiOut);
225 whdd->lpbiOut = NULL;
229 GlobalUnlock16(hdd);
231 return ret;
234 /************************************************************************
235 * DrawDibBegin [MSVIDEO.104]
237 BOOL16 VFWAPI DrawDibBegin16(HDRAWDIB16 hdd,
238 HDC16 hdc,
239 INT16 dxDst,
240 INT16 dyDst,
241 LPBITMAPINFOHEADER lpbi,
242 INT16 dxSrc,
243 INT16 dySrc,
244 UINT16 wFlags) {
245 return DrawDibBegin(hdd,hdc,dxDst,dyDst,lpbi,dxSrc,dySrc,wFlags);
248 /**********************************************************************
249 * DrawDibDraw [MSVFW32.6]
251 BOOL VFWAPI DrawDibDraw(HDRAWDIB hdd,
252 HDC hdc,
253 INT xDst,
254 INT yDst,
255 INT dxDst,
256 INT dyDst,
257 LPBITMAPINFOHEADER lpbi,
258 LPVOID lpBits,
259 INT xSrc,
260 INT ySrc,
261 INT dxSrc,
262 INT dySrc,
263 UINT wFlags) {
264 WINE_HDD *whdd;
265 BOOL ret = TRUE;
267 TRACE("(%d,0x%lx,%d,%d,%d,%d,%p,%p,%d,%d,%d,%d,0x%08lx)\n",
268 hdd,(DWORD)hdc,xDst,yDst,dxDst,dyDst,lpbi,lpBits,xSrc,ySrc,dxSrc,dySrc,(DWORD)wFlags
271 if (wFlags & ~(DDF_SAME_HDC | DDF_SAME_DRAW | DDF_NOTKEYFRAME))
272 FIXME("wFlags == 0x%08lx not handled\n",(DWORD)wFlags);
274 if (!lpBits) {
275 /* Undocumented? */
276 lpBits = (LPSTR)lpbi + (WORD)(lpbi->biSize) + (WORD)(lpbi->biClrUsed*sizeof(RGBQUAD));
279 whdd = GlobalLock16(hdd);
281 #define CHANGED(x) (whdd->##x != ##x)
283 if ((!whdd->begun) || (!(wFlags & DDF_SAME_HDC) && CHANGED(hdc)) || (!(wFlags & DDF_SAME_DRAW) &&
284 (CHANGED(lpbi) || CHANGED(dxSrc) || CHANGED(dySrc) || CHANGED(dxDst) || CHANGED(dyDst)))) {
285 TRACE("Something changed!\n");
286 ret = DrawDibBegin(hdd,hdc,dxDst,dyDst,lpbi,dxSrc,dySrc,0);
289 #undef CHANGED
291 if ((dxDst == -1) && (dyDst == -1)) {
292 dxDst = dxSrc;
293 dyDst = dySrc;
296 if (lpbi->biCompression) {
297 DWORD flags = 0;
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);
305 } else {
306 memcpy(whdd->lpvbits,lpBits,lpbi->biSizeImage);
309 SelectPalette(hdc,whdd->hpal,FALSE);
311 StretchBlt(whdd->hdc,xDst,yDst,dxDst,dyDst,whdd->hMemDC,xSrc,ySrc,dxSrc,dySrc,SRCCOPY);
313 GlobalUnlock16(hdd);
314 return ret;
317 /**********************************************************************
318 * DrawDibDraw [MSVIDEO.106]
320 BOOL16 VFWAPI DrawDibDraw16(HDRAWDIB16 hdd,
321 HDC16 hdc,
322 INT16 xDst,
323 INT16 yDst,
324 INT16 dxDst,
325 INT16 dyDst,
326 LPBITMAPINFOHEADER lpbi,
327 LPVOID lpBits,
328 INT16 xSrc,
329 INT16 ySrc,
330 INT16 dxSrc,
331 INT16 dySrc,
332 UINT16 wFlags) {
333 return DrawDibDraw(hdd,hdc,xDst,yDst,dxDst,dyDst,lpbi,lpBits,xSrc,ySrc,dxSrc,dySrc,wFlags);
336 /*************************************************************************
337 * DrawDibStart [MSVFW32.14]
339 BOOL VFWAPI DrawDibStart(HDRAWDIB hdd, DWORD rate) {
340 FIXME("(0x%08lx,%ld), stub\n",(DWORD)hdd,rate);
341 return TRUE;
344 /*************************************************************************
345 * DrawDibStart [MSVIDEO.118]
347 BOOL16 VFWAPI DrawDibStart16(HDRAWDIB16 hdd, DWORD rate) {
348 return DrawDibStart(hdd,rate);
351 /*************************************************************************
352 * DrawDibStop [MSVFW32.15]
354 BOOL VFWAPI DrawDibStop(HDRAWDIB hdd) {
355 FIXME("(0x%08lx), stub\n",(DWORD)hdd);
356 return TRUE;
359 /*************************************************************************
360 * DrawDibStop [MSVIDEO.119]
362 BOOL16 DrawDibStop16(HDRAWDIB16 hdd) {
363 return DrawDibStop(hdd);
366 /***********************************************************************
367 * DrawDibSetPalette [MSVFW32.13]
369 BOOL VFWAPI DrawDibSetPalette(HDRAWDIB hdd, HPALETTE hpal) {
370 WINE_HDD *whdd;
372 TRACE("(0x%08lx,0x%08lx)\n",(DWORD)hdd,(DWORD)hpal);
374 whdd = GlobalLock16(hdd);
375 whdd->hpal = hpal;
377 if (whdd->begun) {
378 SelectPalette(whdd->hdc,hpal,0);
379 RealizePalette(whdd->hdc);
381 GlobalUnlock16(hdd);
382 return TRUE;
385 /***********************************************************************
386 * DrawDibSetPalette [MSVIDEO.110]
388 BOOL16 VFWAPI DrawDibSetPalette16(HDRAWDIB16 hdd, HPALETTE16 hpal) {
389 return DrawDibSetPalette(hdd,hpal);
392 /***********************************************************************
393 * DrawDibGetPalette [MSVFW32.9]
395 HPALETTE VFWAPI DrawDibGetPalette(HDRAWDIB hdd) {
396 WINE_HDD *whdd;
397 HPALETTE ret;
399 TRACE("(0x%08lx)\n",(DWORD)hdd);
401 whdd = GlobalLock16(hdd);
402 ret = whdd->hpal;
403 GlobalUnlock16(hdd);
404 return ret;
407 /***********************************************************************
408 * DrawDibGetPalette [MSVIDEO.108]]
410 HPALETTE16 VFWAPI DrawDibGetPalette16(HDRAWDIB16 hdd) {
411 return (HPALETTE16)DrawDibGetPalette(hdd);
414 /***********************************************************************
415 * DrawDibRealize [MSVFW32.12]
417 UINT VFWAPI DrawDibRealize(HDRAWDIB hdd, HDC hdc, BOOL fBackground) {
418 WINE_HDD *whdd;
419 HPALETTE oldPal;
420 UINT ret = 0;
422 FIXME("(%d,0x%08lx,%d), stub\n",hdd,(DWORD)hdc,fBackground);
424 whdd = GlobalLock16(hdd);
426 if (!whdd || !(whdd->begun)) {
427 ret = 0;
428 goto out;
431 if (!whdd->hpal)
432 whdd->hpal = CreateHalftonePalette(hdc);
434 oldPal = SelectPalette(hdc,whdd->hpal,fBackground);
435 ret = RealizePalette(hdc);
437 out:
438 GlobalUnlock16(hdd);
440 TRACE("=> %u\n",ret);
441 return ret;
444 /***********************************************************************
445 * DrawDibRealize [MSVIDEO.112]
447 UINT16 VFWAPI DrawDibRealize16(HDRAWDIB16 hdd, HDC16 hdc, BOOL16 fBackground) {
448 return (UINT16)DrawDibRealize(hdd,hdc,fBackground);