Use MsiDecomposeDescriptorW in MsiProvideQualifiedComponentExW.
[wine/multimedia.git] / dlls / msvideo / drawdib.c
blob52f0ecbf577e6eb5b0bcab141dcff3f0f79c230c
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 "msvideo_private.h"
26 #include "wingdi.h"
27 #include "winuser.h"
29 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(msvideo);
33 typedef struct tagWINE_HDD {
34 HDC hdc;
35 INT dxDst;
36 INT dyDst;
37 LPBITMAPINFOHEADER lpbi;
38 INT dxSrc;
39 INT dySrc;
40 HPALETTE hpal; /* Palette to use for the DIB */
41 BOOL begun; /* DrawDibBegin has been called */
42 LPBITMAPINFOHEADER lpbiOut; /* Output format */
43 HIC hic; /* HIC for decompression */
44 HDC hMemDC; /* DC for buffering */
45 HBITMAP hOldDib; /* Original Dib */
46 HBITMAP hDib; /* DibSection */
47 LPVOID lpvbits; /* Buffer for holding decompressed dib */
48 HDRAWDIB hSelf;
49 struct tagWINE_HDD* next;
50 } WINE_HDD;
52 static int num_colours(const LPBITMAPINFOHEADER lpbi)
54 if(lpbi->biClrUsed)
55 return lpbi->biClrUsed;
56 if(lpbi->biBitCount<=8)
57 return 1<<lpbi->biBitCount;
58 return 0;
61 static WINE_HDD* HDD_FirstHdd /* = NULL */;
63 static WINE_HDD* MSVIDEO_GetHddPtr(HDRAWDIB hd)
65 WINE_HDD* hdd;
67 for (hdd = HDD_FirstHdd; hdd != NULL && hdd->hSelf != hd; hdd = hdd->next);
68 return hdd;
71 static DWORD HDD_HandleRef = 1;
73 /***********************************************************************
74 * DrawDibOpen [MSVFW32.@]
76 HDRAWDIB VFWAPI DrawDibOpen(void)
78 WINE_HDD* whdd;
80 TRACE("(void)\n");
82 whdd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_HDD));
83 TRACE("=> %p\n", whdd);
85 while (MSVIDEO_GetHddPtr((HDRAWDIB)HDD_HandleRef) != NULL) HDD_HandleRef++;
86 whdd->hSelf = (HDRAWDIB)HDD_HandleRef++;
88 whdd->next = HDD_FirstHdd;
89 HDD_FirstHdd = whdd;
91 return whdd->hSelf;
94 /***********************************************************************
95 * DrawDibClose [MSVFW32.@]
97 BOOL VFWAPI DrawDibClose(HDRAWDIB hdd)
99 WINE_HDD* whdd = MSVIDEO_GetHddPtr(hdd);
100 WINE_HDD** p;
102 TRACE("(%p)\n", hdd);
104 if (!whdd) return FALSE;
106 if (whdd->begun) DrawDibEnd(hdd);
108 for (p = &HDD_FirstHdd; *p != NULL; p = &((*p)->next))
110 if (*p == whdd)
112 *p = whdd->next;
113 break;
117 HeapFree(GetProcessHeap(), 0, whdd);
119 return TRUE;
122 /***********************************************************************
123 * DrawDibEnd [MSVFW32.@]
125 BOOL VFWAPI DrawDibEnd(HDRAWDIB hdd)
127 BOOL ret = TRUE;
128 WINE_HDD *whdd = MSVIDEO_GetHddPtr(hdd);
130 TRACE("(%p)\n", hdd);
132 whdd->hpal = 0; /* Do not free this */
133 whdd->hdc = 0;
134 HeapFree(GetProcessHeap(), 0, whdd->lpbi);
135 whdd->lpbi = NULL;
136 HeapFree(GetProcessHeap(), 0, whdd->lpbiOut);
137 whdd->lpbiOut = NULL;
139 whdd->begun = FALSE;
141 /*if (whdd->lpvbits)
142 HeapFree(GetProcessHeap(), 0, whdd->lpvbuf);*/
144 if (whdd->hMemDC)
146 SelectObject(whdd->hMemDC, whdd->hOldDib);
147 DeleteDC(whdd->hMemDC);
148 whdd->hMemDC = 0;
151 if (whdd->hDib) DeleteObject(whdd->hDib);
152 whdd->hDib = 0;
154 if (whdd->hic)
156 ICDecompressEnd(whdd->hic);
157 ICClose(whdd->hic);
158 whdd->hic = 0;
161 whdd->lpvbits = NULL;
163 return ret;
166 /***********************************************************************
167 * DrawDibBegin [MSVFW32.@]
169 BOOL VFWAPI DrawDibBegin(HDRAWDIB hdd,
170 HDC hdc,
171 INT dxDst,
172 INT dyDst,
173 LPBITMAPINFOHEADER lpbi,
174 INT dxSrc,
175 INT dySrc,
176 UINT wFlags)
178 BOOL ret = TRUE;
179 WINE_HDD *whdd;
181 TRACE("(%p,%p,%d,%d,%p,%d,%d,0x%08lx)\n",
182 hdd, hdc, dxDst, dyDst, lpbi, dxSrc, dySrc, (DWORD)wFlags);
184 TRACE("lpbi: %ld,%ld/%ld,%d,%d,%ld,%ld,%ld,%ld,%ld,%ld\n",
185 lpbi->biSize, lpbi->biWidth, lpbi->biHeight, lpbi->biPlanes,
186 lpbi->biBitCount, lpbi->biCompression, lpbi->biSizeImage,
187 lpbi->biXPelsPerMeter, lpbi->biYPelsPerMeter, lpbi->biClrUsed,
188 lpbi->biClrImportant);
190 if (wFlags & ~(DDF_BUFFER))
191 FIXME("wFlags == 0x%08x not handled\n", wFlags & ~(DDF_BUFFER));
193 whdd = MSVIDEO_GetHddPtr(hdd);
194 if (!whdd) return FALSE;
196 if (whdd->begun) DrawDibEnd(hdd);
198 if (lpbi->biCompression)
200 DWORD size = 0;
202 whdd->hic = ICOpen(ICTYPE_VIDEO, lpbi->biCompression, ICMODE_DECOMPRESS);
203 if (!whdd->hic)
205 WARN("Could not open IC. biCompression == 0x%08lx\n", lpbi->biCompression);
206 ret = FALSE;
209 if (ret)
211 size = ICDecompressGetFormat(whdd->hic, lpbi, NULL);
212 if (size == ICERR_UNSUPPORTED)
214 WARN("Codec doesn't support GetFormat, giving up.\n");
215 ret = FALSE;
219 if (ret)
221 whdd->lpbiOut = HeapAlloc(GetProcessHeap(), 0, size);
223 if (ICDecompressGetFormat(whdd->hic, lpbi, whdd->lpbiOut) != ICERR_OK)
224 ret = FALSE;
227 if (ret)
229 /* FIXME: Use Ex functions if available? */
230 if (ICDecompressBegin(whdd->hic, lpbi, whdd->lpbiOut) != ICERR_OK)
231 ret = FALSE;
233 TRACE("biSizeImage == %ld\n", whdd->lpbiOut->biSizeImage);
234 TRACE("biCompression == %ld\n", whdd->lpbiOut->biCompression);
235 TRACE("biBitCount == %d\n", whdd->lpbiOut->biBitCount);
238 else
240 DWORD dwSize;
241 /* No compression */
242 TRACE("Not compressed!\n");
243 dwSize = lpbi->biSize + num_colours(lpbi)*sizeof(RGBQUAD);
244 whdd->lpbiOut = HeapAlloc(GetProcessHeap(), 0, dwSize);
245 memcpy(whdd->lpbiOut, lpbi, dwSize);
248 if (ret)
250 /*whdd->lpvbuf = HeapAlloc(GetProcessHeap(), 0, whdd->lpbiOut->biSizeImage);*/
252 whdd->hMemDC = CreateCompatibleDC(hdc);
253 TRACE("Creating: %ld, %p\n", whdd->lpbiOut->biSize, whdd->lpvbits);
254 whdd->hDib = CreateDIBSection(whdd->hMemDC, (BITMAPINFO *)whdd->lpbiOut, DIB_RGB_COLORS, &(whdd->lpvbits), 0, 0);
255 if (whdd->hDib)
257 TRACE("Created: %p,%p\n", whdd->hDib, whdd->lpvbits);
259 else
261 ret = FALSE;
262 TRACE("Error: %ld\n", GetLastError());
264 whdd->hOldDib = SelectObject(whdd->hMemDC, whdd->hDib);
267 if (ret)
269 whdd->hdc = hdc;
270 whdd->dxDst = dxDst;
271 whdd->dyDst = dyDst;
272 whdd->lpbi = HeapAlloc(GetProcessHeap(), 0, lpbi->biSize);
273 memcpy(whdd->lpbi, lpbi, lpbi->biSize);
274 whdd->dxSrc = dxSrc;
275 whdd->dySrc = dySrc;
276 whdd->begun = TRUE;
277 whdd->hpal = 0;
279 else
281 if (whdd->hic)
282 ICClose(whdd->hic);
283 HeapFree(GetProcessHeap(), 0, whdd->lpbiOut);
284 whdd->lpbiOut = NULL;
287 return ret;
290 /**********************************************************************
291 * DrawDibDraw [MSVFW32.@]
293 BOOL VFWAPI DrawDibDraw(HDRAWDIB hdd, HDC hdc,
294 INT xDst, INT yDst, INT dxDst, INT dyDst,
295 LPBITMAPINFOHEADER lpbi,
296 LPVOID lpBits,
297 INT xSrc, INT ySrc, INT dxSrc, INT dySrc,
298 UINT wFlags)
300 WINE_HDD *whdd;
301 BOOL ret = TRUE;
303 TRACE("(%p,%p,%d,%d,%d,%d,%p,%p,%d,%d,%d,%d,0x%08lx)\n",
304 hdd, hdc, xDst, yDst, dxDst, dyDst, lpbi, lpBits, xSrc, ySrc, dxSrc, dySrc, (DWORD)wFlags);
306 whdd = MSVIDEO_GetHddPtr(hdd);
307 if (!whdd) return FALSE;
309 TRACE("whdd=%p\n", whdd);
311 if (wFlags & ~(DDF_SAME_HDC | DDF_SAME_DRAW | DDF_NOTKEYFRAME | DDF_UPDATE | DDF_DONTDRAW | DDF_BACKGROUNDPAL))
312 FIXME("wFlags == 0x%08lx not handled\n", (DWORD)wFlags);
314 if (!lpBits)
316 /* Undocumented? */
317 lpBits = (LPSTR)lpbi + (WORD)(lpbi->biSize) + (WORD)(num_colours(lpbi)*sizeof(RGBQUAD));
321 #define CHANGED(x) (whdd->x != x)
323 if ((!whdd->begun) ||
324 (!(wFlags & DDF_SAME_HDC) && CHANGED(hdc)) ||
325 (!(wFlags & DDF_SAME_DRAW) && (CHANGED(lpbi) || CHANGED(dxSrc) || CHANGED(dySrc) || CHANGED(dxDst) || CHANGED(dyDst))))
327 TRACE("Something changed!\n");
328 ret = DrawDibBegin(hdd, hdc, dxDst, dyDst, lpbi, dxSrc, dySrc, 0);
331 #undef CHANGED
333 if ((dxDst == -1) && (dyDst == -1))
335 dxDst = dxSrc;
336 dyDst = dySrc;
339 if (!(wFlags & DDF_UPDATE))
341 DWORD biSizeImage = lpbi->biSizeImage;
343 /* biSizeImage may be set to 0 for BI_RGB (uncompressed) bitmaps */
344 if ((lpbi->biCompression == BI_RGB) && (biSizeImage == 0))
345 biSizeImage = ((lpbi->biWidth * lpbi->biBitCount + 31) / 32) * 4 * lpbi->biHeight;
347 if (lpbi->biCompression)
349 DWORD flags = 0;
351 TRACE("Compression == 0x%08lx\n", lpbi->biCompression);
353 if (wFlags & DDF_NOTKEYFRAME)
354 flags |= ICDECOMPRESS_NOTKEYFRAME;
356 ICDecompress(whdd->hic, flags, lpbi, lpBits, whdd->lpbiOut, whdd->lpvbits);
358 else
360 memcpy(whdd->lpvbits, lpBits, biSizeImage);
363 if (!(wFlags & DDF_DONTDRAW) && whdd->hpal)
365 if ((wFlags & DDF_BACKGROUNDPAL) && ! (wFlags & DDF_SAME_HDC))
366 SelectPalette(hdc, whdd->hpal, TRUE);
367 else
368 SelectPalette(hdc, whdd->hpal, FALSE);
371 if (!(StretchBlt(whdd->hdc, xDst, yDst, dxDst, dyDst, whdd->hMemDC, xSrc, ySrc, dxSrc, dySrc, SRCCOPY)))
372 ret = FALSE;
374 return ret;
377 /*************************************************************************
378 * DrawDibStart [MSVFW32.@]
380 BOOL VFWAPI DrawDibStart(HDRAWDIB hdd, DWORD rate) {
381 FIXME("(%p, %ld), stub\n", hdd, rate);
382 return TRUE;
385 /*************************************************************************
386 * DrawDibStop [MSVFW32.@]
388 BOOL VFWAPI DrawDibStop(HDRAWDIB hdd) {
389 FIXME("(%p), stub\n", hdd);
390 return TRUE;
393 /***********************************************************************
394 * DrawDibChangePalette [MSVFW32.@]
396 BOOL VFWAPI DrawDibChangePalette(HDRAWDIB hdd, int iStart, int iLen, LPPALETTEENTRY lppe)
398 FIXME("(%p, 0x%08x, 0x%08x, %p), stub\n", hdd, iStart, iLen, lppe);
399 return TRUE;
402 /***********************************************************************
403 * DrawDibSetPalette [MSVFW32.@]
405 BOOL VFWAPI DrawDibSetPalette(HDRAWDIB hdd, HPALETTE hpal)
407 WINE_HDD *whdd;
409 TRACE("(%p, %p)\n", hdd, hpal);
411 whdd = MSVIDEO_GetHddPtr(hdd);
412 if (!whdd) return FALSE;
414 whdd->hpal = hpal;
416 if (whdd->begun)
418 SelectPalette(whdd->hdc, hpal, 0);
419 RealizePalette(whdd->hdc);
422 return TRUE;
425 /***********************************************************************
426 * DrawDibGetBuffer [MSVFW32.@]
428 LPVOID VFWAPI DrawDibGetBuffer(HDRAWDIB hdd, LPBITMAPINFOHEADER lpbi, DWORD dwSize, DWORD dwFlags)
430 FIXME("(%p, %p, 0x%08lx, 0x%08lx), stub\n", hdd, lpbi, dwSize, dwFlags);
431 return NULL;
434 /***********************************************************************
435 * DrawDibGetPalette [MSVFW32.@]
437 HPALETTE VFWAPI DrawDibGetPalette(HDRAWDIB hdd)
439 WINE_HDD *whdd;
441 TRACE("(%p)\n", hdd);
443 whdd = MSVIDEO_GetHddPtr(hdd);
444 if (!whdd) return FALSE;
446 return whdd->hpal;
449 /***********************************************************************
450 * DrawDibRealize [MSVFW32.@]
452 UINT VFWAPI DrawDibRealize(HDRAWDIB hdd, HDC hdc, BOOL fBackground)
454 WINE_HDD *whdd;
455 HPALETTE oldPal;
456 UINT ret = 0;
458 FIXME("(%p, %p, %d), stub\n", hdd, hdc, fBackground);
460 whdd = MSVIDEO_GetHddPtr(hdd);
461 if (!whdd) return FALSE;
463 if (!whdd || !(whdd->begun))
465 ret = 0;
466 goto out;
469 if (!whdd->hpal)
470 whdd->hpal = CreateHalftonePalette(hdc);
472 oldPal = SelectPalette(hdc, whdd->hpal, fBackground);
473 ret = RealizePalette(hdc);
475 out:
476 TRACE("=> %u\n", ret);
477 return ret;
480 /***********************************************************************
481 * DrawDibTime [MSVFW32.@]
483 BOOL VFWAPI DrawDibTime(HDRAWDIB hdd, LPDRAWDIBTIME lpddtime)
485 FIXME("(%p, %p) stub\n", hdd, lpddtime);
486 return FALSE;
489 /***********************************************************************
490 * DrawDibProfileDisplay [MSVFW32.@]
492 DWORD VFWAPI DrawDibProfileDisplay(LPBITMAPINFOHEADER lpbi)
494 FIXME("(%p) stub\n", lpbi);
496 return PD_CAN_DRAW_DIB;