2 * Copyright 1998 Marcus Meissner
3 * Copyright 2000 Bradley Baetz
4 * Copyright 2003 Michael Günnewig
5 * Copyright 2005 Dmitry Timoshkov
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 * FIXME: This all assumes 32 bit codecs
22 * Win95 appears to prefer 32 bit codecs, even from 16 bit code.
23 * There is the ICOpenFunction16 to worry about still, though.
29 #include "msvideo_private.h"
36 /* Drivers32 settings */
37 #define HKLM_DRIVERS32 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32"
39 WINE_DEFAULT_DEBUG_CHANNEL(msvideo
);
41 static inline const char *wine_dbgstr_fcc( DWORD fcc
)
43 return wine_dbg_sprintf("%c%c%c%c",
44 LOBYTE(LOWORD(fcc
)), HIBYTE(LOWORD(fcc
)),
45 LOBYTE(HIWORD(fcc
)), HIBYTE(HIWORD(fcc
)));
48 static WINE_HIC
* MSVIDEO_FirstHic
/* = NULL */;
50 typedef struct _reg_driver reg_driver
;
60 static reg_driver
* reg_driver_list
= NULL
;
62 /* This one is a macro in order to work for both ASCII and Unicode */
63 #define fourcc_to_string(str, fcc) do { \
64 (str)[0] = LOBYTE(LOWORD(fcc)); \
65 (str)[1] = HIBYTE(LOWORD(fcc)); \
66 (str)[2] = LOBYTE(HIWORD(fcc)); \
67 (str)[3] = HIBYTE(HIWORD(fcc)); \
70 HMODULE MSVFW32_hModule
;
72 BOOL WINAPI
DllMain( HINSTANCE hinst
, DWORD reason
, LPVOID reserved
)
74 TRACE("%p,%x,%p\n", hinst
, reason
, reserved
);
78 case DLL_PROCESS_ATTACH
:
79 DisableThreadLibraryCalls(hinst
);
80 MSVFW32_hModule
= hinst
;
86 /******************************************************************
91 static LRESULT
MSVIDEO_SendMessage(WINE_HIC
* whic
, UINT msg
, DWORD_PTR lParam1
, DWORD_PTR lParam2
)
95 #define XX(x) case x: TRACE("(%p,"#x",0x%08lx,0x%08lx)\n",whic,lParam1,lParam2); break
110 XX(ICM_GETDEFAULTQUALITY
);
117 XX(ICM_COMPRESS_FRAMES_INFO
);
118 XX(ICM_COMPRESS_GET_FORMAT
);
119 XX(ICM_COMPRESS_GET_SIZE
);
120 XX(ICM_COMPRESS_QUERY
);
121 XX(ICM_COMPRESS_BEGIN
);
123 XX(ICM_COMPRESS_END
);
124 XX(ICM_DECOMPRESS_GET_FORMAT
);
125 XX(ICM_DECOMPRESS_QUERY
);
126 XX(ICM_DECOMPRESS_BEGIN
);
128 XX(ICM_DECOMPRESS_END
);
129 XX(ICM_DECOMPRESS_SET_PALETTE
);
130 XX(ICM_DECOMPRESS_GET_PALETTE
);
133 XX(ICM_DRAW_GET_PALETTE
);
137 XX(ICM_DRAW_GETTIME
);
140 XX(ICM_DRAW_SETTIME
);
141 XX(ICM_DRAW_REALIZE
);
143 XX(ICM_DRAW_RENDERBUFFER
);
144 XX(ICM_DRAW_START_PLAY
);
145 XX(ICM_DRAW_STOP_PLAY
);
146 XX(ICM_DRAW_SUGGESTFORMAT
);
147 XX(ICM_DRAW_CHANGEPALETTE
);
148 XX(ICM_GETBUFFERSWANTED
);
149 XX(ICM_GETDEFAULTKEYFRAMERATE
);
150 XX(ICM_DECOMPRESSEX_BEGIN
);
151 XX(ICM_DECOMPRESSEX_QUERY
);
152 XX(ICM_DECOMPRESSEX
);
153 XX(ICM_DECOMPRESSEX_END
);
154 XX(ICM_SET_STATUS_PROC
);
156 FIXME("(%p,0x%08x,0x%08lx,0x%08lx) unknown message\n",whic
,msg
,lParam1
,lParam2
);
161 if (whic
->driverproc
) {
162 /* dwDriverId parameter is the value returned by the DRV_OPEN */
163 ret
= whic
->driverproc(whic
->driverId
, whic
->hdrv
, msg
, lParam1
, lParam2
);
165 ret
= SendDriverMessage(whic
->hdrv
, msg
, lParam1
, lParam2
);
168 TRACE(" -> 0x%08lx\n", ret
);
172 static int compare_fourcc(DWORD fcc1
, DWORD fcc2
)
176 fourcc_to_string(fcc_str1
, fcc1
);
177 fourcc_to_string(fcc_str2
, fcc2
);
178 return strncasecmp(fcc_str1
, fcc_str2
, 4);
181 typedef BOOL (*enum_handler_t
)(const char*, unsigned int, void*);
183 static BOOL
enum_drivers(DWORD fccType
, enum_handler_t handler
, void* param
)
185 CHAR buf
[2048], fccTypeStr
[5], *s
;
186 DWORD i
, cnt
= 0, lRet
;
190 fourcc_to_string(fccTypeStr
, fccType
);
193 /* first, go through the registry entries */
194 lRet
= RegOpenKeyExA(HKEY_LOCAL_MACHINE
, HKLM_DRIVERS32
, 0, KEY_QUERY_VALUE
, &hKey
);
195 if (lRet
== ERROR_SUCCESS
)
197 DWORD name
, data
, type
;
202 data
= sizeof buf
- name
;
203 lRet
= RegEnumValueA(hKey
, i
++, buf
, &name
, 0, &type
, (LPBYTE
)(buf
+name
), &data
);
204 if (lRet
== ERROR_NO_MORE_ITEMS
) break;
205 if (lRet
!= ERROR_SUCCESS
) continue;
206 if (name
!= 9 || strncasecmp(buf
, fccTypeStr
, 5)) continue;
208 if ((result
= handler(buf
, cnt
++, param
))) break;
212 if (result
) return result
;
214 /* if that didn't work, go through the values in system.ini */
215 if (GetPrivateProfileSectionA("drivers32", buf
, sizeof(buf
), "system.ini"))
217 for (s
= buf
; *s
; s
+= strlen(s
) + 1)
219 TRACE("got %s\n", s
);
220 if (strncasecmp(s
, fccTypeStr
, 5) || s
[9] != '=') continue;
221 if ((result
= handler(s
, cnt
++, param
))) break;
228 /******************************************************************
233 static WINE_HIC
* MSVIDEO_GetHicPtr(HIC hic
)
237 for (whic
= MSVIDEO_FirstHic
; whic
&& whic
->hic
!= hic
; whic
= whic
->next
);
241 /***********************************************************************
242 * VideoForWindowsVersion [MSVFW32.2]
243 * VideoForWindowsVersion [MSVIDEO.2]
244 * Returns the version in major.minor form.
245 * In Windows95 this returns 0x040003b6 (4.950)
247 DWORD WINAPI
VideoForWindowsVersion(void)
249 return 0x040003B6; /* 4.950 */
252 static BOOL
ICInfo_enum_handler(const char *drv
, unsigned int nr
, void *param
)
254 ICINFO
*lpicinfo
= param
;
255 DWORD fccHandler
= mmioStringToFOURCCA(drv
+ 5, 0);
257 /* exact match of fccHandler or nth driver found */
258 if ((lpicinfo
->fccHandler
!= nr
) && (lpicinfo
->fccHandler
!= fccHandler
))
261 lpicinfo
->fccHandler
= fccHandler
;
262 lpicinfo
->dwFlags
= 0;
263 lpicinfo
->dwVersion
= 0;
264 lpicinfo
->dwVersionICM
= ICVERSION
;
265 lpicinfo
->szName
[0] = 0;
266 lpicinfo
->szDescription
[0] = 0;
267 MultiByteToWideChar(CP_ACP
, 0, drv
+ 10, -1, lpicinfo
->szDriver
,
268 sizeof(lpicinfo
->szDriver
)/sizeof(WCHAR
));
273 /***********************************************************************
275 * Get information about an installable compressor. Return TRUE if there
279 * fccType [I] type of compressor (e.g. 'vidc')
280 * fccHandler [I] real fcc for handler or <n>th compressor
281 * lpicinfo [O] information about compressor
283 BOOL VFWAPI
ICInfo( DWORD fccType
, DWORD fccHandler
, ICINFO
*lpicinfo
)
285 TRACE("(%s,%s/%08x,%p)\n",
286 wine_dbgstr_fcc(fccType
), wine_dbgstr_fcc(fccHandler
), fccHandler
, lpicinfo
);
288 lpicinfo
->fccType
= fccType
;
289 lpicinfo
->fccHandler
= fccHandler
;
290 return enum_drivers(fccType
, ICInfo_enum_handler
, lpicinfo
);
293 static DWORD IC_HandleRef
= 1;
295 /***********************************************************************
296 * ICInstall [MSVFW32.@]
298 BOOL VFWAPI
ICInstall(DWORD fccType
, DWORD fccHandler
, LPARAM lParam
, LPSTR szDesc
, UINT wFlags
)
303 TRACE("(%s,%s,%p,%p,0x%08x)\n", wine_dbgstr_fcc(fccType
), wine_dbgstr_fcc(fccHandler
), (void*)lParam
, szDesc
, wFlags
);
305 /* Check if a driver is already registered */
306 for (driver
= reg_driver_list
; driver
; driver
= driver
->next
)
308 if (!compare_fourcc(fccType
, driver
->fccType
) &&
309 !compare_fourcc(fccHandler
, driver
->fccHandler
))
312 if (driver
) return FALSE
;
314 /* Register the driver */
315 driver
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(reg_driver
));
316 if (!driver
) goto oom
;
317 driver
->fccType
= fccType
;
318 driver
->fccHandler
= fccHandler
;
322 case ICINSTALL_FUNCTION
:
323 driver
->proc
= (DRIVERPROC
)lParam
;
326 case ICINSTALL_DRIVER
:
328 len
= MultiByteToWideChar(CP_ACP
, 0, (char*)lParam
, -1, NULL
, 0);
329 driver
->name
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
330 if (!driver
->name
) goto oom
;
331 MultiByteToWideChar(CP_ACP
, 0, (char*)lParam
, -1, driver
->name
, len
);
334 ERR("Invalid flags!\n");
335 HeapFree(GetProcessHeap(), 0, driver
);
339 /* Insert our driver in the list*/
340 driver
->next
= reg_driver_list
;
341 reg_driver_list
= driver
;
345 HeapFree(GetProcessHeap(), 0, driver
);
349 /***********************************************************************
350 * ICRemove [MSVFW32.@]
352 BOOL VFWAPI
ICRemove(DWORD fccType
, DWORD fccHandler
, UINT wFlags
)
354 reg_driver
** pdriver
;
357 TRACE("(%s,%s,0x%08x)\n", wine_dbgstr_fcc(fccType
), wine_dbgstr_fcc(fccHandler
), wFlags
);
359 /* Check if a driver is already registered */
360 for (pdriver
= ®_driver_list
; *pdriver
; pdriver
= &(*pdriver
)->next
)
362 if (!compare_fourcc(fccType
, (*pdriver
)->fccType
) &&
363 !compare_fourcc(fccHandler
, (*pdriver
)->fccHandler
))
369 /* Remove the driver from the list */
371 *pdriver
= (*pdriver
)->next
;
372 HeapFree(GetProcessHeap(), 0, drv
->name
);
373 HeapFree(GetProcessHeap(), 0, drv
);
379 /***********************************************************************
381 * Opens an installable compressor. Return special handle.
383 HIC VFWAPI
ICOpen(DWORD fccType
, DWORD fccHandler
, UINT wMode
)
389 static const WCHAR drv32W
[] = {'d','r','i','v','e','r','s','3','2','\0'};
392 TRACE("(%s,%s,0x%08x)\n", wine_dbgstr_fcc(fccType
), wine_dbgstr_fcc(fccHandler
), wMode
);
394 /* Check if there is a registered driver that matches */
395 driver
= reg_driver_list
;
397 if (!compare_fourcc(fccType
, driver
->fccType
) &&
398 !compare_fourcc(fccHandler
, driver
->fccHandler
)) {
399 fccType
= driver
->fccType
;
400 fccHandler
= driver
->fccHandler
;
403 driver
= driver
->next
;
405 if (driver
&& driver
->proc
)
406 /* The driver has been registered at runtime with its driverproc */
407 return ICOpenFunction(fccType
, fccHandler
, wMode
, driver
->proc
);
409 /* Well, lParam2 is in fact a LPVIDEO_OPEN_PARMS, but it has the
410 * same layout as ICOPEN
412 icopen
.dwSize
= sizeof(ICOPEN
);
413 icopen
.fccType
= fccType
;
414 icopen
.fccHandler
= fccHandler
;
415 icopen
.dwVersion
= 0x00001000; /* FIXME */
416 icopen
.dwFlags
= wMode
;
418 icopen
.pV1Reserved
= NULL
;
419 icopen
.pV2Reserved
= NULL
;
420 icopen
.dnDevNode
= 0; /* FIXME */
423 /* normalize to lower case as in 'vidc' */
424 ((char*)&fccType
)[0] = tolower(((char*)&fccType
)[0]);
425 ((char*)&fccType
)[1] = tolower(((char*)&fccType
)[1]);
426 ((char*)&fccType
)[2] = tolower(((char*)&fccType
)[2]);
427 ((char*)&fccType
)[3] = tolower(((char*)&fccType
)[3]);
428 icopen
.fccType
= fccType
;
429 /* Seek the driver in the registry */
430 fourcc_to_string(codecname
, fccType
);
432 fourcc_to_string(codecname
+ 5, fccHandler
);
435 hdrv
= OpenDriver(codecname
, drv32W
, (LPARAM
)&icopen
);
439 /* The driver has been registered at runtime with its name */
440 hdrv
= OpenDriver(driver
->name
, NULL
, (LPARAM
)&icopen
);
445 whic
= HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_HIC
));
448 CloseDriver(hdrv
, 0, 0);
452 whic
->driverproc
= NULL
;
453 whic
->type
= fccType
;
454 whic
->handler
= fccHandler
;
455 while (MSVIDEO_GetHicPtr((HIC
)(ULONG_PTR
)IC_HandleRef
) != NULL
) IC_HandleRef
++;
456 whic
->hic
= (HIC
)(ULONG_PTR
)IC_HandleRef
++;
457 whic
->next
= MSVIDEO_FirstHic
;
458 MSVIDEO_FirstHic
= whic
;
460 TRACE("=> %p\n", whic
->hic
);
464 /***********************************************************************
465 * ICOpenFunction [MSVFW32.@]
467 HIC VFWAPI
ICOpenFunction(DWORD fccType
, DWORD fccHandler
, UINT wMode
, DRIVERPROC lpfnHandler
)
472 TRACE("(%s,%s,%d,%p)\n",
473 wine_dbgstr_fcc(fccType
), wine_dbgstr_fcc(fccHandler
), wMode
, lpfnHandler
);
475 icopen
.dwSize
= sizeof(ICOPEN
);
476 icopen
.fccType
= fccType
;
477 icopen
.fccHandler
= fccHandler
;
478 icopen
.dwVersion
= ICVERSION
;
479 icopen
.dwFlags
= wMode
;
481 icopen
.pV1Reserved
= NULL
;
482 icopen
.pV2Reserved
= NULL
;
483 icopen
.dnDevNode
= 0; /* FIXME */
485 whic
= HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_HIC
));
488 whic
->driverproc
= lpfnHandler
;
489 while (MSVIDEO_GetHicPtr((HIC
)(ULONG_PTR
)IC_HandleRef
) != NULL
) IC_HandleRef
++;
490 whic
->hic
= (HIC
)(ULONG_PTR
)IC_HandleRef
++;
491 whic
->next
= MSVIDEO_FirstHic
;
492 MSVIDEO_FirstHic
= whic
;
494 /* Now try opening/loading the driver. Taken from DRIVER_AddToList */
495 /* What if the function is used more than once? */
497 if (MSVIDEO_SendMessage(whic
, DRV_LOAD
, 0L, 0L) != DRV_SUCCESS
)
499 WARN("DRV_LOAD failed for hic %p\n", whic
->hic
);
500 MSVIDEO_FirstHic
= whic
->next
;
501 HeapFree(GetProcessHeap(), 0, whic
);
504 /* return value is not checked */
505 MSVIDEO_SendMessage(whic
, DRV_ENABLE
, 0L, 0L);
507 whic
->driverId
= (DWORD
)MSVIDEO_SendMessage(whic
, DRV_OPEN
, 0, (DWORD_PTR
)&icopen
);
508 /* FIXME: What should we put here? */
511 if (whic
->driverId
== 0)
513 WARN("DRV_OPEN failed for hic %p\n", whic
->hic
);
514 MSVIDEO_FirstHic
= whic
->next
;
515 HeapFree(GetProcessHeap(), 0, whic
);
519 TRACE("=> %p\n", whic
->hic
);
523 /***********************************************************************
524 * ICGetInfo [MSVFW32.@]
526 LRESULT VFWAPI
ICGetInfo(HIC hic
, ICINFO
*picinfo
, DWORD cb
)
529 WINE_HIC
* whic
= MSVIDEO_GetHicPtr(hic
);
531 TRACE("(%p,%p,%d)\n", hic
, picinfo
, cb
);
533 if (!whic
) return ICERR_BADHANDLE
;
534 if (!picinfo
) return MMSYSERR_INVALPARAM
;
536 /* (WS) The field szDriver should be initialized because the driver
537 * is not obliged and often will not do it. Some applications, like
538 * VirtualDub, rely on this field and will occasionally crash if it
539 * goes uninitialized.
541 if (cb
>= sizeof(ICINFO
)) picinfo
->szDriver
[0] = '\0';
543 ret
= ICSendMessage(hic
, ICM_GETINFO
, (DWORD_PTR
)picinfo
, cb
);
545 /* (WS) When szDriver was not supplied by the driver itself, apparently
546 * Windows will set its value equal to the driver file name. This can
547 * be obtained from the registry as we do here.
549 if (cb
>= sizeof(ICINFO
) && picinfo
->szDriver
[0] == 0)
553 memset(&ii
, 0, sizeof(ii
));
554 ii
.dwSize
= sizeof(ii
);
555 ICInfo(picinfo
->fccType
, picinfo
->fccHandler
, &ii
);
556 lstrcpyW(picinfo
->szDriver
, ii
.szDriver
);
559 TRACE(" -> 0x%08lx\n", ret
);
566 LPBITMAPINFOHEADER lpbiIn
;
567 LPBITMAPINFOHEADER lpbiOut
;
573 static HIC
try_driver(driver_info_t
*info
)
577 if ((hic
= ICOpen(info
->fccType
, info
->fccHandler
, info
->wMode
)))
579 if (!ICSendMessage(hic
, info
->querymsg
, (DWORD_PTR
)info
->lpbiIn
, (DWORD_PTR
)info
->lpbiOut
))
586 static BOOL
ICLocate_enum_handler(const char *drv
, unsigned int nr
, void *param
)
588 driver_info_t
*info
= param
;
589 info
->fccHandler
= mmioStringToFOURCCA(drv
+ 5, 0);
590 info
->hic
= try_driver(info
);
591 return info
->hic
!= 0;
594 /***********************************************************************
595 * ICLocate [MSVFW32.@]
597 HIC VFWAPI
ICLocate(DWORD fccType
, DWORD fccHandler
, LPBITMAPINFOHEADER lpbiIn
,
598 LPBITMAPINFOHEADER lpbiOut
, WORD wMode
)
602 TRACE("(%s,%s,%p,%p,0x%04x)\n",
603 wine_dbgstr_fcc(fccType
), wine_dbgstr_fcc(fccHandler
), lpbiIn
, lpbiOut
, wMode
);
605 info
.fccType
= fccType
;
606 info
.fccHandler
= fccHandler
;
607 info
.lpbiIn
= lpbiIn
;
608 info
.lpbiOut
= lpbiOut
;
613 case ICMODE_FASTCOMPRESS
:
614 case ICMODE_COMPRESS
:
615 info
.querymsg
= ICM_COMPRESS_QUERY
;
617 case ICMODE_FASTDECOMPRESS
:
618 case ICMODE_DECOMPRESS
:
619 info
.querymsg
= ICM_DECOMPRESS_QUERY
;
622 info
.querymsg
= ICM_DRAW_QUERY
;
625 WARN("Unknown mode (%d)\n", wMode
);
629 /* Easy case: handler/type match, we just fire a query and return */
630 info
.hic
= try_driver(&info
);
631 /* If it didn't work, try each driver in turn. 32 bit codecs only. */
632 /* FIXME: Move this to an init routine? */
633 if (!info
.hic
) enum_drivers(fccType
, ICLocate_enum_handler
, &info
);
637 TRACE("=> %p\n", info
.hic
);
641 if (fccType
== streamtypeVIDEO
)
642 return ICLocate(ICTYPE_VIDEO
, fccHandler
, lpbiIn
, lpbiOut
, wMode
);
644 WARN("(%s,%s,%p,%p,0x%04x) not found!\n",
645 wine_dbgstr_fcc(fccType
), wine_dbgstr_fcc(fccHandler
), lpbiIn
, lpbiOut
, wMode
);
649 /***********************************************************************
650 * ICGetDisplayFormat [MSVFW32.@]
652 HIC VFWAPI
ICGetDisplayFormat(
653 HIC hic
,LPBITMAPINFOHEADER lpbiIn
,LPBITMAPINFOHEADER lpbiOut
,
654 INT depth
,INT dx
,INT dy
)
658 TRACE("(%p,%p,%p,%d,%d,%d)!\n",hic
,lpbiIn
,lpbiOut
,depth
,dx
,dy
);
661 tmphic
=ICLocate(ICTYPE_VIDEO
,0,lpbiIn
,NULL
,ICMODE_DECOMPRESS
);
665 if ((dy
== lpbiIn
->biHeight
) && (dx
== lpbiIn
->biWidth
))
666 dy
= dx
= 0; /* no resize needed */
668 /* Can we decompress it ? */
669 if (ICDecompressQuery(tmphic
,lpbiIn
,NULL
) != 0)
670 goto errout
; /* no, sorry */
672 ICSendMessage(tmphic
, ICM_DECOMPRESS_GET_FORMAT
, (DWORD_PTR
)lpbiIn
, (DWORD_PTR
)lpbiOut
);
674 if (lpbiOut
->biCompression
!= 0) {
675 FIXME("Ooch, how come decompressor outputs compressed data (%d)??\n",
676 lpbiOut
->biCompression
);
678 if (lpbiOut
->biSize
< sizeof(*lpbiOut
)) {
679 FIXME("Ooch, size of output BIH is too small (%d)\n",
681 lpbiOut
->biSize
= sizeof(*lpbiOut
);
687 depth
= GetDeviceCaps(hdc
,BITSPIXEL
)*GetDeviceCaps(hdc
,PLANES
);
689 if (depth
==15) depth
= 16;
690 if (depth
<8) depth
= 8;
692 if (lpbiIn
->biBitCount
== 8)
695 TRACE("=> %p\n", tmphic
);
705 /***********************************************************************
706 * ICCompress [MSVFW32.@]
710 HIC hic
,DWORD dwFlags
,LPBITMAPINFOHEADER lpbiOutput
,LPVOID lpData
,
711 LPBITMAPINFOHEADER lpbiInput
,LPVOID lpBits
,LPDWORD lpckid
,
712 LPDWORD lpdwFlags
,LONG lFrameNum
,DWORD dwFrameSize
,DWORD dwQuality
,
713 LPBITMAPINFOHEADER lpbiPrev
,LPVOID lpPrev
)
717 TRACE("(%p,%d,%p,%p,%p,%p,...)\n",hic
,dwFlags
,lpbiOutput
,lpData
,lpbiInput
,lpBits
);
719 iccmp
.dwFlags
= dwFlags
;
721 iccmp
.lpbiOutput
= lpbiOutput
;
722 iccmp
.lpOutput
= lpData
;
723 iccmp
.lpbiInput
= lpbiInput
;
724 iccmp
.lpInput
= lpBits
;
726 iccmp
.lpckid
= lpckid
;
727 iccmp
.lpdwFlags
= lpdwFlags
;
728 iccmp
.lFrameNum
= lFrameNum
;
729 iccmp
.dwFrameSize
= dwFrameSize
;
730 iccmp
.dwQuality
= dwQuality
;
731 iccmp
.lpbiPrev
= lpbiPrev
;
732 iccmp
.lpPrev
= lpPrev
;
733 return ICSendMessage(hic
,ICM_COMPRESS
,(DWORD_PTR
)&iccmp
,sizeof(iccmp
));
736 /***********************************************************************
737 * ICDecompress [MSVFW32.@]
739 DWORD VFWAPIV
ICDecompress(HIC hic
,DWORD dwFlags
,LPBITMAPINFOHEADER lpbiFormat
,
740 LPVOID lpData
,LPBITMAPINFOHEADER lpbi
,LPVOID lpBits
)
745 TRACE("(%p,%d,%p,%p,%p,%p)\n",hic
,dwFlags
,lpbiFormat
,lpData
,lpbi
,lpBits
);
747 icd
.dwFlags
= dwFlags
;
748 icd
.lpbiInput
= lpbiFormat
;
749 icd
.lpInput
= lpData
;
751 icd
.lpbiOutput
= lpbi
;
752 icd
.lpOutput
= lpBits
;
754 ret
= ICSendMessage(hic
,ICM_DECOMPRESS
,(DWORD_PTR
)&icd
,sizeof(ICDECOMPRESS
));
756 TRACE("-> %d\n",ret
);
762 struct choose_compressor
775 static BOOL
enum_compressors(HWND list
, COMPVARS
*pcv
, BOOL enum_all
)
782 while (ICInfo(pcv
->fccType
, id
, &icinfo
))
784 struct codec_info
*ic
;
790 hic
= ICOpen(icinfo
.fccType
, icinfo
.fccHandler
, ICMODE_COMPRESS
);
794 /* for unknown reason fccHandler reported by the driver
795 * doesn't always work, use the one returned by ICInfo instead.
797 DWORD fccHandler
= icinfo
.fccHandler
;
799 if (!enum_all
&& pcv
->lpbiIn
)
801 if (ICCompressQuery(hic
, pcv
->lpbiIn
, NULL
) != ICERR_OK
)
803 TRACE("fccHandler %s doesn't support input DIB format %d\n",
804 wine_dbgstr_fcc(icinfo
.fccHandler
), pcv
->lpbiIn
->bmiHeader
.biCompression
);
810 ICGetInfo(hic
, &icinfo
, sizeof(icinfo
));
811 icinfo
.fccHandler
= fccHandler
;
813 idx
= SendMessageW(list
, CB_ADDSTRING
, 0, (LPARAM
)icinfo
.szDescription
);
815 ic
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct codec_info
));
818 SendMessageW(list
, CB_SETITEMDATA
, idx
, (LPARAM
)ic
);
826 static INT_PTR CALLBACK
icm_choose_compressor_dlgproc(HWND hdlg
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
832 struct codec_info
*ic
;
834 struct choose_compressor
*choose_comp
= (struct choose_compressor
*)lparam
;
836 SetWindowLongPtrW(hdlg
, DWLP_USER
, lparam
);
839 choose_comp
->flags
&= ~(ICMF_CHOOSE_DATARATE
| ICMF_CHOOSE_KEYFRAME
);
841 if (choose_comp
->title
)
842 SetWindowTextA(hdlg
, choose_comp
->title
);
844 if (!(choose_comp
->flags
& ICMF_CHOOSE_DATARATE
))
846 ShowWindow(GetDlgItem(hdlg
, IDC_DATARATE_CHECKBOX
), SW_HIDE
);
847 ShowWindow(GetDlgItem(hdlg
, IDC_DATARATE
), SW_HIDE
);
848 ShowWindow(GetDlgItem(hdlg
, IDC_DATARATE_KB
), SW_HIDE
);
851 if (!(choose_comp
->flags
& ICMF_CHOOSE_KEYFRAME
))
853 ShowWindow(GetDlgItem(hdlg
, IDC_KEYFRAME_CHECKBOX
), SW_HIDE
);
854 ShowWindow(GetDlgItem(hdlg
, IDC_KEYFRAME
), SW_HIDE
);
855 ShowWindow(GetDlgItem(hdlg
, IDC_KEYFRAME_FRAMES
), SW_HIDE
);
859 EnableWindow(GetDlgItem(hdlg
, IDC_QUALITY_SCROLL
), FALSE
);
860 EnableWindow(GetDlgItem(hdlg
, IDC_QUALITY_TXT
), FALSE
);
862 /*if (!(choose_comp->flags & ICMF_CHOOSE_PREVIEW))
863 ShowWindow(GetDlgItem(hdlg, IDC_PREVIEW), SW_HIDE);*/
865 LoadStringW(MSVFW32_hModule
, IDS_FULLFRAMES
, buf
, 128);
866 SendDlgItemMessageW(hdlg
, IDC_COMP_LIST
, CB_ADDSTRING
, 0, (LPARAM
)buf
);
868 ic
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct codec_info
));
869 ic
->icinfo
.fccType
= streamtypeVIDEO
;
870 ic
->icinfo
.fccHandler
= comptypeDIB
;
872 SendDlgItemMessageW(hdlg
, IDC_COMP_LIST
, CB_SETITEMDATA
, 0, (LPARAM
)ic
);
874 enum_compressors(GetDlgItem(hdlg
, IDC_COMP_LIST
), &choose_comp
->cv
, choose_comp
->flags
& ICMF_CHOOSE_ALLCOMPRESSORS
);
876 SendDlgItemMessageW(hdlg
, IDC_COMP_LIST
, CB_SETCURSEL
, 0, 0);
877 SetFocus(GetDlgItem(hdlg
, IDC_COMP_LIST
));
879 SetWindowLongPtrW(hdlg
, DWLP_USER
, (ULONG_PTR
)choose_comp
);
884 switch (LOWORD(wparam
))
889 struct codec_info
*ic
;
890 BOOL can_configure
= FALSE
, can_about
= FALSE
;
891 struct choose_compressor
*choose_comp
;
893 if (HIWORD(wparam
) != CBN_SELCHANGE
&& HIWORD(wparam
) != CBN_SETFOCUS
)
896 choose_comp
= (struct choose_compressor
*)GetWindowLongPtrW(hdlg
, DWLP_USER
);
898 cur_sel
= SendMessageW((HWND
)lparam
, CB_GETCURSEL
, 0, 0);
900 ic
= (struct codec_info
*)SendMessageW((HWND
)lparam
, CB_GETITEMDATA
, cur_sel
, 0);
903 if (ICQueryConfigure(ic
->hic
) == DRVCNF_OK
)
904 can_configure
= TRUE
;
905 if (ICQueryAbout(ic
->hic
) == DRVCNF_OK
)
908 EnableWindow(GetDlgItem(hdlg
, IDC_CONFIGURE
), can_configure
);
909 EnableWindow(GetDlgItem(hdlg
, IDC_ABOUT
), can_about
);
911 if (choose_comp
->flags
& ICMF_CHOOSE_DATARATE
)
915 if (choose_comp
->flags
& ICMF_CHOOSE_KEYFRAME
)
926 HWND list
= GetDlgItem(hdlg
, IDC_COMP_LIST
);
928 struct codec_info
*ic
;
930 if (HIWORD(wparam
) != BN_CLICKED
)
933 cur_sel
= SendMessageW(list
, CB_GETCURSEL
, 0, 0);
935 ic
= (struct codec_info
*)SendMessageW(list
, CB_GETITEMDATA
, cur_sel
, 0);
938 if (LOWORD(wparam
) == IDC_CONFIGURE
)
939 ICConfigure(ic
->hic
, hdlg
);
941 ICAbout(ic
->hic
, hdlg
);
949 HWND list
= GetDlgItem(hdlg
, IDC_COMP_LIST
);
951 struct codec_info
*ic
;
953 if (HIWORD(wparam
) != BN_CLICKED
)
956 cur_sel
= SendMessageW(list
, CB_GETCURSEL
, 0, 0);
957 ic
= (struct codec_info
*)SendMessageW(list
, CB_GETITEMDATA
, cur_sel
, 0);
960 struct choose_compressor
*choose_comp
= (struct choose_compressor
*)GetWindowLongPtrW(hdlg
, DWLP_USER
);
962 choose_comp
->cv
.hic
= ic
->hic
;
963 choose_comp
->cv
.fccType
= ic
->icinfo
.fccType
;
964 choose_comp
->cv
.fccHandler
= ic
->icinfo
.fccHandler
;
965 /* FIXME: fill everything else */
967 /* prevent closing the codec handle below */
974 HWND list
= GetDlgItem(hdlg
, IDC_COMP_LIST
);
977 if (HIWORD(wparam
) != BN_CLICKED
)
982 struct codec_info
*ic
;
984 ic
= (struct codec_info
*)SendMessageW(list
, CB_GETITEMDATA
, idx
++, 0);
986 if (!ic
|| (LONG_PTR
)ic
== CB_ERR
) break;
988 if (ic
->hic
) ICClose(ic
->hic
);
989 HeapFree(GetProcessHeap(), 0, ic
);
992 EndDialog(hdlg
, LOWORD(wparam
) == IDOK
);
1008 /***********************************************************************
1009 * ICCompressorChoose [MSVFW32.@]
1011 BOOL VFWAPI
ICCompressorChoose(HWND hwnd
, UINT uiFlags
, LPVOID pvIn
,
1012 LPVOID lpData
, PCOMPVARS pc
, LPSTR lpszTitle
)
1014 struct choose_compressor choose_comp
;
1017 TRACE("(%p,%08x,%p,%p,%p,%s)\n", hwnd
, uiFlags
, pvIn
, lpData
, pc
, lpszTitle
);
1019 if (!pc
|| pc
->cbSize
!= sizeof(COMPVARS
))
1022 if (!(pc
->dwFlags
& ICMF_COMPVARS_VALID
))
1025 pc
->fccType
= pc
->fccHandler
= 0;
1029 pc
->lpBitsOut
= pc
->lpBitsPrev
= pc
->lpState
= NULL
;
1030 pc
->lQ
= ICQUALITY_DEFAULT
;
1032 pc
->lDataRate
= 300; /* kB */
1036 if (pc
->fccType
== 0)
1037 pc
->fccType
= ICTYPE_VIDEO
;
1039 choose_comp
.cv
= *pc
;
1040 choose_comp
.flags
= uiFlags
;
1041 choose_comp
.title
= lpszTitle
;
1043 ret
= DialogBoxParamW(MSVFW32_hModule
, MAKEINTRESOURCEW(ICM_CHOOSE_COMPRESSOR
), hwnd
,
1044 icm_choose_compressor_dlgproc
, (LPARAM
)&choose_comp
);
1048 *pc
= choose_comp
.cv
;
1049 pc
->dwFlags
|= ICMF_COMPVARS_VALID
;
1056 /***********************************************************************
1057 * ICCompressorFree [MSVFW32.@]
1059 void VFWAPI
ICCompressorFree(PCOMPVARS pc
)
1063 if (pc
!= NULL
&& pc
->cbSize
== sizeof(COMPVARS
)) {
1064 if (pc
->hic
!= NULL
) {
1068 HeapFree(GetProcessHeap(), 0, pc
->lpbiIn
);
1070 HeapFree(GetProcessHeap(), 0, pc
->lpBitsOut
);
1071 pc
->lpBitsOut
= NULL
;
1072 HeapFree(GetProcessHeap(), 0, pc
->lpBitsPrev
);
1073 pc
->lpBitsPrev
= NULL
;
1074 HeapFree(GetProcessHeap(), 0, pc
->lpState
);
1080 /***********************************************************************
1081 * ICSendMessage [MSVFW32.@]
1083 LRESULT VFWAPI
ICSendMessage(HIC hic
, UINT msg
, DWORD_PTR lParam1
, DWORD_PTR lParam2
)
1085 WINE_HIC
* whic
= MSVIDEO_GetHicPtr(hic
);
1087 if (!whic
) return ICERR_BADHANDLE
;
1088 return MSVIDEO_SendMessage(whic
, msg
, lParam1
, lParam2
);
1091 /***********************************************************************
1092 * ICDrawBegin [MSVFW32.@]
1094 DWORD VFWAPIV
ICDrawBegin(
1096 DWORD dwFlags
, /* [in] flags */
1097 HPALETTE hpal
, /* [in] palette to draw with */
1098 HWND hwnd
, /* [in] window to draw to */
1099 HDC hdc
, /* [in] HDC to draw to */
1100 INT xDst
, /* [in] destination rectangle */
1101 INT yDst
, /* [in] */
1102 INT dxDst
, /* [in] */
1103 INT dyDst
, /* [in] */
1104 LPBITMAPINFOHEADER lpbi
, /* [in] format of frame to draw */
1105 INT xSrc
, /* [in] source rectangle */
1106 INT ySrc
, /* [in] */
1107 INT dxSrc
, /* [in] */
1108 INT dySrc
, /* [in] */
1109 DWORD dwRate
, /* [in] frames/second = (dwRate/dwScale) */
1110 DWORD dwScale
) /* [in] */
1115 TRACE("(%p,%d,%p,%p,%p,%u,%u,%u,%u,%p,%u,%u,%u,%u,%d,%d)\n",
1116 hic
, dwFlags
, hpal
, hwnd
, hdc
, xDst
, yDst
, dxDst
, dyDst
,
1117 lpbi
, xSrc
, ySrc
, dxSrc
, dySrc
, dwRate
, dwScale
);
1119 icdb
.dwFlags
= dwFlags
;
1132 icdb
.dwRate
= dwRate
;
1133 icdb
.dwScale
= dwScale
;
1134 return ICSendMessage(hic
,ICM_DRAW_BEGIN
,(DWORD_PTR
)&icdb
,sizeof(icdb
));
1137 /***********************************************************************
1138 * ICDraw [MSVFW32.@]
1140 DWORD VFWAPIV
ICDraw(HIC hic
, DWORD dwFlags
, LPVOID lpFormat
, LPVOID lpData
, DWORD cbData
, LONG lTime
) {
1143 TRACE("(%p,%d,%p,%p,%d,%d)\n",hic
,dwFlags
,lpFormat
,lpData
,cbData
,lTime
);
1145 icd
.dwFlags
= dwFlags
;
1146 icd
.lpFormat
= lpFormat
;
1147 icd
.lpData
= lpData
;
1148 icd
.cbData
= cbData
;
1151 return ICSendMessage(hic
,ICM_DRAW
,(DWORD_PTR
)&icd
,sizeof(icd
));
1154 /***********************************************************************
1155 * ICClose [MSVFW32.@]
1157 LRESULT WINAPI
ICClose(HIC hic
)
1159 WINE_HIC
* whic
= MSVIDEO_GetHicPtr(hic
);
1162 TRACE("(%p)\n",hic
);
1164 if (!whic
) return ICERR_BADHANDLE
;
1166 if (whic
->driverproc
)
1168 MSVIDEO_SendMessage(whic
, DRV_CLOSE
, 0, 0);
1169 MSVIDEO_SendMessage(whic
, DRV_DISABLE
, 0, 0);
1170 MSVIDEO_SendMessage(whic
, DRV_FREE
, 0, 0);
1174 CloseDriver(whic
->hdrv
, 0, 0);
1177 /* remove whic from list */
1178 for (p
= &MSVIDEO_FirstHic
; *p
!= NULL
; p
= &((*p
)->next
))
1187 HeapFree(GetProcessHeap(), 0, whic
);
1193 /***********************************************************************
1194 * ICImageCompress [MSVFW32.@]
1196 HANDLE VFWAPI
ICImageCompress(
1197 HIC hic
, UINT uiFlags
,
1198 LPBITMAPINFO lpbiIn
, LPVOID lpBits
,
1199 LPBITMAPINFO lpbiOut
, LONG lQuality
,
1202 FIXME("(%p,%08x,%p,%p,%p,%d,%p)\n",
1203 hic
, uiFlags
, lpbiIn
, lpBits
, lpbiOut
, lQuality
, plSize
);
1208 /***********************************************************************
1209 * ICImageDecompress [MSVFW32.@]
1212 HANDLE VFWAPI
ICImageDecompress(
1213 HIC hic
, UINT uiFlags
, LPBITMAPINFO lpbiIn
,
1214 LPVOID lpBits
, LPBITMAPINFO lpbiOut
)
1216 HGLOBAL hMem
= NULL
;
1218 BOOL bReleaseIC
= FALSE
;
1221 BOOL bSucceeded
= FALSE
;
1222 BOOL bInDecompress
= FALSE
;
1225 TRACE("(%p,%08x,%p,%p,%p)\n",
1226 hic
, uiFlags
, lpbiIn
, lpBits
, lpbiOut
);
1230 hic
= ICDecompressOpen( ICTYPE_VIDEO
, 0, &lpbiIn
->bmiHeader
, (lpbiOut
!= NULL
) ? &lpbiOut
->bmiHeader
: NULL
);
1233 WARN("no handler\n" );
1240 FIXME( "unknown flag %08x\n", uiFlags
);
1243 if ( lpbiIn
== NULL
|| lpBits
== NULL
)
1245 WARN("invalid argument\n");
1249 if ( lpbiOut
!= NULL
)
1251 if ( lpbiOut
->bmiHeader
.biSize
!= sizeof(BITMAPINFOHEADER
) )
1253 cbHdr
= sizeof(BITMAPINFOHEADER
);
1254 if ( lpbiOut
->bmiHeader
.biCompression
== 3 )
1255 cbHdr
+= sizeof(DWORD
)*3;
1257 if ( lpbiOut
->bmiHeader
.biBitCount
<= 8 )
1259 if ( lpbiOut
->bmiHeader
.biClrUsed
== 0 )
1260 cbHdr
+= sizeof(RGBQUAD
) * (1<<lpbiOut
->bmiHeader
.biBitCount
);
1262 cbHdr
+= sizeof(RGBQUAD
) * lpbiOut
->bmiHeader
.biClrUsed
;
1267 TRACE( "get format\n" );
1269 cbHdr
= ICDecompressGetFormatSize(hic
,lpbiIn
);
1270 if ( cbHdr
< sizeof(BITMAPINFOHEADER
) )
1272 pHdr
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,cbHdr
+sizeof(RGBQUAD
)*256);
1275 if ( ICDecompressGetFormat( hic
, lpbiIn
, pHdr
) != ICERR_OK
)
1277 lpbiOut
= (BITMAPINFO
*)pHdr
;
1278 if ( lpbiOut
->bmiHeader
.biBitCount
<= 8 &&
1279 ICDecompressGetPalette( hic
, lpbiIn
, lpbiOut
) != ICERR_OK
&&
1280 lpbiIn
->bmiHeader
.biBitCount
== lpbiOut
->bmiHeader
.biBitCount
)
1282 if ( lpbiIn
->bmiHeader
.biClrUsed
== 0 )
1283 memcpy( lpbiOut
->bmiColors
, lpbiIn
->bmiColors
, sizeof(RGBQUAD
)*(1<<lpbiOut
->bmiHeader
.biBitCount
) );
1285 memcpy( lpbiOut
->bmiColors
, lpbiIn
->bmiColors
, sizeof(RGBQUAD
)*lpbiIn
->bmiHeader
.biClrUsed
);
1287 if ( lpbiOut
->bmiHeader
.biBitCount
<= 8 &&
1288 lpbiOut
->bmiHeader
.biClrUsed
== 0 )
1289 lpbiOut
->bmiHeader
.biClrUsed
= 1<<lpbiOut
->bmiHeader
.biBitCount
;
1291 lpbiOut
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
1292 cbHdr
= sizeof(BITMAPINFOHEADER
) + sizeof(RGBQUAD
)*lpbiOut
->bmiHeader
.biClrUsed
;
1295 biSizeImage
= lpbiOut
->bmiHeader
.biSizeImage
;
1296 if ( biSizeImage
== 0 )
1297 biSizeImage
= ((((lpbiOut
->bmiHeader
.biWidth
* lpbiOut
->bmiHeader
.biBitCount
+ 7) >> 3) + 3) & (~3)) * abs(lpbiOut
->bmiHeader
.biHeight
);
1299 TRACE( "call ICDecompressBegin\n" );
1301 if ( ICDecompressBegin( hic
, lpbiIn
, lpbiOut
) != ICERR_OK
)
1303 bInDecompress
= TRUE
;
1305 TRACE( "cbHdr %d, biSizeImage %d\n", cbHdr
, biSizeImage
);
1307 hMem
= GlobalAlloc( GMEM_MOVEABLE
|GMEM_ZEROINIT
, cbHdr
+ biSizeImage
);
1310 WARN( "out of memory\n" );
1313 pMem
= GlobalLock( hMem
);
1316 memcpy( pMem
, lpbiOut
, cbHdr
);
1318 TRACE( "call ICDecompress\n" );
1319 if ( ICDecompress( hic
, 0, &lpbiIn
->bmiHeader
, lpBits
, &lpbiOut
->bmiHeader
, pMem
+cbHdr
) != ICERR_OK
)
1324 if ( bInDecompress
)
1325 ICDecompressEnd( hic
);
1328 HeapFree(GetProcessHeap(),0,pHdr
);
1330 GlobalUnlock( hMem
);
1331 if ( !bSucceeded
&& hMem
!= NULL
)
1333 GlobalFree(hMem
); hMem
= NULL
;
1339 /***********************************************************************
1340 * ICSeqCompressFrame [MSVFW32.@]
1342 LPVOID VFWAPI
ICSeqCompressFrame(PCOMPVARS pc
, UINT uiFlags
, LPVOID lpBits
, BOOL
*pfKey
, LONG
*plSize
)
1344 ICCOMPRESS
* icComp
= pc
->lpState
;
1346 TRACE("(%p, 0x%08x, %p, %p, %p)\n", pc
, uiFlags
, lpBits
, pfKey
, plSize
);
1348 if (pc
->cbState
!= sizeof(ICCOMPRESS
))
1350 ERR("Invalid cbState %i\n", pc
->cbState
);
1354 if (!pc
->lKeyCount
++)
1355 icComp
->dwFlags
= ICCOMPRESS_KEYFRAME
;
1358 if (pc
->lKey
&& pc
->lKeyCount
== (pc
->lKey
- 1))
1359 /* No key frames if pc->lKey == 0 */
1361 icComp
->dwFlags
= 0;
1364 icComp
->lpInput
= lpBits
;
1365 icComp
->lFrameNum
= pc
->lFrame
++;
1366 icComp
->lpOutput
= pc
->lpBitsOut
;
1367 icComp
->lpPrev
= pc
->lpBitsPrev
;
1368 ret
= ICSendMessage(pc
->hic
, ICM_COMPRESS
, (DWORD_PTR
)icComp
, sizeof(*icComp
));
1370 if (icComp
->dwFlags
& AVIIF_KEYFRAME
)
1374 TRACE("Key frame\n");
1379 *plSize
= icComp
->lpbiOutput
->biSizeImage
;
1380 TRACE(" -- 0x%08x\n", ret
);
1381 if (ret
== ICERR_OK
)
1383 LPVOID oldprev
, oldout
;
1384 /* We shift Prev and Out, so we don't have to allocate and release memory */
1385 oldprev
= pc
->lpBitsPrev
;
1386 oldout
= pc
->lpBitsOut
;
1387 pc
->lpBitsPrev
= oldout
;
1388 pc
->lpBitsOut
= oldprev
;
1390 TRACE("returning: %p\n", icComp
->lpOutput
);
1391 return icComp
->lpOutput
;
1396 /***********************************************************************
1397 * ICSeqCompressFrameEnd [MSVFW32.@]
1399 void VFWAPI
ICSeqCompressFrameEnd(PCOMPVARS pc
)
1402 TRACE("(%p)\n", pc
);
1403 ret
= ICSendMessage(pc
->hic
, ICM_COMPRESS_END
, 0, 0);
1404 TRACE(" -- %x\n", ret
);
1405 HeapFree(GetProcessHeap(), 0, pc
->lpbiIn
);
1406 HeapFree(GetProcessHeap(), 0, pc
->lpBitsPrev
);
1407 HeapFree(GetProcessHeap(), 0, pc
->lpBitsOut
);
1408 HeapFree(GetProcessHeap(), 0, pc
->lpState
);
1409 pc
->lpbiIn
= pc
->lpBitsPrev
= pc
->lpBitsOut
= pc
->lpState
= NULL
;
1412 /***********************************************************************
1413 * ICSeqCompressFrameStart [MSVFW32.@]
1415 BOOL VFWAPI
ICSeqCompressFrameStart(PCOMPVARS pc
, LPBITMAPINFO lpbiIn
)
1417 /* I'm ignoring bmiColors as I don't know what to do with it,
1418 * it doesn't appear to be used though
1421 pc
->lpbiIn
= HeapAlloc(GetProcessHeap(), 0, sizeof(BITMAPINFO
));
1425 *pc
->lpbiIn
= *lpbiIn
;
1426 pc
->lpBitsPrev
= HeapAlloc(GetProcessHeap(), 0, pc
->lpbiIn
->bmiHeader
.biSizeImage
);
1427 if (!pc
->lpBitsPrev
)
1429 HeapFree(GetProcessHeap(), 0, pc
->lpbiIn
);
1433 pc
->lpState
= HeapAlloc(GetProcessHeap(), 0, sizeof(ICCOMPRESS
));
1436 HeapFree(GetProcessHeap(), 0, pc
->lpbiIn
);
1437 HeapFree(GetProcessHeap(), 0, pc
->lpBitsPrev
);
1440 pc
->cbState
= sizeof(ICCOMPRESS
);
1442 pc
->lpBitsOut
= HeapAlloc(GetProcessHeap(), 0, pc
->lpbiOut
->bmiHeader
.biSizeImage
);
1445 HeapFree(GetProcessHeap(), 0, pc
->lpbiIn
);
1446 HeapFree(GetProcessHeap(), 0, pc
->lpBitsPrev
);
1447 HeapFree(GetProcessHeap(), 0, pc
->lpState
);
1458 "key/data/quality: %i/%i/%i\n",
1459 pc
->cbSize
, pc
->dwFlags
, pc
->hic
, pc
->fccType
, pc
->fccHandler
,
1460 pc
->lpbiIn
, pc
->lpbiOut
, pc
->lKey
, pc
->lDataRate
, pc
->lQ
);
1462 ret
= ICSendMessage(pc
->hic
, ICM_COMPRESS_BEGIN
, (DWORD_PTR
)pc
->lpbiIn
, (DWORD_PTR
)pc
->lpbiOut
);
1463 TRACE(" -- %x\n", ret
);
1464 if (ret
== ICERR_OK
)
1466 ICCOMPRESS
* icComp
= pc
->lpState
;
1467 /* Initialise some variables */
1468 pc
->lFrame
= 0; pc
->lKeyCount
= 0;
1470 icComp
->lpbiOutput
= &pc
->lpbiOut
->bmiHeader
;
1471 icComp
->lpbiInput
= &pc
->lpbiIn
->bmiHeader
;
1472 icComp
->lpckid
= NULL
;
1473 icComp
->dwFrameSize
= 0;
1474 icComp
->dwQuality
= pc
->lQ
;
1475 icComp
->lpbiPrev
= &pc
->lpbiIn
->bmiHeader
;
1478 HeapFree(GetProcessHeap(), 0, pc
->lpbiIn
);
1479 HeapFree(GetProcessHeap(), 0, pc
->lpBitsPrev
);
1480 HeapFree(GetProcessHeap(), 0, pc
->lpState
);
1481 HeapFree(GetProcessHeap(), 0, pc
->lpBitsOut
);
1482 pc
->lpBitsPrev
= pc
->lpbiIn
= pc
->lpState
= pc
->lpBitsOut
= NULL
;
1486 /***********************************************************************
1487 * GetFileNamePreview [MSVFW32.@]
1489 static BOOL
GetFileNamePreview(LPVOID lpofn
,BOOL bSave
,BOOL bUnicode
)
1491 CHAR szFunctionName
[20];
1492 BOOL (*fnGetFileName
)(LPVOID
);
1496 FIXME("(%p,%d,%d), semi-stub!\n",lpofn
,bSave
,bUnicode
);
1498 lstrcpyA(szFunctionName
, (bSave
? "GetSaveFileName" : "GetOpenFileName"));
1499 lstrcatA(szFunctionName
, (bUnicode
? "W" : "A"));
1501 hComdlg32
= LoadLibraryA("COMDLG32.DLL");
1502 if (hComdlg32
== NULL
)
1505 fnGetFileName
= (LPVOID
)GetProcAddress(hComdlg32
, szFunctionName
);
1506 if (fnGetFileName
== NULL
)
1508 FreeLibrary(hComdlg32
);
1512 /* FIXME: need to add OFN_ENABLEHOOK and our own handler */
1513 ret
= fnGetFileName(lpofn
);
1515 FreeLibrary(hComdlg32
);
1519 /***********************************************************************
1520 * GetOpenFileNamePreviewA [MSVFW32.@]
1522 BOOL WINAPI
GetOpenFileNamePreviewA(LPOPENFILENAMEA lpofn
)
1524 FIXME("(%p), semi-stub!\n", lpofn
);
1526 return GetFileNamePreview(lpofn
, FALSE
, FALSE
);
1529 /***********************************************************************
1530 * GetOpenFileNamePreviewW [MSVFW32.@]
1532 BOOL WINAPI
GetOpenFileNamePreviewW(LPOPENFILENAMEW lpofn
)
1534 FIXME("(%p), semi-stub!\n", lpofn
);
1536 return GetFileNamePreview(lpofn
, FALSE
, TRUE
);
1539 /***********************************************************************
1540 * GetSaveFileNamePreviewA [MSVFW32.@]
1542 BOOL WINAPI
GetSaveFileNamePreviewA(LPOPENFILENAMEA lpofn
)
1544 FIXME("(%p), semi-stub!\n", lpofn
);
1546 return GetFileNamePreview(lpofn
, TRUE
, FALSE
);
1549 /***********************************************************************
1550 * GetSaveFileNamePreviewW [MSVFW32.@]
1552 BOOL WINAPI
GetSaveFileNamePreviewW(LPOPENFILENAMEW lpofn
)
1554 FIXME("(%p), semi-stub!\n", lpofn
);
1556 return GetFileNamePreview(lpofn
, TRUE
, TRUE
);