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
;