source: trunk/src/msvfw32/drawdib.c

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

wine resync; fixed 16 bits handle bugs

File size: 9.9 KB
RevLine 
[9140]1/*
[6386]2 * Copyright 2000 Bradley Baetz
3 *
[9140]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.
[6386]8 *
[9140]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 *
[6386]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"
[9140]29#include "wine/debug.h"
[6386]30#include "vfw.h"
31#include "vfw16.h"
32#include "windef.h"
33
[9140]34WINE_DEFAULT_DEBUG_CHANNEL(msvideo);
[6386]35
36typedef struct {
[6712]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 */
[6386]51} WINE_HDD;
52
[9140]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}
[6386]61
62/***********************************************************************
[6712]63 * DrawDibOpen [MSVFW32.@]
[6386]64 */
65HDRAWDIB VFWAPI DrawDibOpen(void) {
[6712]66 HDRAWDIB hdd;
[6386]67
[6712]68 TRACE("(void)\n");
69 hdd = GlobalAlloc16(GHND,sizeof(WINE_HDD));
70 TRACE("=> %d\n",hdd);
71 return hdd;
[6386]72}
73
74/***********************************************************************
[6712]75 * DrawDibClose [MSVFW32.@]
[6386]76 */
77BOOL VFWAPI DrawDibClose(HDRAWDIB hdd) {
[6712]78 WINE_HDD *whdd = GlobalLock16(hdd);
[6386]79
[6712]80 TRACE("(0x%08lx)\n",(DWORD)hdd);
[6386]81
[6712]82 if (!whdd)
83 return FALSE;
[6386]84
[6712]85 if (whdd->begun)
86 DrawDibEnd(hdd);
[6386]87
[6712]88 GlobalUnlock16(hdd);
89 GlobalFree16(hdd);
90 return TRUE;
[6386]91}
92
93/***********************************************************************
[6712]94 * DrawDibEnd [MSVFW32.@]
[6386]95 */
96BOOL VFWAPI DrawDibEnd(HDRAWDIB hdd) {
[6712]97 BOOL ret = TRUE;
98 WINE_HDD *whdd = GlobalLock16(hdd);
[9140]99
[6712]100 TRACE("(0x%08lx)\n",(DWORD)hdd);
[6386]101
[6712]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 }
[6386]112
[6712]113 whdd->begun = FALSE;
[6386]114
[6712]115 /*if (whdd->lpvbits)
116 HeapFree(GetProcessHeap(),0,whdd->lpvbuf);*/
[6386]117
[6712]118 if (whdd->hMemDC) {
119 SelectObject(whdd->hMemDC,whdd->hOldDib);
120 DeleteDC(whdd->hMemDC);
121 }
[6386]122
[6712]123 if (whdd->hDib)
124 DeleteObject(whdd->hDib);
[9140]125
[6712]126 if (whdd->hic) {
127 ICDecompressEnd(whdd->hic);
128 ICClose(whdd->hic);
129 }
[6386]130
[6712]131 whdd->lpvbits = NULL;
[6386]132
[6712]133 GlobalUnlock16(hdd);
134 return ret;
[6386]135}
136
137/***********************************************************************
138 * DrawDibBegin [MSVFW32.@]
139 */
140BOOL VFWAPI DrawDibBegin(HDRAWDIB hdd,
[6712]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;
[6386]150
[6712]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",
[9140]155 lpbi->biSize, lpbi->biWidth, lpbi->biHeight, lpbi->biPlanes,
156 lpbi->biBitCount, lpbi->biCompression, lpbi->biSizeImage,
157 lpbi->biXPelsPerMeter, lpbi->biYPelsPerMeter, lpbi->biClrUsed,
[6712]158 lpbi->biClrImportant);
[6386]159
[7511]160 if (wFlags & ~(DDF_BUFFER))
[6712]161 FIXME("wFlags == 0x%08x not handled\n", wFlags & ~(DDF_BUFFER));
[7511]162
[6712]163 whdd = (WINE_HDD*)GlobalLock16(hdd);
164 if (!whdd) return FALSE;
[6386]165
[6712]166 if (whdd->begun)
167 DrawDibEnd(hdd);
[6386]168
[6712]169 if (lpbi->biCompression) {
170 DWORD size = 0;
[6386]171
[6712]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 }
[6386]177
[6712]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 }
[6386]185
[6712]186 if (ret) {
187 whdd->lpbiOut = HeapAlloc(GetProcessHeap(),0,size);
[6386]188
[6712]189 if (ICDecompressGetFormat(whdd->hic,lpbi,whdd->lpbiOut) != ICERR_OK)
190 ret = FALSE;
191 }
[6386]192
[6712]193 if (ret) {
194 /* FIXME: Use Ex functions if available? */
195 if (ICDecompressBegin(whdd->hic,lpbi,whdd->lpbiOut) != ICERR_OK)
196 ret = FALSE;
[6386]197
[6712]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");
[9140]206 dwSize = lpbi->biSize + num_colours(lpbi)*sizeof(RGBQUAD);
[6712]207 whdd->lpbiOut = HeapAlloc(GetProcessHeap(),0,dwSize);
208 memcpy(whdd->lpbiOut,lpbi,dwSize);
209 }
[6386]210
[6712]211 if (ret) {
212 /*whdd->lpvbuf = HeapAlloc(GetProcessHeap(),0,whdd->lpbiOut->biSizeImage);*/
[9140]213
[6712]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 }
[6386]223
[6712]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 }
[6386]242
[6712]243 GlobalUnlock16(hdd);
[6386]244
[6712]245 return ret;
[6386]246}
247
248/**********************************************************************
[6712]249 * DrawDibDraw [MSVFW32.@]
[6386]250 */
251BOOL VFWAPI DrawDibDraw(HDRAWDIB hdd, HDC hdc,
[6712]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
[6386]257) {
[6712]258 WINE_HDD *whdd;
259 BOOL ret = TRUE;
[6386]260
[6712]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 );
[6386]264
[9140]265 if (wFlags & ~(DDF_SAME_HDC | DDF_SAME_DRAW | DDF_NOTKEYFRAME |
[6712]266 DDF_UPDATE | DDF_DONTDRAW))
[7511]267 FIXME("wFlags == 0x%08lx not handled\n",(DWORD)wFlags);
[6386]268
[6712]269 if (!lpBits) {
270 /* Undocumented? */
[9140]271 lpBits = (LPSTR)lpbi + (WORD)(lpbi->biSize) + (WORD)(num_colours(lpbi)*sizeof(RGBQUAD));
[6712]272 }
[6386]273
[6712]274 whdd = GlobalLock16(hdd);
[6386]275
276#define CHANGED(x) (whdd->x != x)
277
[6712]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 }
[6386]283
284#undef CHANGED
285
286 if ((dxDst == -1) && (dyDst == -1)) {
[6712]287 dxDst = dxSrc;
288 dyDst = dySrc;
289 }
[6386]290
[6712]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;
[6386]295
[6712]296 if (lpbi->biCompression) {
297 DWORD flags = 0;
[9140]298
[6712]299 TRACE("Compression == 0x%08lx\n",lpbi->biCompression);
[9140]300
[6712]301 if (wFlags & DDF_NOTKEYFRAME)
302 flags |= ICDECOMPRESS_NOTKEYFRAME;
[9140]303
[6712]304 ICDecompress(whdd->hic,flags,lpbi,lpBits,whdd->lpbiOut,whdd->lpvbits);
305 } else {
306 memcpy(whdd->lpvbits,lpBits,lpbi->biSizeImage);
[9140]307 }
[6712]308 }
309 if (!(wFlags & DDF_DONTDRAW) && whdd->hpal)
310 SelectPalette(hdc,whdd->hpal,FALSE);
[6386]311
[6712]312 if (!(StretchBlt(whdd->hdc,xDst,yDst,dxDst,dyDst,whdd->hMemDC,xSrc,ySrc,dxSrc,dySrc,SRCCOPY)))
313 ret = FALSE;
[6386]314
[6712]315 GlobalUnlock16(hdd);
316 return ret;
[6386]317}
318
319/*************************************************************************
[6712]320 * DrawDibStart [MSVFW32.@]
[6386]321 */
322BOOL VFWAPI DrawDibStart(HDRAWDIB hdd, DWORD rate) {
[6712]323 FIXME("(0x%08lx,%ld), stub\n",(DWORD)hdd,rate);
324 return TRUE;
[6386]325}
326
327/*************************************************************************
[6712]328 * DrawDibStop [MSVFW32.@]
[6386]329 */
330BOOL VFWAPI DrawDibStop(HDRAWDIB hdd) {
[6712]331 FIXME("(0x%08lx), stub\n",(DWORD)hdd);
332 return TRUE;
[6386]333}
334
335/***********************************************************************
336 * DrawDibSetPalette [MSVFW32.@]
337 */
338BOOL VFWAPI DrawDibSetPalette(HDRAWDIB hdd, HPALETTE hpal) {
[6712]339 WINE_HDD *whdd;
[6386]340
[6712]341 TRACE("(0x%08lx,0x%08lx)\n",(DWORD)hdd,(DWORD)hpal);
[6386]342
[6712]343 whdd = GlobalLock16(hdd);
344 whdd->hpal = hpal;
[9140]345
[6712]346 if (whdd->begun) {
347 SelectPalette(whdd->hdc,hpal,0);
348 RealizePalette(whdd->hdc);
349 }
350 GlobalUnlock16(hdd);
351 return TRUE;
[6386]352}
353
354/***********************************************************************
355 * DrawDibGetPalette [MSVFW32.@]
356 */
357HPALETTE VFWAPI DrawDibGetPalette(HDRAWDIB hdd) {
[6712]358 WINE_HDD *whdd;
359 HPALETTE ret;
[6386]360
[6712]361 TRACE("(0x%08lx)\n",(DWORD)hdd);
[6386]362
[6712]363 whdd = GlobalLock16(hdd);
364 ret = whdd->hpal;
365 GlobalUnlock16(hdd);
366 return ret;
[6386]367}
368
369/***********************************************************************
370 * DrawDibRealize [MSVFW32.@]
371 */
372UINT VFWAPI DrawDibRealize(HDRAWDIB hdd, HDC hdc, BOOL fBackground) {
[6712]373 WINE_HDD *whdd;
374 HPALETTE oldPal;
375 UINT ret = 0;
[6386]376
[6712]377 FIXME("(%d,0x%08lx,%d), stub\n",hdd,(DWORD)hdc,fBackground);
[9140]378
[6712]379 whdd = GlobalLock16(hdd);
[6386]380
[6712]381 if (!whdd || !(whdd->begun)) {
382 ret = 0;
383 goto out;
384 }
[9140]385
[6712]386 if (!whdd->hpal)
387 whdd->hpal = CreateHalftonePalette(hdc);
[6386]388
[6712]389 oldPal = SelectPalette(hdc,whdd->hpal,fBackground);
390 ret = RealizePalette(hdc);
[9140]391
[6386]392 out:
[6712]393 GlobalUnlock16(hdd);
[6386]394
[6712]395 TRACE("=> %u\n",ret);
396 return ret;
[6386]397}
Note: See TracBrowser for help on using the repository browser.