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.
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
69 char *s,buf[2000],fn[260];
73 TRACE("(%d,%p,%d,%p,%d)\n",nr,buf1,buf1len,buf2,buf2len);
74 if (GetPrivateProfileStringA("drivers32",NULL,NULL,buf,sizeof(buf),"system.ini")) {
77 if (!strncasecmp(s,"vid",3)) {
82 s=s+strlen(s)+1; /* either next char or \0 */
85 return 20; /* hmm, out of entries even if we don't have any */
87 FIXME("No more VID* entries found\n");
90 GetPrivateProfileStringA("drivers32",s,NULL,fn,sizeof(fn),"system.ini");
91 infosize = GetFileVersionInfoSizeA(fn,&verhandle);
93 TRACE("%s has no fileversioninfo.\n",fn);
96 infobuf = HeapAlloc(GetProcessHeap(),0,infosize);
97 if (GetFileVersionInfoA(fn,verhandle,infosize,infobuf)) {
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);
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",
119 TRACE("VQA returned %s\n",(LPCSTR)subblock);
120 strncpy(buf1,subblock,buf1len);
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);
129 /* system.ini: [drivers] */
131 /***********************************************************************
133 * Get information about an installable compressor. Return TRUE if there
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")) {
152 if (!strncasecmp(type,s,4)) {
154 lpicinfo->fccHandler = mmioStringToFOURCCA(s+5,0);
158 s=s+strlen(s)+1; /* either next char or \0 */
164 /***********************************************************************
165 * ICInfo [MSVIDEO.200]
167 BOOL16 VFWAPI ICInfo16(
168 DWORD fccType, /* [in] */
169 DWORD fccHandler, /* [in] */
170 ICINFO16 *lpicinfo) /* [in/out] NOTE: SEGPTR */
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);
187 /***********************************************************************
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];
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);
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);
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);
226 whic->driverproc= NULL;
229 TRACE("=> 0x%08lx\n",(DWORD)hic);
233 HIC MSVIDEO_OpenFunc(DWORD fccType, DWORD fccHandler, UINT wMode, FARPROC lpfnHandler, BOOL bFrom32) {
234 char type[5],handler[5],codecname[20];
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));
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);
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);
280 TRACE("=> 0x%08lx\n",(DWORD)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) {
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);
318 /***********************************************************************
319 * ICGetInfo [MSVIDEO.212]
321 LRESULT VFWAPI ICGetInfo16(HIC16 hic, ICINFO16 *picinfo,DWORD cb) {
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);
330 /***********************************************************************
331 * ICLocate [MSVFW32.@]
334 DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn,
335 LPBITMAPINFOHEADER lpbiOut, WORD wMode)
337 char type[5],handler[5];
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);
348 case ICMODE_FASTCOMPRESS:
349 case ICMODE_COMPRESS:
350 querymsg = ICM_COMPRESS_QUERY;
352 case ICMODE_FASTDECOMPRESS:
353 case ICMODE_DECOMPRESS:
354 querymsg = ICM_DECOMPRESS_QUERY;
357 querymsg = ICM_DRAW_QUERY;
360 WARN("Unknown mode (%d)\n",wMode);
364 /* Easy case: handler/type match, we just fire a query and return */
365 hic = ICOpen(fccType,fccHandler,wMode);
367 if (!ICSendMessage(hic,querymsg,(DWORD)lpbiIn,(DWORD)lpbiOut))
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")) {
382 if (!strncasecmp(type,s,5)) {
384 while (*s2 != '\0' && *s2 != '.') s2++;
388 h = ICOpen(fccType,*(DWORD*)s2,wMode);
390 if (!ICSendMessage(h,querymsg,(DWORD)lpbiIn,(DWORD)lpbiOut))
399 HeapFree(GetProcessHeap(),0,pszBuffer);
401 if (fccType==streamtypeVIDEO) {
402 hic = ICLocate(ICTYPE_VIDEO,fccHandler,lpbiIn,lpbiOut,wMode);
407 type[4] = handler[4] = '\0';
408 WARN("(%.4s,%.4s,%p,%p,0x%04x) not found!\n",type,handler,lpbiIn,lpbiOut,wMode);
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)
429 FIXME("(0x%08lx,%p,%p,%d,%d,%d),stub!\n",(DWORD)hic,lpbiIn,lpbiOut,depth,dx,dy);
431 tmphic=ICLocate(ICTYPE_VIDEO,0,lpbiIn,NULL,ICMODE_DECOMPRESS);
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",
451 lpbiOut->biSize = sizeof(*lpbiOut);
457 depth = GetDeviceCaps(hdc,BITSPIXEL)*GetDeviceCaps(hdc,PLANES);
459 if (depth==15) depth = 16;
460 if (depth<8) depth = 8;
462 if (lpbiIn->biBitCount == 8)
465 TRACE("=> 0x%08lx\n",(DWORD)tmphic);
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.@]
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)
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) {
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 );
548 /***********************************************************************
549 * ICDecompress [MSVFW32.@]
551 DWORD VFWAPIV ICDecompress(HIC hic,DWORD dwFlags,LPBITMAPINFOHEADER lpbiFormat,
552 LPVOID lpData,LPBITMAPINFOHEADER lpbi,LPVOID lpBits)
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;
568 ret = ICSendMessage(hic,ICM_DECOMPRESS,(DWORD)&icd,sizeof(ICDECOMPRESS));
570 TRACE("lpBits[0] == %ld\n",((LPDWORD)lpBits)[0]);
572 TRACE("-> %ld\n",ret);
577 /***********************************************************************
578 * _ICDecompress [MSVIDEO.230]
580 DWORD VFWAPIV ICDecompress16(HIC16 hic, DWORD dwFlags, LPBITMAPINFOHEADER lpbiFormat,
581 LPVOID lpData, LPBITMAPINFOHEADER lpbi, LPVOID lpBits)
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;
595 segptr = MapLS( &icd );
596 ret = ICSendMessage16(hic,ICM_DECOMPRESS,segptr,sizeof(ICDECOMPRESS));
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) {
607 ICDECOMPRESSEX *icdx = HeapAlloc(GetProcessHeap(),0,sizeof(ICDECOMPRESSEX));
608 ICDECOMPRESSEX16 *icdx16 = MapSL(*lParam);
612 COPYPTR(icdx,lpbiSrc);
614 COPYPTR(icdx,lpbiDst);
625 *lParam = (DWORD)(icdx);
629 LPVOID MSVIDEO_MapMsg16To32(UINT msg, LPDWORD lParam1, LPDWORD lParam2) {
632 TRACE("Mapping %d\n",msg);
642 case ICM_COMPRESS_END:
643 case ICM_DECOMPRESS_END:
644 case ICM_DECOMPRESSEX_END:
646 case ICM_DRAW_START_PLAY:
647 case ICM_DRAW_STOP_PLAY:
648 case ICM_DRAW_REALIZE:
649 case ICM_DRAW_RENDERBUFFER:
653 case ICM_GETDEFAULTQUALITY:
656 case ICM_DRAW_WINDOW:
657 case ICM_GETBUFFERSWANTED:
658 *lParam1 = (DWORD)MapSL(*lParam1);
662 ICINFO *ici = HeapAlloc(GetProcessHeap(),0,sizeof(ICINFO));
665 ici16 = MapSL(*lParam1);
668 ici->dwSize = sizeof(ICINFO);
670 COPY(ici,fccHandler);
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);
683 ICCOMPRESS *icc = HeapAlloc(GetProcessHeap(),0,sizeof(ICCOMPRESS));
686 icc16 = MapSL(*lParam1);
690 COPYPTR(icc,lpbiOutput);
691 COPYPTR(icc,lpOutput);
692 COPYPTR(icc,lpbiInput);
693 COPYPTR(icc,lpInput);
695 COPYPTR(icc,lpdwFlags);
697 COPY(icc,dwFrameSize);
699 COPYPTR(icc,lpbiPrev);
702 *lParam1 = (DWORD)(icc);
703 *lParam2 = sizeof(ICCOMPRESS);
708 ICDECOMPRESS *icd = HeapAlloc(GetProcessHeap(),0,sizeof(ICDECOMPRESS));
709 ICDECOMPRESS *icd16; /* Same structure except for the pointers */
711 icd16 = MapSL(*lParam1);
715 COPYPTR(icd,lpbiInput);
716 COPYPTR(icd,lpInput);
717 COPYPTR(icd,lpbiOutput);
718 COPYPTR(icd,lpOutput);
721 *lParam1 = (DWORD)(icd);
722 *lParam2 = sizeof(ICDECOMPRESS);
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);
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);
746 addr[1] = MSVIDEO_MapICDEX16To32(lParam2);
753 case ICM_DECOMPRESSEX_BEGIN:
754 case ICM_DECOMPRESSEX:
755 ret = MSVIDEO_MapICDEX16To32(lParam1);
756 *lParam2 = sizeof(ICDECOMPRESSEX);
760 ICDRAWBEGIN *icdb = HeapAlloc(GetProcessHeap(),0,sizeof(ICDRAWBEGIN));
761 ICDRAWBEGIN16 *icdb16 = MapSL(*lParam1);
780 *lParam1 = (DWORD)(icdb);
781 *lParam2 = sizeof(ICDRAWBEGIN);
784 case ICM_DRAW_SUGGESTFORMAT:
786 ICDRAWSUGGEST *icds = HeapAlloc(GetProcessHeap(),0,sizeof(ICDRAWSUGGEST));
787 ICDRAWSUGGEST16 *icds16 = MapSL(*lParam1);
792 COPYPTR(icds,lpbiIn);
793 COPYPTR(icds,lpbiSuggest);
798 COPY(icds,hicDecompressor);
800 *lParam1 = (DWORD)(icds);
801 *lParam2 = sizeof(ICDRAWSUGGEST);
806 ICDRAW *icd = HeapAlloc(GetProcessHeap(),0,sizeof(ICDRAW));
807 ICDRAW *icd16 = MapSL(*lParam1);
811 COPYPTR(icd,lpFormat);
816 *lParam1 = (DWORD)(icd);
817 *lParam2 = sizeof(ICDRAW);
824 FIXME("%d is not yet handled. Expect a crash.\n",msg);
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);
840 ICINFO *ici = (ICINFO*)(*lParam1);
841 ICINFO16 *ici16 = (ICINFO16*)data16;
844 UNCOPY(ici,fccHandler);
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);
860 case ICM_DECOMPRESS_QUERY:
863 HeapFree(GetProcessHeap(),0,x[0]);
865 HeapFree(GetProcessHeap(),0,x[1]);
870 case ICM_DECOMPRESSEX_QUERY:
871 case ICM_DECOMPRESSEX_BEGIN:
872 case ICM_DECOMPRESSEX:
874 case ICM_DRAW_SUGGESTFORMAT:
876 HeapFree(GetProcessHeap(),0,data16);
879 ERR("Unmapping unmapped msg %d\n",msg);
884 LRESULT MSVIDEO_SendMessage(HIC hic,UINT msg,DWORD lParam1,DWORD lParam2, BOOL bFrom32) {
886 WINE_HIC *whic = GlobalLock16(hic);
890 #define XX(x) case x: TRACE("(0x%08lx,"#x",0x%08lx,0x%08lx,%d)\n",(DWORD)hic,lParam1,lParam2,bFrom32?32:16);break;
905 XX(ICM_GETDEFAULTQUALITY);
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);
918 XX(ICM_COMPRESS_END);
919 XX(ICM_DECOMPRESS_GET_FORMAT);
920 XX(ICM_DECOMPRESS_QUERY);
921 XX(ICM_DECOMPRESS_BEGIN);
923 XX(ICM_DECOMPRESS_END);
924 XX(ICM_DECOMPRESS_SET_PALETTE);
925 XX(ICM_DECOMPRESS_GET_PALETTE);
928 XX(ICM_DRAW_GET_PALETTE);
932 XX(ICM_DRAW_GETTIME);
935 XX(ICM_DRAW_SETTIME);
936 XX(ICM_DRAW_REALIZE);
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);
951 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx,%i) unknown message\n",(DWORD)hic,(DWORD)msg,lParam1,lParam2,bFrom32?32:16);
956 if (!whic) return ICERR_BADHANDLE;
958 if (whic->driverproc) { /* IC is a function */
959 bDrv32 = whic->private;
961 bDrv32 = ((GetDriverFlags(whic->hdrv) & (WINE_GDF_EXIST|WINE_GDF_16BIT)) == WINE_GDF_EXIST);
966 data16 = MSVIDEO_MapMsg16To32(msg,&lParam1,&lParam2);
969 ERR("Can't do 32->16 mappings\n");
975 if (whic->driverproc) {
977 ret = whic->driverproc(whic->hdrv,hic,msg,lParam1,lParam2);
979 ret = MSVIDEO_CallTo16_long_lwwll((FARPROC16)whic->driverproc,whic->hdrv,hic,msg,lParam1,lParam2);
982 ret = SendDriverMessage(whic->hdrv,msg,lParam1,lParam2);
986 MSVIDEO_UnmapMsg16To32(msg,data16,&lParam1,&lParam2);
991 TRACE(" -> 0x%08lx\n",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) {
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);
1037 segData = MapLS( lpData );
1038 ret = ICSendMessage16(hic, msg, segData, (DWORD)cb);
1040 HeapFree( GetProcessHeap(), 0, lpData );
1044 /***********************************************************************
1045 * ICDrawBegin [MSVFW32.@]
1047 DWORD VFWAPIV ICDrawBegin(
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] */
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;
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] */
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;
1127 icdb.lpbi = lpbi; /* Keep this as SEGPTR for the mapping code to deal with */
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 );
1140 /***********************************************************************
1141 * ICDraw [MSVFW32.@]
1143 DWORD VFWAPIV ICDraw(HIC hic, DWORD dwFlags, LPVOID lpFormat, LPVOID lpData, DWORD cbData, LONG lTime) {
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;
1154 return ICSendMessage(hic,ICM_DRAW,(DWORD)&icd,sizeof(icd));
1157 /***********************************************************************
1158 * _ICDraw [MSVIDEO.234]
1160 DWORD VFWAPIV ICDraw16(
1163 LPVOID lpFormat, /* [???] NOTE: SEGPTR */
1164 LPVOID lpData, /* [???] NOTE: SEGPTR */
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;
1178 seg_icd = MapLS( &icd );
1179 ret = ICSendMessage16(hic,ICM_DRAW,seg_icd,sizeof(ICDRAW));
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);
1195 CloseDriver(whic->hdrv,0,0);
1198 GlobalUnlock16(hic);
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,
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;
1237 BOOL bReleaseIC = FALSE;
1240 BOOL bSucceeded = FALSE;
1241 BOOL bInDecompress = FALSE;
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" );
1259 FIXME( "unknown flag %08x\n", uiFlags );
1262 if ( lpbiIn == NULL || lpBits == NULL )
1264 WARN("invalid argument\n");
1268 if ( lpbiOut != NULL )
1270 if ( lpbiOut->bmiHeader.biSize != sizeof(BITMAPINFOHEADER) )
1272 cbHdr = sizeof(BITMAPINFOHEADER);
1273 if ( lpbiOut->bmiHeader.biCompression == 3 )
1274 cbHdr += sizeof(DWORD)*3;
1276 if ( lpbiOut->bmiHeader.biBitCount <= 8 )
1278 if ( lpbiOut->bmiHeader.biClrUsed == 0 )
1279 cbHdr += sizeof(RGBQUAD) * (1<<lpbiOut->bmiHeader.biBitCount);
1281 cbHdr += sizeof(RGBQUAD) * lpbiOut->bmiHeader.biClrUsed;
1286 TRACE( "get format\n" );
1288 cbHdr = ICDecompressGetFormatSize(hic,lpbiIn);
1289 if ( cbHdr < sizeof(BITMAPINFOHEADER) )
1291 pHdr = (BYTE*)HeapAlloc(GetProcessHeap(),0,cbHdr+sizeof(RGBQUAD)*256);
1294 ZeroMemory( pHdr, cbHdr+sizeof(RGBQUAD)*256 );
1295 if ( ICDecompressGetFormat( hic, lpbiIn, (BITMAPINFO*)pHdr ) != ICERR_OK )
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) );
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 )
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" );
1333 pMem = (BYTE*)GlobalLock( hMem );
1336 memcpy( pMem, lpbiOut, cbHdr );
1338 TRACE( "call ICDecompress\n" );
1339 if ( ICDecompress( hic, 0, &lpbiIn->bmiHeader, lpBits, &lpbiOut->bmiHeader, pMem+cbHdr ) != ICERR_OK )
1344 if ( bInDecompress )
1345 ICDecompressEnd( hic );
1349 HeapFree(GetProcessHeap(),0,pHdr);
1351 GlobalUnlock( hMem );
1352 if ( !bSucceeded && hMem != (HGLOBAL)NULL )
1354 GlobalFree(hMem); hMem = (HGLOBAL)NULL;
1357 return (HANDLE)hMem;