Return empty string on error in WM_GETTEXT.
[wine/gsoc_dplay.git] / dlls / msvideo / msvideo_main.c
blob66c0b8638d6dd707de7ebcf3e883559dfc5b0c94
1 /*
2 * Copyright 1998 Marcus Meissner
3 * Copyright 2000 Bradley Baetz
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 * FIXME: This all assumes 32 bit codecs
20 * Win95 appears to prefer 32 bit codecs, even from 16 bit code.
21 * There is the ICOpenFunction16 to worry about still, though.
24 #include <stdio.h>
25 #include <string.h>
27 #include "winbase.h"
28 #include "windef.h"
29 #include "winnls.h"
30 #include "wingdi.h"
31 #include "winuser.h"
32 #include "winver.h"
33 #include "vfw.h"
34 #include "vfw16.h"
35 #include "wine/winbase16.h"
36 #include "wine/debug.h"
37 #include "stackframe.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(msvideo);
41 /* ### start build ### */
42 extern LONG CALLBACK MSVIDEO_CallTo16_long_lwwll(FARPROC16,LONG,WORD,WORD,LONG,LONG);
43 /* ### stop build ### */
45 LPVOID MSVIDEO_MapMsg16To32(UINT msg, LPDWORD lParam1, LPDWORD lParam2);
46 void MSVIDEO_UnmapMsg16To32(UINT msg, LPVOID lpv, LPDWORD lParam1, LPDWORD lParam2);
47 LRESULT MSVIDEO_SendMessage(HIC hic, UINT msg, DWORD lParam1, DWORD lParam2, BOOL bFrom32);
49 /***********************************************************************
50 * VideoForWindowsVersion [MSVFW32.2]
51 * VideoForWindowsVersion [MSVIDEO.2]
52 * Returns the version in major.minor form.
53 * In Windows95 this returns 0x040003b6 (4.950)
55 DWORD WINAPI VideoForWindowsVersion(void) {
56 return 0x040003B6; /* 4.950 */
59 /***********************************************************************
60 * VideoCapDriverDescAndVer [MSVIDEO.22]
62 DWORD WINAPI VideoCapDriverDescAndVer(
63 WORD nr,LPSTR buf1,WORD buf1len,LPSTR buf2,WORD buf2len
64 ) {
65 DWORD verhandle;
66 WORD xnr = nr;
67 DWORD infosize;
68 UINT subblocklen;
69 char *s,buf[2000],fn[260];
70 LPBYTE infobuf;
71 LPVOID subblock;
73 TRACE("(%d,%p,%d,%p,%d)\n",nr,buf1,buf1len,buf2,buf2len);
74 if (GetPrivateProfileStringA("drivers32",NULL,NULL,buf,sizeof(buf),"system.ini")) {
75 s = buf;
76 while (*s) {
77 if (!strncasecmp(s,"vid",3)) {
78 if (!xnr)
79 break;
80 xnr--;
82 s=s+strlen(s)+1; /* either next char or \0 */
84 } else
85 return 20; /* hmm, out of entries even if we don't have any */
86 if (xnr) {
87 FIXME("No more VID* entries found\n");
88 return 20;
90 GetPrivateProfileStringA("drivers32",s,NULL,fn,sizeof(fn),"system.ini");
91 infosize = GetFileVersionInfoSizeA(fn,&verhandle);
92 if (!infosize) {
93 TRACE("%s has no fileversioninfo.\n",fn);
94 return 18;
96 infobuf = HeapAlloc(GetProcessHeap(),0,infosize);
97 if (GetFileVersionInfoA(fn,verhandle,infosize,infobuf)) {
98 char vbuf[200];
99 /* Yes, two space behind : */
100 /* FIXME: test for buflen */
101 sprintf(vbuf,"Version: %d.%d.%d.%d\n",
102 ((WORD*)infobuf)[0x0f],
103 ((WORD*)infobuf)[0x0e],
104 ((WORD*)infobuf)[0x11],
105 ((WORD*)infobuf)[0x10]
107 TRACE("version of %s is %s\n",fn,vbuf);
108 strncpy(buf2,vbuf,buf2len);
109 } else {
110 TRACE("GetFileVersionInfoA failed for %s.\n",fn);
111 strncpy(buf2,fn,buf2len); /* msvideo.dll appears to copy fn*/
113 /* FIXME: language problem? */
114 if (VerQueryValueA( infobuf,
115 "\\StringFileInfo\\040904E4\\FileDescription",
116 &subblock,
117 &subblocklen
118 )) {
119 TRACE("VQA returned %s\n",(LPCSTR)subblock);
120 strncpy(buf1,subblock,buf1len);
121 } else {
122 TRACE("VQA did not return on query \\StringFileInfo\\040904E4\\FileDescription?\n");
123 strncpy(buf1,fn,buf1len); /* msvideo.dll appears to copy fn*/
125 HeapFree(GetProcessHeap(),0,infobuf);
126 return 0;
129 /* system.ini: [drivers] */
131 /***********************************************************************
132 * ICInfo [MSVFW32.@]
133 * Get information about an installable compressor. Return TRUE if there
134 * is one.
136 BOOL VFWAPI ICInfo(
137 DWORD fccType, /* [in] type of compressor ('vidc') */
138 DWORD fccHandler, /* [in] <n>th compressor */
139 ICINFO *lpicinfo) /* [out] information about compressor */
141 char type[5],buf[2000];
143 memcpy(type,&fccType,4);type[4]=0;
144 TRACE("(%s,%ld,%p).\n",type,fccHandler,lpicinfo);
145 /* does OpenDriver/CloseDriver */
146 lpicinfo->dwSize = sizeof(ICINFO);
147 lpicinfo->fccType = fccType;
148 lpicinfo->dwFlags = 0;
149 if (GetPrivateProfileStringA("drivers32",NULL,NULL,buf,2000,"system.ini")) {
150 char *s = buf;
151 while (*s) {
152 if (!strncasecmp(type,s,4)) {
153 if(!fccHandler--) {
154 lpicinfo->fccHandler = mmioStringToFOURCCA(s+5,0);
155 return TRUE;
158 s=s+strlen(s)+1; /* either next char or \0 */
161 return FALSE;
164 /***********************************************************************
165 * ICInfo [MSVIDEO.200]
167 BOOL16 VFWAPI ICInfo16(
168 DWORD fccType, /* [in] */
169 DWORD fccHandler, /* [in] */
170 ICINFO16 *lpicinfo) /* [in/out] NOTE: SEGPTR */
172 BOOL16 ret;
173 LPVOID lpv;
174 DWORD lParam = (DWORD)lpicinfo;
175 DWORD size = ((ICINFO*)(MapSL((SEGPTR)lpicinfo)))->dwSize;
177 /* Use the mapping functions to map the ICINFO structure */
178 lpv = MSVIDEO_MapMsg16To32(ICM_GETINFO,&lParam,&size);
180 ret = ICInfo(fccType,fccHandler,(ICINFO*)lParam);
182 MSVIDEO_UnmapMsg16To32(ICM_GETINFO,lpv,&lParam,&size);
184 return ret;
187 /***********************************************************************
188 * ICOpen [MSVFW32.@]
189 * Opens an installable compressor. Return special handle.
191 HIC VFWAPI ICOpen(DWORD fccType,DWORD fccHandler,UINT wMode) {
192 char type[5],handler[5],codecname[20];
193 ICOPEN icopen;
194 HDRVR hdrv;
195 HIC16 hic;
196 WINE_HIC *whic;
198 memcpy(type,&fccType,4);type[4]=0;
199 memcpy(handler,&fccHandler,4);handler[4]=0;
200 TRACE("(%s,%s,0x%08lx)\n",type,handler,(DWORD)wMode);
202 sprintf(codecname,"%s.%s",type,handler);
204 /* Well, lParam2 is in fact a LPVIDEO_OPEN_PARMS, but it has the
205 * same layout as ICOPEN
207 icopen.fccType = fccType;
208 icopen.fccHandler = fccHandler;
209 icopen.dwSize = sizeof(ICOPEN);
210 icopen.dwFlags = wMode;
211 /* FIXME: do we need to fill out the rest too? */
212 hdrv=OpenDriverA(codecname,"drivers32",(LPARAM)&icopen);
213 if (!hdrv) {
214 if (!strcasecmp(type,"vids")) {
215 sprintf(codecname,"vidc.%s",handler);
216 fccType = mmioFOURCC('v','i','d','c');
218 hdrv=OpenDriverA(codecname,"drivers32",(LPARAM)&icopen);
219 if (!hdrv)
220 return 0;
222 /* The handle should be a valid 16-bit handle as well */
223 hic = GlobalAlloc16(GHND,sizeof(WINE_HIC));
224 whic = (WINE_HIC*)GlobalLock16(hic);
225 whic->hdrv = hdrv;
226 whic->driverproc= NULL;
227 whic->private = 0;
228 GlobalUnlock16(hic);
229 TRACE("=> 0x%08lx\n",(DWORD)hic);
230 return hic;
233 HIC MSVIDEO_OpenFunc(DWORD fccType, DWORD fccHandler, UINT wMode, FARPROC lpfnHandler, BOOL bFrom32) {
234 char type[5],handler[5],codecname[20];
235 HIC16 hic;
236 ICOPEN icopen;
237 SEGPTR seg_icopen;
238 WINE_HIC *whic;
240 memcpy(type,&fccType,4);type[4]=0;
241 memcpy(handler,&fccHandler,4);handler[4]=0;
242 TRACE("(%s,%s,%d,%p,%d)\n",type,handler,wMode,lpfnHandler,bFrom32?32:16);
244 icopen.fccType = fccType;
245 icopen.fccHandler = fccHandler;
246 icopen.dwSize = sizeof(ICOPEN);
247 icopen.dwFlags = wMode;
249 sprintf(codecname,"%s.%s",type,handler);
251 hic = GlobalAlloc16(GHND,sizeof(WINE_HIC));
252 if (!hic)
253 return 0;
254 whic = GlobalLock16(hic);
255 whic->driverproc = lpfnHandler;
257 whic->private = bFrom32;
259 /* Now try opening/loading the driver. Taken from DRIVER_AddToList */
260 /* What if the function is used more than once? */
262 if (MSVIDEO_SendMessage(hic,DRV_LOAD,0L,0L,bFrom32) != DRV_SUCCESS) {
263 WARN("DRV_LOAD failed for hic 0x%08lx\n",(DWORD)hic);
264 GlobalFree16(hic);
265 return 0;
267 /* return value is not checked */
268 MSVIDEO_SendMessage(hic,DRV_ENABLE,0L,0L,bFrom32);
270 seg_icopen = MapLS( &icopen );
271 whic->hdrv = MSVIDEO_SendMessage(hic,DRV_OPEN,0,seg_icopen,FALSE);
272 UnMapLS( seg_icopen );
273 if (whic->hdrv == 0) {
274 WARN("DRV_OPEN failed for hic 0x%08lx\n",(DWORD)hic);
275 GlobalFree16(hic);
276 return 0;
279 GlobalUnlock16(hic);
280 TRACE("=> 0x%08lx\n",(DWORD)hic);
281 return hic;
284 /***********************************************************************
285 * ICOpenFunction [MSVFW32.@]
287 HIC VFWAPI ICOpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, FARPROC lpfnHandler) {
288 return MSVIDEO_OpenFunc(fccType,fccHandler,wMode,lpfnHandler,TRUE);
291 /***********************************************************************
292 * ICOpen [MSVIDEO.203]
294 HIC16 VFWAPI ICOpen16(DWORD fccType, DWORD fccHandler, UINT16 wMode) {
295 return (HIC16)ICOpen(fccType, fccHandler, wMode);
298 /***********************************************************************
299 * ICOpenFunction [MSVIDEO.206]
301 HIC16 VFWAPI ICOpenFunction16(DWORD fccType, DWORD fccHandler, UINT16 wMode, FARPROC16 lpfnHandler)
303 return MSVIDEO_OpenFunc(fccType, fccHandler, wMode, (FARPROC)lpfnHandler,FALSE);
306 /***********************************************************************
307 * ICGetInfo [MSVFW32.@]
309 LRESULT VFWAPI ICGetInfo(HIC hic,ICINFO *picinfo,DWORD cb) {
310 LRESULT ret;
312 TRACE("(0x%08lx,%p,%ld)\n",(DWORD)hic,picinfo,cb);
313 ret = ICSendMessage(hic,ICM_GETINFO,(DWORD)picinfo,cb);
314 TRACE(" -> 0x%08lx\n",ret);
315 return ret;
318 /***********************************************************************
319 * ICGetInfo [MSVIDEO.212]
321 LRESULT VFWAPI ICGetInfo16(HIC16 hic, ICINFO16 *picinfo,DWORD cb) {
322 LRESULT ret;
324 TRACE("(0x%08lx,%p,%ld)\n",(DWORD)hic,picinfo,cb);
325 ret = ICSendMessage16(hic,ICM_GETINFO,(DWORD)picinfo,cb);
326 TRACE(" -> 0x%08lx\n",ret);
327 return ret;
330 /***********************************************************************
331 * ICLocate [MSVFW32.@]
333 HIC VFWAPI ICLocate(
334 DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn,
335 LPBITMAPINFOHEADER lpbiOut, WORD wMode)
337 char type[5],handler[5];
338 HIC hic;
339 DWORD querymsg;
340 LPSTR pszBuffer;
342 type[4]=0;memcpy(type,&fccType,4);
343 handler[4]=0;memcpy(handler,&fccHandler,4);
345 TRACE("(%s,%s,%p,%p,0x%04x)\n", type, handler, lpbiIn, lpbiOut, wMode);
347 switch (wMode) {
348 case ICMODE_FASTCOMPRESS:
349 case ICMODE_COMPRESS:
350 querymsg = ICM_COMPRESS_QUERY;
351 break;
352 case ICMODE_FASTDECOMPRESS:
353 case ICMODE_DECOMPRESS:
354 querymsg = ICM_DECOMPRESS_QUERY;
355 break;
356 case ICMODE_DRAW:
357 querymsg = ICM_DRAW_QUERY;
358 break;
359 default:
360 WARN("Unknown mode (%d)\n",wMode);
361 return 0;
364 /* Easy case: handler/type match, we just fire a query and return */
365 hic = ICOpen(fccType,fccHandler,wMode);
366 if (hic) {
367 if (!ICSendMessage(hic,querymsg,(DWORD)lpbiIn,(DWORD)lpbiOut))
368 return hic;
369 ICClose(hic);
372 type[4]='.';memcpy(type,&fccType,4);
373 handler[4]='.';memcpy(handler,&fccHandler,4);
375 /* Now try each driver in turn. 32 bit codecs only. */
376 /* FIXME: Move this to an init routine? */
378 pszBuffer = (LPSTR)HeapAlloc(GetProcessHeap(),0,1024);
379 if (GetPrivateProfileSectionA("drivers32",pszBuffer,1024,"system.ini")) {
380 char* s = pszBuffer;
381 while (*s) {
382 if (!strncasecmp(type,s,5)) {
383 char *s2 = s;
384 while (*s2 != '\0' && *s2 != '.') s2++;
385 if (*s2++) {
386 HIC h;
388 h = ICOpen(fccType,*(DWORD*)s2,wMode);
389 if (h) {
390 if (!ICSendMessage(h,querymsg,(DWORD)lpbiIn,(DWORD)lpbiOut))
391 return h;
392 ICClose(h);
396 s += strlen(s) + 1;
399 HeapFree(GetProcessHeap(),0,pszBuffer);
401 if (fccType==streamtypeVIDEO) {
402 hic = ICLocate(ICTYPE_VIDEO,fccHandler,lpbiIn,lpbiOut,wMode);
403 if (hic)
404 return hic;
407 type[4] = handler[4] = '\0';
408 WARN("(%.4s,%.4s,%p,%p,0x%04x) not found!\n",type,handler,lpbiIn,lpbiOut,wMode);
409 return 0;
412 /***********************************************************************
413 * ICLocate [MSVIDEO.213]
415 HIC16 VFWAPI ICLocate16(DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn,
416 LPBITMAPINFOHEADER lpbiOut, WORD wFlags) {
417 return (HIC16)ICLocate(fccType, fccHandler, lpbiIn, lpbiOut, wFlags);
420 /***********************************************************************
421 * ICGetDisplayFormat [MSVFW32.@]
423 HIC VFWAPI ICGetDisplayFormat(
424 HIC hic,LPBITMAPINFOHEADER lpbiIn,LPBITMAPINFOHEADER lpbiOut,
425 INT depth,INT dx,INT dy)
427 HIC tmphic = hic;
429 FIXME("(0x%08lx,%p,%p,%d,%d,%d),stub!\n",(DWORD)hic,lpbiIn,lpbiOut,depth,dx,dy);
430 if (!tmphic) {
431 tmphic=ICLocate(ICTYPE_VIDEO,0,lpbiIn,NULL,ICMODE_DECOMPRESS);
432 if (!tmphic)
433 return tmphic;
435 if ((dy == lpbiIn->biHeight) && (dx == lpbiIn->biWidth))
436 dy = dx = 0; /* no resize needed */
438 /* Can we decompress it ? */
439 if (ICDecompressQuery(tmphic,lpbiIn,NULL) != 0)
440 goto errout; /* no, sorry */
442 ICDecompressGetFormat(tmphic,lpbiIn,lpbiOut);
444 if (lpbiOut->biCompression != 0) {
445 FIXME("Ooch, how come decompressor outputs compressed data (%ld)??\n",
446 lpbiOut->biCompression);
448 if (lpbiOut->biSize < sizeof(*lpbiOut)) {
449 FIXME("Ooch, size of output BIH is too small (%ld)\n",
450 lpbiOut->biSize);
451 lpbiOut->biSize = sizeof(*lpbiOut);
453 if (!depth) {
454 HDC hdc;
456 hdc = GetDC(0);
457 depth = GetDeviceCaps(hdc,BITSPIXEL)*GetDeviceCaps(hdc,PLANES);
458 ReleaseDC(0,hdc);
459 if (depth==15) depth = 16;
460 if (depth<8) depth = 8;
462 if (lpbiIn->biBitCount == 8)
463 depth = 8;
465 TRACE("=> 0x%08lx\n",(DWORD)tmphic);
466 return tmphic;
467 errout:
468 if (hic!=tmphic)
469 ICClose(tmphic);
471 TRACE("=> 0\n");
472 return 0;
475 /***********************************************************************
476 * ICGetDisplayFormat [MSVIDEO.239]
478 HIC16 VFWAPI ICGetDisplayFormat16(HIC16 hic, LPBITMAPINFOHEADER lpbiIn,
479 LPBITMAPINFOHEADER lpbiOut, INT16 depth, INT16 dx, INT16 dy) {
480 return (HIC16)ICGetDisplayFormat(hic,lpbiIn,lpbiOut,depth,dx,dy);
483 /***********************************************************************
484 * ICCompress [MSVFW32.@]
486 DWORD VFWAPIV
487 ICCompress(
488 HIC hic,DWORD dwFlags,LPBITMAPINFOHEADER lpbiOutput,LPVOID lpData,
489 LPBITMAPINFOHEADER lpbiInput,LPVOID lpBits,LPDWORD lpckid,
490 LPDWORD lpdwFlags,LONG lFrameNum,DWORD dwFrameSize,DWORD dwQuality,
491 LPBITMAPINFOHEADER lpbiPrev,LPVOID lpPrev)
493 ICCOMPRESS iccmp;
495 TRACE("(0x%08lx,%ld,%p,%p,%p,%p,...)\n",(DWORD)hic,dwFlags,lpbiOutput,lpData,lpbiInput,lpBits);
497 iccmp.dwFlags = dwFlags;
499 iccmp.lpbiOutput = lpbiOutput;
500 iccmp.lpOutput = lpData;
501 iccmp.lpbiInput = lpbiInput;
502 iccmp.lpInput = lpBits;
504 iccmp.lpckid = lpckid;
505 iccmp.lpdwFlags = lpdwFlags;
506 iccmp.lFrameNum = lFrameNum;
507 iccmp.dwFrameSize = dwFrameSize;
508 iccmp.dwQuality = dwQuality;
509 iccmp.lpbiPrev = lpbiPrev;
510 iccmp.lpPrev = lpPrev;
511 return ICSendMessage(hic,ICM_COMPRESS,(DWORD)&iccmp,sizeof(iccmp));
514 /***********************************************************************
515 * _ICCompress [MSVIDEO.224]
517 DWORD VFWAPIV ICCompress16(HIC16 hic, DWORD dwFlags, LPBITMAPINFOHEADER lpbiOutput, LPVOID lpData,
518 LPBITMAPINFOHEADER lpbiInput, LPVOID lpBits, LPDWORD lpckid,
519 LPDWORD lpdwFlags, LONG lFrameNum, DWORD dwFrameSize, DWORD dwQuality,
520 LPBITMAPINFOHEADER lpbiPrev, LPVOID lpPrev) {
522 DWORD ret;
523 ICCOMPRESS iccmp;
524 SEGPTR seg_iccmp;
526 TRACE("(0x%08lx,%ld,%p,%p,%p,%p,...)\n",(DWORD)hic,dwFlags,lpbiOutput,lpData,lpbiInput,lpBits);
528 iccmp.dwFlags = dwFlags;
530 iccmp.lpbiOutput = lpbiOutput;
531 iccmp.lpOutput = lpData;
532 iccmp.lpbiInput = lpbiInput;
533 iccmp.lpInput = lpBits;
535 iccmp.lpckid = lpckid;
536 iccmp.lpdwFlags = lpdwFlags;
537 iccmp.lFrameNum = lFrameNum;
538 iccmp.dwFrameSize = dwFrameSize;
539 iccmp.dwQuality = dwQuality;
540 iccmp.lpbiPrev = lpbiPrev;
541 iccmp.lpPrev = lpPrev;
542 seg_iccmp = MapLS( &iccmp );
543 ret = ICSendMessage16(hic,ICM_COMPRESS,seg_iccmp,sizeof(ICCOMPRESS));
544 UnMapLS( seg_iccmp );
545 return ret;
548 /***********************************************************************
549 * ICDecompress [MSVFW32.@]
551 DWORD VFWAPIV ICDecompress(HIC hic,DWORD dwFlags,LPBITMAPINFOHEADER lpbiFormat,
552 LPVOID lpData,LPBITMAPINFOHEADER lpbi,LPVOID lpBits)
554 ICDECOMPRESS icd;
555 DWORD ret;
557 TRACE("(0x%08lx,%ld,%p,%p,%p,%p)\n",(DWORD)hic,dwFlags,lpbiFormat,lpData,lpbi,lpBits);
559 TRACE("lpBits[0] == %ld\n",((LPDWORD)lpBits)[0]);
561 icd.dwFlags = dwFlags;
562 icd.lpbiInput = lpbiFormat;
563 icd.lpInput = lpData;
565 icd.lpbiOutput = lpbi;
566 icd.lpOutput = lpBits;
567 icd.ckid = 0;
568 ret = ICSendMessage(hic,ICM_DECOMPRESS,(DWORD)&icd,sizeof(ICDECOMPRESS));
570 TRACE("lpBits[0] == %ld\n",((LPDWORD)lpBits)[0]);
572 TRACE("-> %ld\n",ret);
574 return ret;
577 /***********************************************************************
578 * _ICDecompress [MSVIDEO.230]
580 DWORD VFWAPIV ICDecompress16(HIC16 hic, DWORD dwFlags, LPBITMAPINFOHEADER lpbiFormat,
581 LPVOID lpData, LPBITMAPINFOHEADER lpbi, LPVOID lpBits)
583 ICDECOMPRESS icd;
584 SEGPTR segptr;
585 DWORD ret;
587 TRACE("(0x%08lx,%ld,%p,%p,%p,%p)\n",(DWORD)hic,dwFlags,lpbiFormat,lpData,lpbi,lpBits);
589 icd.dwFlags = dwFlags;
590 icd.lpbiInput = lpbiFormat;
591 icd.lpInput = lpData;
592 icd.lpbiOutput = lpbi;
593 icd.lpOutput = lpBits;
594 icd.ckid = 0;
595 segptr = MapLS( &icd );
596 ret = ICSendMessage16(hic,ICM_DECOMPRESS,segptr,sizeof(ICDECOMPRESS));
597 UnMapLS( segptr );
598 return ret;
601 #define COPY(x,y) (x->y = x##16->y);
602 #define COPYPTR(x,y) (x->y = MapSL((SEGPTR)x##16->y));
604 LPVOID MSVIDEO_MapICDEX16To32(LPDWORD lParam) {
605 LPVOID ret;
607 ICDECOMPRESSEX *icdx = HeapAlloc(GetProcessHeap(),0,sizeof(ICDECOMPRESSEX));
608 ICDECOMPRESSEX16 *icdx16 = MapSL(*lParam);
609 ret = icdx16;
611 COPY(icdx,dwFlags);
612 COPYPTR(icdx,lpbiSrc);
613 COPYPTR(icdx,lpSrc);
614 COPYPTR(icdx,lpbiDst);
615 COPYPTR(icdx,lpDst);
616 COPY(icdx,xDst);
617 COPY(icdx,yDst);
618 COPY(icdx,dxDst);
619 COPY(icdx,dyDst);
620 COPY(icdx,xSrc);
621 COPY(icdx,ySrc);
622 COPY(icdx,dxSrc);
623 COPY(icdx,dySrc);
625 *lParam = (DWORD)(icdx);
626 return ret;
629 LPVOID MSVIDEO_MapMsg16To32(UINT msg, LPDWORD lParam1, LPDWORD lParam2) {
630 LPVOID ret = 0;
632 TRACE("Mapping %d\n",msg);
634 switch (msg) {
635 case DRV_LOAD:
636 case DRV_ENABLE:
637 case DRV_CLOSE:
638 case DRV_DISABLE:
639 case DRV_FREE:
640 case ICM_ABOUT:
641 case ICM_CONFIGURE:
642 case ICM_COMPRESS_END:
643 case ICM_DECOMPRESS_END:
644 case ICM_DECOMPRESSEX_END:
645 case ICM_SETQUALITY:
646 case ICM_DRAW_START_PLAY:
647 case ICM_DRAW_STOP_PLAY:
648 case ICM_DRAW_REALIZE:
649 case ICM_DRAW_RENDERBUFFER:
650 case ICM_DRAW_END:
651 break;
652 case DRV_OPEN:
653 case ICM_GETDEFAULTQUALITY:
654 case ICM_GETQUALITY:
655 case ICM_SETSTATE:
656 case ICM_DRAW_WINDOW:
657 case ICM_GETBUFFERSWANTED:
658 *lParam1 = (DWORD)MapSL(*lParam1);
659 break;
660 case ICM_GETINFO:
662 ICINFO *ici = HeapAlloc(GetProcessHeap(),0,sizeof(ICINFO));
663 ICINFO16 *ici16;
665 ici16 = MapSL(*lParam1);
666 ret = ici16;
668 ici->dwSize = sizeof(ICINFO);
669 COPY(ici,fccType);
670 COPY(ici,fccHandler);
671 COPY(ici,dwFlags);
672 COPY(ici,dwVersion);
673 COPY(ici,dwVersionICM);
674 MultiByteToWideChar( CP_ACP, 0, ici16->szName, -1, ici->szName, 16 );
675 MultiByteToWideChar( CP_ACP, 0, ici16->szDescription, -1, ici->szDescription, 128 );
676 MultiByteToWideChar( CP_ACP, 0, ici16->szDriver, -1, ici->szDriver, 128 );
677 *lParam1 = (DWORD)(ici);
678 *lParam2 = sizeof(ICINFO);
680 break;
681 case ICM_COMPRESS:
683 ICCOMPRESS *icc = HeapAlloc(GetProcessHeap(),0,sizeof(ICCOMPRESS));
684 ICCOMPRESS *icc16;
686 icc16 = MapSL(*lParam1);
687 ret = icc16;
689 COPY(icc,dwFlags);
690 COPYPTR(icc,lpbiOutput);
691 COPYPTR(icc,lpOutput);
692 COPYPTR(icc,lpbiInput);
693 COPYPTR(icc,lpInput);
694 COPYPTR(icc,lpckid);
695 COPYPTR(icc,lpdwFlags);
696 COPY(icc,lFrameNum);
697 COPY(icc,dwFrameSize);
698 COPY(icc,dwQuality);
699 COPYPTR(icc,lpbiPrev);
700 COPYPTR(icc,lpPrev);
702 *lParam1 = (DWORD)(icc);
703 *lParam2 = sizeof(ICCOMPRESS);
705 break;
706 case ICM_DECOMPRESS:
708 ICDECOMPRESS *icd = HeapAlloc(GetProcessHeap(),0,sizeof(ICDECOMPRESS));
709 ICDECOMPRESS *icd16; /* Same structure except for the pointers */
711 icd16 = MapSL(*lParam1);
712 ret = icd16;
714 COPY(icd,dwFlags);
715 COPYPTR(icd,lpbiInput);
716 COPYPTR(icd,lpInput);
717 COPYPTR(icd,lpbiOutput);
718 COPYPTR(icd,lpOutput);
719 COPY(icd,ckid);
721 *lParam1 = (DWORD)(icd);
722 *lParam2 = sizeof(ICDECOMPRESS);
724 break;
725 case ICM_COMPRESS_BEGIN:
726 case ICM_COMPRESS_GET_FORMAT:
727 case ICM_COMPRESS_GET_SIZE:
728 case ICM_COMPRESS_QUERY:
729 case ICM_DECOMPRESS_GET_FORMAT:
730 case ICM_DECOMPRESS_QUERY:
731 case ICM_DECOMPRESS_BEGIN:
732 case ICM_DECOMPRESS_SET_PALETTE:
733 case ICM_DECOMPRESS_GET_PALETTE:
734 *lParam1 = (DWORD)MapSL(*lParam1);
735 *lParam2 = (DWORD)MapSL(*lParam2);
736 break;
737 case ICM_DECOMPRESSEX_QUERY:
738 if ((*lParam2 != sizeof(ICDECOMPRESSEX16)) && (*lParam2 != 0))
739 WARN("*lParam2 has unknown value %p\n",(ICDECOMPRESSEX16*)*lParam2);
740 /* FIXME: *lParm2 is meant to be 0 or an ICDECOMPRESSEX16*, but is sizeof(ICDECOMRPESSEX16)
741 * This is because of ICMessage(). Special case it?
743 LPVOID* addr = HeapAlloc(GetProcessHeap(),0,2*sizeof(LPVOID));
744 addr[0] = MSVIDEO_MapICDEX16To32(lParam1);
745 if (*lParam2)
746 addr[1] = MSVIDEO_MapICDEX16To32(lParam2);
747 else
748 addr[1] = 0;
750 ret = addr;
752 break;*/
753 case ICM_DECOMPRESSEX_BEGIN:
754 case ICM_DECOMPRESSEX:
755 ret = MSVIDEO_MapICDEX16To32(lParam1);
756 *lParam2 = sizeof(ICDECOMPRESSEX);
757 break;
758 case ICM_DRAW_BEGIN:
760 ICDRAWBEGIN *icdb = HeapAlloc(GetProcessHeap(),0,sizeof(ICDRAWBEGIN));
761 ICDRAWBEGIN16 *icdb16 = MapSL(*lParam1);
762 ret = icdb16;
764 COPY(icdb,dwFlags);
765 COPY(icdb,hpal);
766 COPY(icdb,hwnd);
767 COPY(icdb,hdc);
768 COPY(icdb,xDst);
769 COPY(icdb,yDst);
770 COPY(icdb,dxDst);
771 COPY(icdb,dyDst);
772 COPYPTR(icdb,lpbi);
773 COPY(icdb,xSrc);
774 COPY(icdb,ySrc);
775 COPY(icdb,dxSrc);
776 COPY(icdb,dySrc);
777 COPY(icdb,dwRate);
778 COPY(icdb,dwScale);
780 *lParam1 = (DWORD)(icdb);
781 *lParam2 = sizeof(ICDRAWBEGIN);
783 break;
784 case ICM_DRAW_SUGGESTFORMAT:
786 ICDRAWSUGGEST *icds = HeapAlloc(GetProcessHeap(),0,sizeof(ICDRAWSUGGEST));
787 ICDRAWSUGGEST16 *icds16 = MapSL(*lParam1);
789 ret = icds16;
791 COPY(icds,dwFlags);
792 COPYPTR(icds,lpbiIn);
793 COPYPTR(icds,lpbiSuggest);
794 COPY(icds,dxSrc);
795 COPY(icds,dySrc);
796 COPY(icds,dxDst);
797 COPY(icds,dyDst);
798 COPY(icds,hicDecompressor);
800 *lParam1 = (DWORD)(icds);
801 *lParam2 = sizeof(ICDRAWSUGGEST);
803 break;
804 case ICM_DRAW:
806 ICDRAW *icd = HeapAlloc(GetProcessHeap(),0,sizeof(ICDRAW));
807 ICDRAW *icd16 = MapSL(*lParam1);
808 ret = icd16;
810 COPY(icd,dwFlags);
811 COPYPTR(icd,lpFormat);
812 COPYPTR(icd,lpData);
813 COPY(icd,cbData);
814 COPY(icd,lTime);
816 *lParam1 = (DWORD)(icd);
817 *lParam2 = sizeof(ICDRAW);
819 break;
820 case ICM_DRAW_START:
821 case ICM_DRAW_STOP:
822 break;
823 default:
824 FIXME("%d is not yet handled. Expect a crash.\n",msg);
826 return ret;
829 #undef COPY
830 #undef COPYPTR
832 void MSVIDEO_UnmapMsg16To32(UINT msg, LPVOID data16, LPDWORD lParam1, LPDWORD lParam2) {
833 TRACE("Unmapping %d\n",msg);
835 #define UNCOPY(x,y) (x##16->y = x->y);
837 switch (msg) {
838 case ICM_GETINFO:
840 ICINFO *ici = (ICINFO*)(*lParam1);
841 ICINFO16 *ici16 = (ICINFO16*)data16;
843 UNCOPY(ici,fccType);
844 UNCOPY(ici,fccHandler);
845 UNCOPY(ici,dwFlags);
846 UNCOPY(ici,dwVersion);
847 UNCOPY(ici,dwVersionICM);
848 WideCharToMultiByte( CP_ACP, 0, ici->szName, -1, ici16->szName,
849 sizeof(ici16->szName), NULL, NULL );
850 ici16->szName[sizeof(ici16->szName)-1] = 0;
851 WideCharToMultiByte( CP_ACP, 0, ici->szDescription, -1, ici16->szDescription,
852 sizeof(ici16->szDescription), NULL, NULL );
853 ici16->szDescription[sizeof(ici16->szDescription)-1] = 0;
854 /* This just gives garbage for some reason - BB
855 lstrcpynWtoA(ici16->szDriver,ici->szDriver,128);*/
857 HeapFree(GetProcessHeap(),0,ici);
859 break;
860 case ICM_DECOMPRESS_QUERY:
862 LPVOID* x = data16;
863 HeapFree(GetProcessHeap(),0,x[0]);
864 if (x[1])
865 HeapFree(GetProcessHeap(),0,x[1]);
867 break;*/
868 case ICM_COMPRESS:
869 case ICM_DECOMPRESS:
870 case ICM_DECOMPRESSEX_QUERY:
871 case ICM_DECOMPRESSEX_BEGIN:
872 case ICM_DECOMPRESSEX:
873 case ICM_DRAW_BEGIN:
874 case ICM_DRAW_SUGGESTFORMAT:
875 case ICM_DRAW:
876 HeapFree(GetProcessHeap(),0,data16);
877 break;
878 default:
879 ERR("Unmapping unmapped msg %d\n",msg);
881 #undef UNCOPY
884 LRESULT MSVIDEO_SendMessage(HIC hic,UINT msg,DWORD lParam1,DWORD lParam2, BOOL bFrom32) {
885 LRESULT ret;
886 WINE_HIC *whic = GlobalLock16(hic);
887 LPVOID data16 = 0;
888 BOOL bDrv32;
890 #define XX(x) case x: TRACE("(0x%08lx,"#x",0x%08lx,0x%08lx,%d)\n",(DWORD)hic,lParam1,lParam2,bFrom32?32:16);break;
892 switch (msg) {
893 /* DRV_* */
894 XX(DRV_LOAD);
895 XX(DRV_ENABLE);
896 XX(DRV_OPEN);
897 XX(DRV_CLOSE);
898 XX(DRV_DISABLE);
899 XX(DRV_FREE);
900 /* ICM_RESERVED+X */
901 XX(ICM_ABOUT);
902 XX(ICM_CONFIGURE);
903 XX(ICM_GET);
904 XX(ICM_GETINFO);
905 XX(ICM_GETDEFAULTQUALITY);
906 XX(ICM_GETQUALITY);
907 XX(ICM_GETSTATE);
908 XX(ICM_SETQUALITY);
909 XX(ICM_SET);
910 XX(ICM_SETSTATE);
911 /* ICM_USER+X */
912 XX(ICM_COMPRESS_FRAMES_INFO);
913 XX(ICM_COMPRESS_GET_FORMAT);
914 XX(ICM_COMPRESS_GET_SIZE);
915 XX(ICM_COMPRESS_QUERY);
916 XX(ICM_COMPRESS_BEGIN);
917 XX(ICM_COMPRESS);
918 XX(ICM_COMPRESS_END);
919 XX(ICM_DECOMPRESS_GET_FORMAT);
920 XX(ICM_DECOMPRESS_QUERY);
921 XX(ICM_DECOMPRESS_BEGIN);
922 XX(ICM_DECOMPRESS);
923 XX(ICM_DECOMPRESS_END);
924 XX(ICM_DECOMPRESS_SET_PALETTE);
925 XX(ICM_DECOMPRESS_GET_PALETTE);
926 XX(ICM_DRAW_QUERY);
927 XX(ICM_DRAW_BEGIN);
928 XX(ICM_DRAW_GET_PALETTE);
929 XX(ICM_DRAW_START);
930 XX(ICM_DRAW_STOP);
931 XX(ICM_DRAW_END);
932 XX(ICM_DRAW_GETTIME);
933 XX(ICM_DRAW);
934 XX(ICM_DRAW_WINDOW);
935 XX(ICM_DRAW_SETTIME);
936 XX(ICM_DRAW_REALIZE);
937 XX(ICM_DRAW_FLUSH);
938 XX(ICM_DRAW_RENDERBUFFER);
939 XX(ICM_DRAW_START_PLAY);
940 XX(ICM_DRAW_STOP_PLAY);
941 XX(ICM_DRAW_SUGGESTFORMAT);
942 XX(ICM_DRAW_CHANGEPALETTE);
943 XX(ICM_GETBUFFERSWANTED);
944 XX(ICM_GETDEFAULTKEYFRAMERATE);
945 XX(ICM_DECOMPRESSEX_BEGIN);
946 XX(ICM_DECOMPRESSEX_QUERY);
947 XX(ICM_DECOMPRESSEX);
948 XX(ICM_DECOMPRESSEX_END);
949 XX(ICM_SET_STATUS_PROC);
950 default:
951 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx,%i) unknown message\n",(DWORD)hic,(DWORD)msg,lParam1,lParam2,bFrom32?32:16);
954 #undef XX
956 if (!whic) return ICERR_BADHANDLE;
958 if (whic->driverproc) { /* IC is a function */
959 bDrv32 = whic->private;
960 } else {
961 bDrv32 = ((GetDriverFlags(whic->hdrv) & (WINE_GDF_EXIST|WINE_GDF_16BIT)) == WINE_GDF_EXIST);
964 if (!bFrom32) {
965 if (bDrv32)
966 data16 = MSVIDEO_MapMsg16To32(msg,&lParam1,&lParam2);
967 } else {
968 if (!bDrv32) {
969 ERR("Can't do 32->16 mappings\n");
970 ret = -1;
971 goto out;
975 if (whic->driverproc) {
976 if (bDrv32) {
977 ret = whic->driverproc(whic->hdrv,hic,msg,lParam1,lParam2);
978 } else {
979 ret = MSVIDEO_CallTo16_long_lwwll((FARPROC16)whic->driverproc,whic->hdrv,hic,msg,lParam1,lParam2);
981 } else {
982 ret = SendDriverMessage(whic->hdrv,msg,lParam1,lParam2);
985 if (data16)
986 MSVIDEO_UnmapMsg16To32(msg,data16,&lParam1,&lParam2);
988 out:
989 GlobalUnlock16(hic);
991 TRACE(" -> 0x%08lx\n",ret);
992 return ret;
995 /***********************************************************************
996 * ICSendMessage [MSVFW32.@]
998 LRESULT VFWAPI ICSendMessage(HIC hic, UINT msg, DWORD lParam1, DWORD lParam2) {
999 return MSVIDEO_SendMessage(hic,msg,lParam1,lParam2,TRUE);
1002 /***********************************************************************
1003 * ICSendMessage [MSVIDEO.205]
1005 LRESULT VFWAPI ICSendMessage16(HIC16 hic, UINT16 msg, DWORD lParam1, DWORD lParam2) {
1006 return MSVIDEO_SendMessage(hic,msg,lParam1,lParam2,FALSE);
1009 /***********************************************************************
1010 * _ICMessage [MSVIDEO.207]
1012 LRESULT VFWAPIV ICMessage16(void) {
1013 HIC16 hic;
1014 UINT16 msg;
1015 UINT16 cb;
1016 LPWORD lpData;
1017 SEGPTR segData;
1018 LRESULT ret;
1019 UINT16 i;
1021 VA_LIST16 valist;
1023 VA_START16(valist);
1024 hic = VA_ARG16(valist, HIC16);
1025 msg = VA_ARG16(valist, UINT16);
1026 cb = VA_ARG16(valist, UINT16);
1028 lpData = HeapAlloc( GetProcessHeap(), 0, cb );
1030 TRACE("0x%08lx, %u, %u, ...)\n",(DWORD)hic,msg,cb);
1032 for(i=0;i<cb/sizeof(WORD);i++) {
1033 lpData[i] = VA_ARG16(valist, WORD);
1036 VA_END16(valist);
1037 segData = MapLS( lpData );
1038 ret = ICSendMessage16(hic, msg, segData, (DWORD)cb);
1039 UnMapLS( segData );
1040 HeapFree( GetProcessHeap(), 0, lpData );
1041 return ret;
1044 /***********************************************************************
1045 * ICDrawBegin [MSVFW32.@]
1047 DWORD VFWAPIV ICDrawBegin(
1048 HIC hic, /* [in] */
1049 DWORD dwFlags, /* [in] flags */
1050 HPALETTE hpal, /* [in] palette to draw with */
1051 HWND hwnd, /* [in] window to draw to */
1052 HDC hdc, /* [in] HDC to draw to */
1053 INT xDst, /* [in] destination rectangle */
1054 INT yDst, /* [in] */
1055 INT dxDst, /* [in] */
1056 INT dyDst, /* [in] */
1057 LPBITMAPINFOHEADER lpbi, /* [in] format of frame to draw */
1058 INT xSrc, /* [in] source rectangle */
1059 INT ySrc, /* [in] */
1060 INT dxSrc, /* [in] */
1061 INT dySrc, /* [in] */
1062 DWORD dwRate, /* [in] frames/second = (dwRate/dwScale) */
1063 DWORD dwScale) /* [in] */
1066 ICDRAWBEGIN icdb;
1068 TRACE("(0x%08lx,%ld,0x%08lx,0x%08lx,0x%08lx,%u,%u,%u,%u,%p,%u,%u,%u,%u,%ld,%ld)\n",
1069 (DWORD)hic, dwFlags, (DWORD)hpal, (DWORD)hwnd, (DWORD)hdc, xDst, yDst, dxDst, dyDst,
1070 lpbi, xSrc, ySrc, dxSrc, dySrc, dwRate, dwScale);
1072 icdb.dwFlags = dwFlags;
1073 icdb.hpal = hpal;
1074 icdb.hwnd = hwnd;
1075 icdb.hdc = hdc;
1076 icdb.xDst = xDst;
1077 icdb.yDst = yDst;
1078 icdb.dxDst = dxDst;
1079 icdb.dyDst = dyDst;
1080 icdb.lpbi = lpbi;
1081 icdb.xSrc = xSrc;
1082 icdb.ySrc = ySrc;
1083 icdb.dxSrc = dxSrc;
1084 icdb.dySrc = dySrc;
1085 icdb.dwRate = dwRate;
1086 icdb.dwScale = dwScale;
1087 return ICSendMessage(hic,ICM_DRAW_BEGIN,(DWORD)&icdb,sizeof(icdb));
1090 /***********************************************************************
1091 * _ICDrawBegin [MSVIDEO.232]
1093 DWORD VFWAPIV ICDrawBegin16(
1094 HIC16 hic, /* [in] */
1095 DWORD dwFlags, /* [in] flags */
1096 HPALETTE16 hpal, /* [in] palette to draw with */
1097 HWND16 hwnd, /* [in] window to draw to */
1098 HDC16 hdc, /* [in] HDC to draw to */
1099 INT16 xDst, /* [in] destination rectangle */
1100 INT16 yDst, /* [in] */
1101 INT16 dxDst, /* [in] */
1102 INT16 dyDst, /* [in] */
1103 LPBITMAPINFOHEADER lpbi, /* [in] format of frame to draw NOTE: SEGPTR */
1104 INT16 xSrc, /* [in] source rectangle */
1105 INT16 ySrc, /* [in] */
1106 INT16 dxSrc, /* [in] */
1107 INT16 dySrc, /* [in] */
1108 DWORD dwRate, /* [in] frames/second = (dwRate/dwScale) */
1109 DWORD dwScale) /* [in] */
1111 DWORD ret;
1112 ICDRAWBEGIN16 icdb;
1113 SEGPTR seg_icdb;
1115 TRACE("(0x%08lx,%ld,0x%08lx,0x%08lx,0x%08lx,%u,%u,%u,%u,%p,%u,%u,%u,%u,%ld,%ld)\n",
1116 (DWORD)hic, dwFlags, (DWORD)hpal, (DWORD)hwnd, (DWORD)hdc, xDst, yDst, dxDst, dyDst,
1117 lpbi, xSrc, ySrc, dxSrc, dySrc, dwRate, dwScale);
1119 icdb.dwFlags = dwFlags;
1120 icdb.hpal = hpal;
1121 icdb.hwnd = hwnd;
1122 icdb.hdc = hdc;
1123 icdb.xDst = xDst;
1124 icdb.yDst = yDst;
1125 icdb.dxDst = dxDst;
1126 icdb.dyDst = dyDst;
1127 icdb.lpbi = lpbi; /* Keep this as SEGPTR for the mapping code to deal with */
1128 icdb.xSrc = xSrc;
1129 icdb.ySrc = ySrc;
1130 icdb.dxSrc = dxSrc;
1131 icdb.dySrc = dySrc;
1132 icdb.dwRate = dwRate;
1133 icdb.dwScale = dwScale;
1134 seg_icdb = MapLS( &icdb );
1135 ret = (DWORD)ICSendMessage16(hic,ICM_DRAW_BEGIN,seg_icdb,sizeof(ICDRAWBEGIN16));
1136 UnMapLS( seg_icdb );
1137 return ret;
1140 /***********************************************************************
1141 * ICDraw [MSVFW32.@]
1143 DWORD VFWAPIV ICDraw(HIC hic, DWORD dwFlags, LPVOID lpFormat, LPVOID lpData, DWORD cbData, LONG lTime) {
1144 ICDRAW icd;
1146 TRACE("(0x%09lx,%ld,%p,%p,%ld,%ld)\n",(DWORD)hic,dwFlags,lpFormat,lpData,cbData,lTime);
1148 icd.dwFlags = dwFlags;
1149 icd.lpFormat = lpFormat;
1150 icd.lpData = lpData;
1151 icd.cbData = cbData;
1152 icd.lTime = lTime;
1154 return ICSendMessage(hic,ICM_DRAW,(DWORD)&icd,sizeof(icd));
1157 /***********************************************************************
1158 * _ICDraw [MSVIDEO.234]
1160 DWORD VFWAPIV ICDraw16(
1161 HIC16 hic,
1162 DWORD dwFlags,
1163 LPVOID lpFormat, /* [???] NOTE: SEGPTR */
1164 LPVOID lpData, /* [???] NOTE: SEGPTR */
1165 DWORD cbData,
1166 LONG lTime)
1168 DWORD ret;
1169 ICDRAW icd;
1170 SEGPTR seg_icd;
1172 TRACE("(0x%08lx,0x%08lx,%p,%p,%ld,%ld)\n",(DWORD)hic,dwFlags,lpFormat,lpData,cbData,lTime);
1173 icd.dwFlags = dwFlags;
1174 icd.lpFormat = lpFormat;
1175 icd.lpData = lpData;
1176 icd.cbData = cbData;
1177 icd.lTime = lTime;
1178 seg_icd = MapLS( &icd );
1179 ret = ICSendMessage16(hic,ICM_DRAW,seg_icd,sizeof(ICDRAW));
1180 UnMapLS( seg_icd );
1181 return ret;
1184 /***********************************************************************
1185 * ICClose [MSVFW32.@]
1187 LRESULT WINAPI ICClose(HIC hic) {
1188 WINE_HIC *whic = GlobalLock16(hic);
1189 TRACE("(0x%08lx)\n",(DWORD)hic);
1190 if (whic->driverproc) {
1191 ICSendMessage(hic,DRV_CLOSE,0,0);
1192 ICSendMessage(hic,DRV_DISABLE,0,0);
1193 ICSendMessage(hic,DRV_FREE,0,0);
1194 } else {
1195 CloseDriver(whic->hdrv,0,0);
1198 GlobalUnlock16(hic);
1199 GlobalFree16(hic);
1200 return 0;
1203 /***********************************************************************
1204 * ICClose [MSVIDEO.204]
1206 LRESULT WINAPI ICClose16(HIC16 hic) {
1207 return ICClose(hic);
1212 /***********************************************************************
1213 * ICImageCompress [MSVFW32.@]
1215 HANDLE VFWAPI ICImageCompress(
1216 HIC hic, UINT uiFlags,
1217 LPBITMAPINFO lpbiIn, LPVOID lpBits,
1218 LPBITMAPINFO lpbiOut, LONG lQuality,
1219 LONG* plSize)
1221 FIXME("(%08x,%08x,%p,%p,%p,%ld,%p)\n",
1222 hic, uiFlags, lpbiIn, lpBits, lpbiOut, lQuality, plSize);
1224 return (HANDLE)NULL;
1227 /***********************************************************************
1228 * ICImageDecompress [MSVFW32.@]
1231 HANDLE VFWAPI ICImageDecompress(
1232 HIC hic, UINT uiFlags, LPBITMAPINFO lpbiIn,
1233 LPVOID lpBits, LPBITMAPINFO lpbiOut)
1235 HGLOBAL hMem = (HGLOBAL)NULL;
1236 BYTE* pMem = NULL;
1237 BOOL bReleaseIC = FALSE;
1238 BYTE* pHdr = NULL;
1239 LONG cbHdr = 0;
1240 BOOL bSucceeded = FALSE;
1241 BOOL bInDecompress = FALSE;
1242 DWORD biSizeImage;
1244 TRACE("(%08x,%08x,%p,%p,%p)\n",
1245 hic, uiFlags, lpbiIn, lpBits, lpbiOut);
1247 if ( hic == (HIC)NULL )
1249 hic = ICDecompressOpen( mmioFOURCC('V','I','D','C'), 0, &lpbiIn->bmiHeader, (lpbiOut != NULL) ? &lpbiOut->bmiHeader : NULL );
1250 if ( hic == (HIC)NULL )
1252 WARN("no handler\n" );
1253 goto err;
1255 bReleaseIC = TRUE;
1257 if ( uiFlags != 0 )
1259 FIXME( "unknown flag %08x\n", uiFlags );
1260 goto err;
1262 if ( lpbiIn == NULL || lpBits == NULL )
1264 WARN("invalid argument\n");
1265 goto err;
1268 if ( lpbiOut != NULL )
1270 if ( lpbiOut->bmiHeader.biSize != sizeof(BITMAPINFOHEADER) )
1271 goto err;
1272 cbHdr = sizeof(BITMAPINFOHEADER);
1273 if ( lpbiOut->bmiHeader.biCompression == 3 )
1274 cbHdr += sizeof(DWORD)*3;
1275 else
1276 if ( lpbiOut->bmiHeader.biBitCount <= 8 )
1278 if ( lpbiOut->bmiHeader.biClrUsed == 0 )
1279 cbHdr += sizeof(RGBQUAD) * (1<<lpbiOut->bmiHeader.biBitCount);
1280 else
1281 cbHdr += sizeof(RGBQUAD) * lpbiOut->bmiHeader.biClrUsed;
1284 else
1286 TRACE( "get format\n" );
1288 cbHdr = ICDecompressGetFormatSize(hic,lpbiIn);
1289 if ( cbHdr < sizeof(BITMAPINFOHEADER) )
1290 goto err;
1291 pHdr = (BYTE*)HeapAlloc(GetProcessHeap(),0,cbHdr+sizeof(RGBQUAD)*256);
1292 if ( pHdr == NULL )
1293 goto err;
1294 ZeroMemory( pHdr, cbHdr+sizeof(RGBQUAD)*256 );
1295 if ( ICDecompressGetFormat( hic, lpbiIn, (BITMAPINFO*)pHdr ) != ICERR_OK )
1296 goto err;
1297 lpbiOut = (BITMAPINFO*)pHdr;
1298 if ( lpbiOut->bmiHeader.biBitCount <= 8 &&
1299 ICDecompressGetPalette( hic, lpbiIn, lpbiOut ) != ICERR_OK &&
1300 lpbiIn->bmiHeader.biBitCount == lpbiOut->bmiHeader.biBitCount )
1302 if ( lpbiIn->bmiHeader.biClrUsed == 0 )
1303 memcpy( lpbiOut->bmiColors, lpbiIn->bmiColors, sizeof(RGBQUAD)*(1<<lpbiOut->bmiHeader.biBitCount) );
1304 else
1305 memcpy( lpbiOut->bmiColors, lpbiIn->bmiColors, sizeof(RGBQUAD)*lpbiIn->bmiHeader.biClrUsed );
1307 if ( lpbiOut->bmiHeader.biBitCount <= 8 &&
1308 lpbiOut->bmiHeader.biClrUsed == 0 )
1309 lpbiOut->bmiHeader.biClrUsed = 1<<lpbiOut->bmiHeader.biBitCount;
1311 lpbiOut->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1312 cbHdr = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*lpbiOut->bmiHeader.biClrUsed;
1315 biSizeImage = lpbiOut->bmiHeader.biSizeImage;
1316 if ( biSizeImage == 0 )
1317 biSizeImage = ((((lpbiOut->bmiHeader.biWidth * lpbiOut->bmiHeader.biBitCount + 7) >> 3) + 3) & (~3)) * abs(lpbiOut->bmiHeader.biHeight);
1319 TRACE( "call ICDecompressBegin\n" );
1321 if ( ICDecompressBegin( hic, lpbiIn, lpbiOut ) != ICERR_OK )
1322 goto err;
1323 bInDecompress = TRUE;
1325 TRACE( "cbHdr %ld, biSizeImage %ld\n", cbHdr, biSizeImage );
1327 hMem = GlobalAlloc( GMEM_MOVEABLE|GMEM_ZEROINIT, cbHdr + biSizeImage );
1328 if ( hMem == (HGLOBAL)NULL )
1330 WARN( "out of memory\n" );
1331 goto err;
1333 pMem = (BYTE*)GlobalLock( hMem );
1334 if ( pMem == NULL )
1335 goto err;
1336 memcpy( pMem, lpbiOut, cbHdr );
1338 TRACE( "call ICDecompress\n" );
1339 if ( ICDecompress( hic, 0, &lpbiIn->bmiHeader, lpBits, &lpbiOut->bmiHeader, pMem+cbHdr ) != ICERR_OK )
1340 goto err;
1342 bSucceeded = TRUE;
1343 err:
1344 if ( bInDecompress )
1345 ICDecompressEnd( hic );
1346 if ( bReleaseIC )
1347 ICClose(hic);
1348 if ( pHdr != NULL )
1349 HeapFree(GetProcessHeap(),0,pHdr);
1350 if ( pMem != NULL )
1351 GlobalUnlock( hMem );
1352 if ( !bSucceeded && hMem != (HGLOBAL)NULL )
1354 GlobalFree(hMem); hMem = (HGLOBAL)NULL;
1357 return (HANDLE)hMem;