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

Last change on this file since 10367 was 9140, checked in by sandervl, 23 years ago

wine resync; fixed 16 bits handle bugs

File size: 9.9 KB
Line 
1/*
2 * Copyright 2000 Bradley Baetz
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * FIXME: Some flags are ignored
19 *
20 * Handle palettes
21 */
22
23#include <string.h>
24#include "windef.h"
25#include "winbase.h"
26#include "wingdi.h"
27#include "winuser.h"
28#include "wine/winbase16.h"
29#include "wine/debug.h"
30#include "vfw.h"
31#include "vfw16.h"
32#include "windef.h"
33
34WINE_DEFAULT_DEBUG_CHANNEL(msvideo);
35
36typedef struct {
37 HDC hdc;
38 INT dxDst;
39 INT dyDst;
40 LPBITMAPINFOHEADER lpbi;
41 INT dxSrc;
42 INT dySrc;
43 HPALETTE hpal; /* Palette to use for the DIB */
44 BOOL begun; /* DrawDibBegin has been called */
45 LPBITMAPINFOHEADER lpbiOut; /* Output format */
46 HIC hic; /* HIC for decompression */
47 HDC hMemDC; /* DC for buffering */
48 HBITMAP hOldDib; /* Original Dib */
49 HBITMAP hDib; /* DibSection */
50 LPVOID lpvbits; /* Buffer for holding decompressed dib */
51} WINE_HDD;
52
53int num_colours(LPBITMAPINFOHEADER lpbi)
54{
55 if(lpbi->biClrUsed)
56 return lpbi->biClrUsed;
57 if(lpbi->biBitCount<=8)
58 return 1<<lpbi->biBitCount;
59 return 0;
60}
61
62/***********************************************************************
63 * DrawDibOpen [MSVFW32.@]
64 */
65HDRAWDIB VFWAPI DrawDibOpen(void) {
66 HDRAWDIB hdd;
67
68 TRACE("(void)\n");
69 hdd = GlobalAlloc16(GHND,sizeof(WINE_HDD));
70 TRACE("=> %d\n",hdd);
71 return hdd;
72}
73
74/***********************************************************************
75 * DrawDibClose [MSVFW32.@]
76 */
77BOOL VFWAPI DrawDibClose(HDRAWDIB hdd) {
78 WINE_HDD *whdd = GlobalLock16(hdd);
79
80 TRACE("(0x%08lx)\n",(DWORD)hdd);
81
82 if (!whdd)
83 return FALSE;
84
85 if (whdd->begun)
86 DrawDibEnd(hdd);
87
88 GlobalUnlock16(hdd);
89 GlobalFree16(hdd);
90 return TRUE;
91}
92
93/***********************************************************************
94 * DrawDibEnd [MSVFW32.@]
95 */
96BOOL VFWAPI DrawDibEnd(HDRAWDIB hdd) {
97 BOOL ret = TRUE;
98 WINE_HDD *whdd = GlobalLock16(hdd);
99
100 TRACE("(0x%08lx)\n",(DWORD)hdd);
101
102 whdd->hpal = 0; /* Do not free this */
103 whdd->hdc = 0;
104 if (whdd->lpbi) {
105 HeapFree(GetProcessHeap(),0,whdd->lpbi);
106 whdd->lpbi = NULL;
107 }
108 if (whdd->lpbiOut) {
109 HeapFree(GetProcessHeap(),0,whdd->lpbiOut);
110 whdd->lpbiOut = NULL;
111 }
112
113 whdd->begun = FALSE;
114
115 /*if (whdd->lpvbits)
116 HeapFree(GetProcessHeap(),0,whdd->lpvbuf);*/
117
118 if (whdd->hMemDC) {
119 SelectObject(whdd->hMemDC,whdd->hOldDib);
120 DeleteDC(whdd->hMemDC);
121 }
122
123 if (whdd->hDib)
124 DeleteObject(whdd->hDib);
125
126 if (whdd->hic) {
127 ICDecompressEnd(whdd->hic);
128 ICClose(whdd->hic);
129 }
130
131 whdd->lpvbits = NULL;
132
133 GlobalUnlock16(hdd);
134 return ret;
135}
136
137/***********************************************************************
138 * DrawDibBegin [MSVFW32.@]
139 */
140BOOL VFWAPI DrawDibBegin(HDRAWDIB hdd,
141 HDC hdc,
142 INT dxDst,
143 INT dyDst,
144 LPBITMAPINFOHEADER lpbi,
145 INT dxSrc,
146 INT dySrc,
147 UINT wFlags) {
148 BOOL ret = TRUE;
149 WINE_HDD *whdd;
150
151 TRACE("(%d,0x%lx,%d,%d,%p,%d,%d,0x%08lx)\n",
152 hdd,(DWORD)hdc,dxDst,dyDst,lpbi,dxSrc,dySrc,(DWORD)wFlags
153 );
154 TRACE("lpbi: %ld,%ld/%ld,%d,%d,%ld,%ld,%ld,%ld,%ld,%ld\n",
155 lpbi->biSize, lpbi->biWidth, lpbi->biHeight, lpbi->biPlanes,
156 lpbi->biBitCount, lpbi->biCompression, lpbi->biSizeImage,
157 lpbi->biXPelsPerMeter, lpbi->biYPelsPerMeter, lpbi->biClrUsed,
158 lpbi->biClrImportant);
159
160 if (wFlags & ~(DDF_BUFFER))
161 FIXME("wFlags == 0x%08x not handled\n", wFlags & ~(DDF_BUFFER));
162
163 whdd = (WINE_HDD*)GlobalLock16(hdd);
164 if (!whdd) return FALSE;
165
166 if (whdd->begun)
167 DrawDibEnd(hdd);
168
169 if (lpbi->biCompression) {
170 DWORD size = 0;
171
172 whdd->hic = ICOpen(ICTYPE_VIDEO,lpbi->biCompression,ICMODE_DECOMPRESS);
173 if (!whdd->hic) {
174 WARN("Could not open IC. biCompression == 0x%08lx\n",lpbi->biCompression);
175 ret = FALSE;
176 }
177
178 if (ret) {
179 size = ICDecompressGetFormat(whdd->hic,lpbi,NULL);
180 if (size == ICERR_UNSUPPORTED) {
181 WARN("Codec doesn't support GetFormat, giving up.\n");
182 ret = FALSE;
183 }
184 }
185
186 if (ret) {
187 whdd->lpbiOut = HeapAlloc(GetProcessHeap(),0,size);
188
189 if (ICDecompressGetFormat(whdd->hic,lpbi,whdd->lpbiOut) != ICERR_OK)
190 ret = FALSE;
191 }
192
193 if (ret) {
194 /* FIXME: Use Ex functions if available? */
195 if (ICDecompressBegin(whdd->hic,lpbi,whdd->lpbiOut) != ICERR_OK)
196 ret = FALSE;
197
198 TRACE("biSizeImage == %ld\n",whdd->lpbiOut->biSizeImage);
199 TRACE("biCompression == %ld\n",whdd->lpbiOut->biCompression);
200 TRACE("biBitCount == %d\n",whdd->lpbiOut->biBitCount);
201 }
202 } else {
203 DWORD dwSize;
204 /* No compression */
205 TRACE("Not compressed!\n");
206 dwSize = lpbi->biSize + num_colours(lpbi)*sizeof(RGBQUAD);
207 whdd->lpbiOut = HeapAlloc(GetProcessHeap(),0,dwSize);
208 memcpy(whdd->lpbiOut,lpbi,dwSize);
209 }
210
211 if (ret) {
212 /*whdd->lpvbuf = HeapAlloc(GetProcessHeap(),0,whdd->lpbiOut->biSizeImage);*/
213
214 whdd->hMemDC = CreateCompatibleDC(hdc);
215 TRACE("Creating: %ld,%p\n",whdd->lpbiOut->biSize,whdd->lpvbits);
216 whdd->hDib = CreateDIBSection(whdd->hMemDC,(BITMAPINFO *)whdd->lpbiOut,DIB_RGB_COLORS,&(whdd->lpvbits),0,0);
217 if (!whdd->hDib) {
218 TRACE("Error: %ld\n",GetLastError());
219 }
220 TRACE("Created: %d,%p\n",whdd->hDib,whdd->lpvbits);
221 whdd->hOldDib = SelectObject(whdd->hMemDC,whdd->hDib);
222 }
223
224 if (ret) {
225 whdd->hdc = hdc;
226 whdd->dxDst = dxDst;
227 whdd->dyDst = dyDst;
228 whdd->lpbi = HeapAlloc(GetProcessHeap(),0,lpbi->biSize);
229 memcpy(whdd->lpbi,lpbi,lpbi->biSize);
230 whdd->dxSrc = dxSrc;
231 whdd->dySrc = dySrc;
232 whdd->begun = TRUE;
233 whdd->hpal = 0;
234 } else {
235 if (whdd->hic)
236 ICClose(whdd->hic);
237 if (whdd->lpbiOut) {
238 HeapFree(GetProcessHeap(),0,whdd->lpbiOut);
239 whdd->lpbiOut = NULL;
240 }
241 }
242
243 GlobalUnlock16(hdd);
244
245 return ret;
246}
247
248/**********************************************************************
249 * DrawDibDraw [MSVFW32.@]
250 */
251BOOL VFWAPI DrawDibDraw(HDRAWDIB hdd, HDC hdc,
252 INT xDst, INT yDst, INT dxDst, INT dyDst,
253 LPBITMAPINFOHEADER lpbi,
254 LPVOID lpBits,
255 INT xSrc, INT ySrc, INT dxSrc, INT dySrc,
256 UINT wFlags
257) {
258 WINE_HDD *whdd;
259 BOOL ret = TRUE;
260
261 TRACE("(%d,0x%lx,%d,%d,%d,%d,%p,%p,%d,%d,%d,%d,0x%08lx)\n",
262 hdd,(DWORD)hdc,xDst,yDst,dxDst,dyDst,lpbi,lpBits,xSrc,ySrc,dxSrc,dySrc,(DWORD)wFlags
263 );
264
265 if (wFlags & ~(DDF_SAME_HDC | DDF_SAME_DRAW | DDF_NOTKEYFRAME |
266 DDF_UPDATE | DDF_DONTDRAW))
267 FIXME("wFlags == 0x%08lx not handled\n",(DWORD)wFlags);
268
269 if (!lpBits) {
270 /* Undocumented? */
271 lpBits = (LPSTR)lpbi + (WORD)(lpbi->biSize) + (WORD)(num_colours(lpbi)*sizeof(RGBQUAD));
272 }
273
274 whdd = GlobalLock16(hdd);
275
276#define CHANGED(x) (whdd->x != x)
277
278 if ((!whdd->begun) || (!(wFlags & DDF_SAME_HDC) && CHANGED(hdc)) || (!(wFlags & DDF_SAME_DRAW) &&
279 (CHANGED(lpbi) || CHANGED(dxSrc) || CHANGED(dySrc) || CHANGED(dxDst) || CHANGED(dyDst)))) {
280 TRACE("Something changed!\n");
281 ret = DrawDibBegin(hdd,hdc,dxDst,dyDst,lpbi,dxSrc,dySrc,0);
282 }
283
284#undef CHANGED
285
286 if ((dxDst == -1) && (dyDst == -1)) {
287 dxDst = dxSrc;
288 dyDst = dySrc;
289 }
290
291 if (!(wFlags & DDF_UPDATE)) {
292 /* biSizeImage may be set to 0 for BI_RGB (uncompressed) bitmaps */
293 if ((lpbi->biCompression == BI_RGB) && (lpbi->biSizeImage == 0))
294 lpbi->biSizeImage = ((lpbi->biWidth * lpbi->biBitCount + 31) / 32) * 4 * lpbi->biHeight;
295
296 if (lpbi->biCompression) {
297 DWORD flags = 0;
298
299 TRACE("Compression == 0x%08lx\n",lpbi->biCompression);
300
301 if (wFlags & DDF_NOTKEYFRAME)
302 flags |= ICDECOMPRESS_NOTKEYFRAME;
303
304 ICDecompress(whdd->hic,flags,lpbi,lpBits,whdd->lpbiOut,whdd->lpvbits);
305 } else {
306 memcpy(whdd->lpvbits,lpBits,lpbi->biSizeImage);
307 }
308 }
309 if (!(wFlags & DDF_DONTDRAW) && whdd->hpal)
310 SelectPalette(hdc,whdd->hpal,FALSE);
311
312 if (!(StretchBlt(whdd->hdc,xDst,yDst,dxDst,dyDst,whdd->hMemDC,xSrc,ySrc,dxSrc,dySrc,SRCCOPY)))
313 ret = FALSE;
314
315 GlobalUnlock16(hdd);
316 return ret;
317}
318
319/*************************************************************************
320 * DrawDibStart [MSVFW32.@]
321 */
322BOOL VFWAPI DrawDibStart(HDRAWDIB hdd, DWORD rate) {
323 FIXME("(0x%08lx,%ld), stub\n",(DWORD)hdd,rate);
324 return TRUE;
325}
326
327/*************************************************************************
328 * DrawDibStop [MSVFW32.@]
329 */
330BOOL VFWAPI DrawDibStop(HDRAWDIB hdd) {
331 FIXME("(0x%08lx), stub\n",(DWORD)hdd);
332 return TRUE;
333}
334
335/***********************************************************************
336 * DrawDibSetPalette [MSVFW32.@]
337 */
338BOOL VFWAPI DrawDibSetPalette(HDRAWDIB hdd, HPALETTE hpal) {
339 WINE_HDD *whdd;
340
341 TRACE("(0x%08lx,0x%08lx)\n",(DWORD)hdd,(DWORD)hpal);
342
343 whdd = GlobalLock16(hdd);
344 whdd->hpal = hpal;
345
346 if (whdd->begun) {
347 SelectPalette(whdd->hdc,hpal,0);
348 RealizePalette(whdd->hdc);
349 }
350 GlobalUnlock16(hdd);
351 return TRUE;
352}
353
354/***********************************************************************
355 * DrawDibGetPalette [MSVFW32.@]
356 */
357HPALETTE VFWAPI DrawDibGetPalette(HDRAWDIB hdd) {
358 WINE_HDD *whdd;
359 HPALETTE ret;
360
361 TRACE("(0x%08lx)\n",(DWORD)hdd);
362
363 whdd = GlobalLock16(hdd);
364 ret = whdd->hpal;
365 GlobalUnlock16(hdd);
366 return ret;
367}
368
369/***********************************************************************
370 * DrawDibRealize [MSVFW32.@]
371 */
372UINT VFWAPI DrawDibRealize(HDRAWDIB hdd, HDC hdc, BOOL fBackground) {
373 WINE_HDD *whdd;
374 HPALETTE oldPal;
375 UINT ret = 0;
376
377 FIXME("(%d,0x%08lx,%d), stub\n",hdd,(DWORD)hdc,fBackground);
378
379 whdd = GlobalLock16(hdd);
380
381 if (!whdd || !(whdd->begun)) {
382 ret = 0;
383 goto out;
384 }
385
386 if (!whdd->hpal)
387 whdd->hpal = CreateHalftonePalette(hdc);
388
389 oldPal = SelectPalette(hdc,whdd->hpal,fBackground);
390 ret = RealizePalette(hdc);
391
392 out:
393 GlobalUnlock16(hdd);
394
395 TRACE("=> %u\n",ret);
396 return ret;
397}
Note: See TracBrowser for help on using the repository browser.