source: trunk/src/msvfw32/drawdib.c@ 6648

Last change on this file since 6648 was 6648, checked in by bird, 24 years ago

Added $Id:$ keyword.

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