Moved most of the 16-bit functions in dlls/msvideo to msvideo16.c.
[wine/multimedia.git] / dlls / msvideo / drawdib.c
blob32e5c47ba75b08e158b7a631e1ea6b2b14aad708
1 /*
2 * Copyright 2000 Bradley Baetz
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.
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.
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
18 * FIXME: Some flags are ignored
20 * Handle palettes
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"
34 WINE_DEFAULT_DEBUG_CHANNEL(msvideo);
36 typedef 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;
53 int num_colours(LPBITMAPINFOHEADER lpbi)
55 if(lpbi->biClrUsed)
56 return lpbi->biClrUsed;
57 if(lpbi->biBitCount<=8)
58 return 1<<lpbi->biBitCount;
59 return 0;
62 /***********************************************************************
63 * DrawDibOpen [MSVFW32.@]
65 HDRAWDIB VFWAPI DrawDibOpen(void) {
66 HDRAWDIB hdd;
68 TRACE("(void)\n");
69 hdd = GlobalAlloc16(GHND,sizeof(WINE_HDD));
70 TRACE("=> %d\n",hdd);
71 return hdd;
74 /***********************************************************************
75 * DrawDibClose [MSVFW32.@]
77 BOOL VFWAPI DrawDibClose(HDRAWDIB hdd) {
78 WINE_HDD *whdd = GlobalLock16(hdd);
80 TRACE("(0x%08lx)\n",(DWORD)hdd);
82 if (!whdd)
83 return FALSE;
85 if (whdd->begun)
86 DrawDibEnd(hdd);
88 GlobalUnlock16(hdd);
89 GlobalFree16(hdd);
90 return TRUE;
93 /***********************************************************************
94 * DrawDibEnd [MSVFW32.@]
96 BOOL VFWAPI DrawDibEnd(HDRAWDIB hdd) {
97 BOOL ret = TRUE;
98 WINE_HDD *whdd = GlobalLock16(hdd);
100 TRACE("(0x%08lx)\n",(DWORD)hdd);
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;
108 if (whdd->lpbiOut) {
109 HeapFree(GetProcessHeap(),0,whdd->lpbiOut);
110 whdd->lpbiOut = NULL;
113 whdd->begun = FALSE;
115 /*if (whdd->lpvbits)
116 HeapFree(GetProcessHeap(),0,whdd->lpvbuf);*/
118 if (whdd->hMemDC) {
119 SelectObject(whdd->hMemDC,whdd->hOldDib);
120 DeleteDC(whdd->hMemDC);
123 if (whdd->hDib)
124 DeleteObject(whdd->hDib);
126 if (whdd->hic) {
127 ICDecompressEnd(whdd->hic);
128 ICClose(whdd->hic);
131 whdd->lpvbits = NULL;
133 GlobalUnlock16(hdd);
134 return ret;
137 /***********************************************************************
138 * DrawDibBegin [MSVFW32.@]
140 BOOL 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;
151 TRACE("(%d,0x%lx,%d,%d,%p,%d,%d,0x%08lx)\n",
152 hdd,(DWORD)hdc,dxDst,dyDst,lpbi,dxSrc,dySrc,(DWORD)wFlags
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);
160 if (wFlags & ~(DDF_BUFFER))
161 FIXME("wFlags == 0x%08x not handled\n", wFlags & ~(DDF_BUFFER));
163 whdd = (WINE_HDD*)GlobalLock16(hdd);
164 if (!whdd) return FALSE;
166 if (whdd->begun)
167 DrawDibEnd(hdd);
169 if (lpbi->biCompression) {
170 DWORD size = 0;
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;
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;
186 if (ret) {
187 whdd->lpbiOut = HeapAlloc(GetProcessHeap(),0,size);
189 if (ICDecompressGetFormat(whdd->hic,lpbi,whdd->lpbiOut) != ICERR_OK)
190 ret = FALSE;
193 if (ret) {
194 /* FIXME: Use Ex functions if available? */
195 if (ICDecompressBegin(whdd->hic,lpbi,whdd->lpbiOut) != ICERR_OK)
196 ret = FALSE;
198 TRACE("biSizeImage == %ld\n",whdd->lpbiOut->biSizeImage);
199 TRACE("biCompression == %ld\n",whdd->lpbiOut->biCompression);
200 TRACE("biBitCount == %d\n",whdd->lpbiOut->biBitCount);
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);
211 if (ret) {
212 /*whdd->lpvbuf = HeapAlloc(GetProcessHeap(),0,whdd->lpbiOut->biSizeImage);*/
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());
220 TRACE("Created: %d,%p\n",whdd->hDib,whdd->lpvbits);
221 whdd->hOldDib = SelectObject(whdd->hMemDC,whdd->hDib);
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;
243 GlobalUnlock16(hdd);
245 return ret;
248 /**********************************************************************
249 * DrawDibDraw [MSVFW32.@]
251 BOOL 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
258 WINE_HDD *whdd;
259 BOOL ret = TRUE;
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
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);
269 if (!lpBits) {
270 /* Undocumented? */
271 lpBits = (LPSTR)lpbi + (WORD)(lpbi->biSize) + (WORD)(num_colours(lpbi)*sizeof(RGBQUAD));
274 whdd = GlobalLock16(hdd);
276 #define CHANGED(x) (whdd->x != x)
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);
284 #undef CHANGED
286 if ((dxDst == -1) && (dyDst == -1)) {
287 dxDst = dxSrc;
288 dyDst = dySrc;
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;
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 if (!(wFlags & DDF_DONTDRAW) && whdd->hpal)
310 SelectPalette(hdc,whdd->hpal,FALSE);
312 if (!(StretchBlt(whdd->hdc,xDst,yDst,dxDst,dyDst,whdd->hMemDC,xSrc,ySrc,dxSrc,dySrc,SRCCOPY)))
313 ret = FALSE;
315 GlobalUnlock16(hdd);
316 return ret;
319 /*************************************************************************
320 * DrawDibStart [MSVFW32.@]
322 BOOL VFWAPI DrawDibStart(HDRAWDIB hdd, DWORD rate) {
323 FIXME("(0x%08lx,%ld), stub\n",(DWORD)hdd,rate);
324 return TRUE;
327 /*************************************************************************
328 * DrawDibStop [MSVFW32.@]
330 BOOL VFWAPI DrawDibStop(HDRAWDIB hdd) {
331 FIXME("(0x%08lx), stub\n",(DWORD)hdd);
332 return TRUE;
335 /***********************************************************************
336 * DrawDibSetPalette [MSVFW32.@]
338 BOOL VFWAPI DrawDibSetPalette(HDRAWDIB hdd, HPALETTE hpal) {
339 WINE_HDD *whdd;
341 TRACE("(0x%08lx,0x%08lx)\n",(DWORD)hdd,(DWORD)hpal);
343 whdd = GlobalLock16(hdd);
344 whdd->hpal = hpal;
346 if (whdd->begun) {
347 SelectPalette(whdd->hdc,hpal,0);
348 RealizePalette(whdd->hdc);
350 GlobalUnlock16(hdd);
351 return TRUE;
354 /***********************************************************************
355 * DrawDibGetPalette [MSVFW32.@]
357 HPALETTE VFWAPI DrawDibGetPalette(HDRAWDIB hdd) {
358 WINE_HDD *whdd;
359 HPALETTE ret;
361 TRACE("(0x%08lx)\n",(DWORD)hdd);
363 whdd = GlobalLock16(hdd);
364 ret = whdd->hpal;
365 GlobalUnlock16(hdd);
366 return ret;
369 /***********************************************************************
370 * DrawDibRealize [MSVFW32.@]
372 UINT VFWAPI DrawDibRealize(HDRAWDIB hdd, HDC hdc, BOOL fBackground) {
373 WINE_HDD *whdd;
374 HPALETTE oldPal;
375 UINT ret = 0;
377 FIXME("(%d,0x%08lx,%d), stub\n",hdd,(DWORD)hdc,fBackground);
379 whdd = GlobalLock16(hdd);
381 if (!whdd || !(whdd->begun)) {
382 ret = 0;
383 goto out;
386 if (!whdd->hpal)
387 whdd->hpal = CreateHalftonePalette(hdc);
389 oldPal = SelectPalette(hdc,whdd->hpal,fBackground);
390 ret = RealizePalette(hdc);
392 out:
393 GlobalUnlock16(hdd);
395 TRACE("=> %u\n",ret);
396 return ret;