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.
32 #include "wine/winbase16.h"
33 #include "wine/debug.h"
34 #include "msvideo_private.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(msvideo
);
38 LRESULT (CALLBACK
*pFnCallTo16
)(HDRVR
, HIC
, UINT
, LPARAM
, LPARAM
) = NULL
;
40 /***********************************************************************
41 * VideoForWindowsVersion [MSVFW32.2]
42 * VideoForWindowsVersion [MSVIDEO.2]
43 * Returns the version in major.minor form.
44 * In Windows95 this returns 0x040003b6 (4.950)
46 DWORD WINAPI
VideoForWindowsVersion(void)
48 return 0x040003B6; /* 4.950 */
51 /* system.ini: [drivers] */
53 /***********************************************************************
55 * Get information about an installable compressor. Return TRUE if there
59 DWORD fccType
, /* [in] type of compressor ('vidc') */
60 DWORD fccHandler
, /* [in] <n>th compressor */
61 ICINFO
*lpicinfo
) /* [out] information about compressor */
63 char type
[5],buf
[2000];
65 memcpy(type
,&fccType
,4);type
[4]=0;
66 TRACE("(%s,%ld,%p).\n",type
,fccHandler
,lpicinfo
);
67 /* does OpenDriver/CloseDriver */
68 lpicinfo
->dwSize
= sizeof(ICINFO
);
69 lpicinfo
->fccType
= fccType
;
70 lpicinfo
->dwFlags
= 0;
71 if (GetPrivateProfileStringA("drivers32",NULL
,NULL
,buf
,2000,"system.ini")) {
74 if (!strncasecmp(type
,s
,4)) {
76 lpicinfo
->fccHandler
= mmioStringToFOURCCA(s
+5,0);
80 s
=s
+strlen(s
)+1; /* either next char or \0 */
86 /***********************************************************************
88 * Opens an installable compressor. Return special handle.
90 HIC VFWAPI
ICOpen(DWORD fccType
,DWORD fccHandler
,UINT wMode
) {
91 char type
[5],handler
[5],codecname
[20];
98 memcpy(type
,&fccType
,4);type
[4]=0;
99 memcpy(handler
,&fccHandler
,4);handler
[4]=0;
100 TRACE("(%s,%s,0x%08lx)\n",type
,handler
,(DWORD
)wMode
);
102 sprintf(codecname
,"%s.%s",type
,handler
);
104 /* Well, lParam2 is in fact a LPVIDEO_OPEN_PARMS, but it has the
105 * same layout as ICOPEN
107 icopen
.dwSize
= sizeof(ICOPEN
);
108 icopen
.fccType
= fccType
;
109 icopen
.fccHandler
= fccHandler
;
110 icopen
.dwVersion
= 0x00001000; /* FIXME */
111 icopen
.dwFlags
= wMode
;
113 icopen
.pV1Reserved
= NULL
;
114 icopen
.pV2Reserved
= NULL
;
115 icopen
.dnDevNode
= 0; /* FIXME */
117 hdrv
=OpenDriverA(codecname
,"drivers32",(LPARAM
)&icopen
);
119 if (!strcasecmp(type
,"vids")) {
120 sprintf(codecname
,"vidc.%s",handler
);
121 fccType
= mmioFOURCC('v','i','d','c');
123 hdrv
=OpenDriverA(codecname
,"drivers32",(LPARAM
)&icopen
);
127 bIs16
= GetDriverFlags(hdrv
) & WINE_GDF_16BIT
;
129 if (bIs16
&& !pFnCallTo16
)
131 FIXME("Got a 16 bit driver, but no 16 bit support in msvfw\n");
134 /* The handle should be a valid 16-bit handle as well */
135 hic
= HIC_32(GlobalAlloc16(GHND
,sizeof(WINE_HIC
)));
136 whic
= (WINE_HIC
*)GlobalLock16(HIC_16(hic
));
138 /* FIXME: is the signature the real one ? */
139 whic
->driverproc
= bIs16
? (DRIVERPROC
)pFnCallTo16
: NULL
;
140 whic
->driverproc16
= NULL
;
142 GlobalUnlock16(HIC_16(hic
));
143 TRACE("=> %p\n",hic
);
147 /***********************************************************************
148 * MSVIDEO_OpenFunction
150 HIC
MSVIDEO_OpenFunction(DWORD fccType
, DWORD fccHandler
, UINT wMode
,
151 DRIVERPROC lpfnHandler
, DRIVERPROC16 lpfnHandler16
)
153 char type
[5],handler
[5],codecname
[20];
158 memcpy(type
,&fccType
,4);type
[4]=0;
159 memcpy(handler
,&fccHandler
,4);handler
[4]=0;
160 TRACE("(%s,%s,%d,%p,%p)\n",type
,handler
,wMode
,lpfnHandler
,lpfnHandler16
);
162 icopen
.fccType
= fccType
;
163 icopen
.fccHandler
= fccHandler
;
164 icopen
.dwSize
= sizeof(ICOPEN
);
165 icopen
.dwFlags
= wMode
;
167 sprintf(codecname
,"%s.%s",type
,handler
);
169 hic
= HIC_32(GlobalAlloc16(GHND
,sizeof(WINE_HIC
)));
172 whic
= GlobalLock16(HIC_16(hic
));
173 whic
->driverproc
= lpfnHandler
;
174 whic
->driverproc16
= lpfnHandler16
;
176 /* Now try opening/loading the driver. Taken from DRIVER_AddToList */
177 /* What if the function is used more than once? */
179 if (MSVIDEO_SendMessage(hic
,DRV_LOAD
,0L,0L) != DRV_SUCCESS
) {
180 WARN("DRV_LOAD failed for hic %p\n", hic
);
181 GlobalFree16(HIC_16(hic
));
184 /* return value is not checked */
185 MSVIDEO_SendMessage(hic
,DRV_ENABLE
,0L,0L);
187 whic
->hdrv
= (HDRVR
)MSVIDEO_SendMessage(hic
,DRV_OPEN
,0,(DWORD
)&icopen
);
189 if (whic
->hdrv
== 0) {
190 WARN("DRV_OPEN failed for hic %p\n",hic
);
191 GlobalFree16(HIC_16(hic
));
195 GlobalUnlock16(HIC_16(hic
));
196 TRACE("=> %p\n",hic
);
200 /***********************************************************************
201 * ICOpenFunction [MSVFW32.@]
203 HIC VFWAPI
ICOpenFunction(DWORD fccType
, DWORD fccHandler
, UINT wMode
, FARPROC lpfnHandler
)
205 return MSVIDEO_OpenFunction(fccType
, fccHandler
, wMode
, (DRIVERPROC
)lpfnHandler
, NULL
);
208 /***********************************************************************
209 * ICGetInfo [MSVFW32.@]
211 LRESULT VFWAPI
ICGetInfo(HIC hic
,ICINFO
*picinfo
,DWORD cb
) {
214 TRACE("(%p,%p,%ld)\n",hic
,picinfo
,cb
);
215 ret
= ICSendMessage(hic
,ICM_GETINFO
,(DWORD
)picinfo
,cb
);
216 TRACE(" -> 0x%08lx\n",ret
);
220 /***********************************************************************
221 * ICLocate [MSVFW32.@]
224 DWORD fccType
, DWORD fccHandler
, LPBITMAPINFOHEADER lpbiIn
,
225 LPBITMAPINFOHEADER lpbiOut
, WORD wMode
)
227 char type
[5],handler
[5];
232 type
[4]=0;memcpy(type
,&fccType
,4);
233 handler
[4]=0;memcpy(handler
,&fccHandler
,4);
235 TRACE("(%s,%s,%p,%p,0x%04x)\n", type
, handler
, lpbiIn
, lpbiOut
, wMode
);
238 case ICMODE_FASTCOMPRESS
:
239 case ICMODE_COMPRESS
:
240 querymsg
= ICM_COMPRESS_QUERY
;
242 case ICMODE_FASTDECOMPRESS
:
243 case ICMODE_DECOMPRESS
:
244 querymsg
= ICM_DECOMPRESS_QUERY
;
247 querymsg
= ICM_DRAW_QUERY
;
250 WARN("Unknown mode (%d)\n",wMode
);
254 /* Easy case: handler/type match, we just fire a query and return */
255 hic
= ICOpen(fccType
,fccHandler
,wMode
);
257 if (!ICSendMessage(hic
,querymsg
,(DWORD
)lpbiIn
,(DWORD
)lpbiOut
))
262 type
[4]='.';memcpy(type
,&fccType
,4);
263 handler
[4]='.';memcpy(handler
,&fccHandler
,4);
265 /* Now try each driver in turn. 32 bit codecs only. */
266 /* FIXME: Move this to an init routine? */
268 pszBuffer
= (LPSTR
)HeapAlloc(GetProcessHeap(),0,1024);
269 if (GetPrivateProfileSectionA("drivers32",pszBuffer
,1024,"system.ini")) {
272 if (!strncasecmp(type
,s
,5)) {
274 while (*s2
!= '\0' && *s2
!= '.') s2
++;
278 h
= ICOpen(fccType
,*(DWORD
*)s2
,wMode
);
280 if (!ICSendMessage(h
,querymsg
,(DWORD
)lpbiIn
,(DWORD
)lpbiOut
))
289 HeapFree(GetProcessHeap(),0,pszBuffer
);
291 if (fccType
==streamtypeVIDEO
) {
292 hic
= ICLocate(ICTYPE_VIDEO
,fccHandler
,lpbiIn
,lpbiOut
,wMode
);
297 type
[4] = handler
[4] = '\0';
298 WARN("(%.4s,%.4s,%p,%p,0x%04x) not found!\n",type
,handler
,lpbiIn
,lpbiOut
,wMode
);
302 /***********************************************************************
303 * ICGetDisplayFormat [MSVFW32.@]
305 HIC VFWAPI
ICGetDisplayFormat(
306 HIC hic
,LPBITMAPINFOHEADER lpbiIn
,LPBITMAPINFOHEADER lpbiOut
,
307 INT depth
,INT dx
,INT dy
)
311 FIXME("(%p,%p,%p,%d,%d,%d),stub!\n",hic
,lpbiIn
,lpbiOut
,depth
,dx
,dy
);
313 tmphic
=ICLocate(ICTYPE_VIDEO
,0,lpbiIn
,NULL
,ICMODE_DECOMPRESS
);
317 if ((dy
== lpbiIn
->biHeight
) && (dx
== lpbiIn
->biWidth
))
318 dy
= dx
= 0; /* no resize needed */
320 /* Can we decompress it ? */
321 if (ICDecompressQuery(tmphic
,lpbiIn
,NULL
) != 0)
322 goto errout
; /* no, sorry */
324 ICDecompressGetFormat(tmphic
,lpbiIn
,lpbiOut
);
326 if (lpbiOut
->biCompression
!= 0) {
327 FIXME("Ooch, how come decompressor outputs compressed data (%ld)??\n",
328 lpbiOut
->biCompression
);
330 if (lpbiOut
->biSize
< sizeof(*lpbiOut
)) {
331 FIXME("Ooch, size of output BIH is too small (%ld)\n",
333 lpbiOut
->biSize
= sizeof(*lpbiOut
);
339 depth
= GetDeviceCaps(hdc
,BITSPIXEL
)*GetDeviceCaps(hdc
,PLANES
);
341 if (depth
==15) depth
= 16;
342 if (depth
<8) depth
= 8;
344 if (lpbiIn
->biBitCount
== 8)
347 TRACE("=> %p\n", tmphic
);
357 /***********************************************************************
358 * ICCompress [MSVFW32.@]
362 HIC hic
,DWORD dwFlags
,LPBITMAPINFOHEADER lpbiOutput
,LPVOID lpData
,
363 LPBITMAPINFOHEADER lpbiInput
,LPVOID lpBits
,LPDWORD lpckid
,
364 LPDWORD lpdwFlags
,LONG lFrameNum
,DWORD dwFrameSize
,DWORD dwQuality
,
365 LPBITMAPINFOHEADER lpbiPrev
,LPVOID lpPrev
)
369 TRACE("(%p,%ld,%p,%p,%p,%p,...)\n",hic
,dwFlags
,lpbiOutput
,lpData
,lpbiInput
,lpBits
);
371 iccmp
.dwFlags
= dwFlags
;
373 iccmp
.lpbiOutput
= lpbiOutput
;
374 iccmp
.lpOutput
= lpData
;
375 iccmp
.lpbiInput
= lpbiInput
;
376 iccmp
.lpInput
= lpBits
;
378 iccmp
.lpckid
= lpckid
;
379 iccmp
.lpdwFlags
= lpdwFlags
;
380 iccmp
.lFrameNum
= lFrameNum
;
381 iccmp
.dwFrameSize
= dwFrameSize
;
382 iccmp
.dwQuality
= dwQuality
;
383 iccmp
.lpbiPrev
= lpbiPrev
;
384 iccmp
.lpPrev
= lpPrev
;
385 return ICSendMessage(hic
,ICM_COMPRESS
,(DWORD
)&iccmp
,sizeof(iccmp
));
388 /***********************************************************************
389 * ICDecompress [MSVFW32.@]
391 DWORD VFWAPIV
ICDecompress(HIC hic
,DWORD dwFlags
,LPBITMAPINFOHEADER lpbiFormat
,
392 LPVOID lpData
,LPBITMAPINFOHEADER lpbi
,LPVOID lpBits
)
397 TRACE("(%p,%ld,%p,%p,%p,%p)\n",hic
,dwFlags
,lpbiFormat
,lpData
,lpbi
,lpBits
);
399 TRACE("lpBits[0] == %ld\n",((LPDWORD
)lpBits
)[0]);
401 icd
.dwFlags
= dwFlags
;
402 icd
.lpbiInput
= lpbiFormat
;
403 icd
.lpInput
= lpData
;
405 icd
.lpbiOutput
= lpbi
;
406 icd
.lpOutput
= lpBits
;
408 ret
= ICSendMessage(hic
,ICM_DECOMPRESS
,(DWORD
)&icd
,sizeof(ICDECOMPRESS
));
410 TRACE("lpBits[0] == %ld\n",((LPDWORD
)lpBits
)[0]);
412 TRACE("-> %ld\n",ret
);
417 /******************************************************************
418 * MSVIDEO_SendMessage
422 LRESULT
MSVIDEO_SendMessage(HIC hic
,UINT msg
,DWORD lParam1
,DWORD lParam2
)
425 WINE_HIC
* whic
= GlobalLock16(HIC_16(hic
));
427 #define XX(x) case x: TRACE("(%p,"#x",0x%08lx,0x%08lx)\n",hic,lParam1,lParam2);break;
442 XX(ICM_GETDEFAULTQUALITY
);
449 XX(ICM_COMPRESS_FRAMES_INFO
);
450 XX(ICM_COMPRESS_GET_FORMAT
);
451 XX(ICM_COMPRESS_GET_SIZE
);
452 XX(ICM_COMPRESS_QUERY
);
453 XX(ICM_COMPRESS_BEGIN
);
455 XX(ICM_COMPRESS_END
);
456 XX(ICM_DECOMPRESS_GET_FORMAT
);
457 XX(ICM_DECOMPRESS_QUERY
);
458 XX(ICM_DECOMPRESS_BEGIN
);
460 XX(ICM_DECOMPRESS_END
);
461 XX(ICM_DECOMPRESS_SET_PALETTE
);
462 XX(ICM_DECOMPRESS_GET_PALETTE
);
465 XX(ICM_DRAW_GET_PALETTE
);
469 XX(ICM_DRAW_GETTIME
);
472 XX(ICM_DRAW_SETTIME
);
473 XX(ICM_DRAW_REALIZE
);
475 XX(ICM_DRAW_RENDERBUFFER
);
476 XX(ICM_DRAW_START_PLAY
);
477 XX(ICM_DRAW_STOP_PLAY
);
478 XX(ICM_DRAW_SUGGESTFORMAT
);
479 XX(ICM_DRAW_CHANGEPALETTE
);
480 XX(ICM_GETBUFFERSWANTED
);
481 XX(ICM_GETDEFAULTKEYFRAMERATE
);
482 XX(ICM_DECOMPRESSEX_BEGIN
);
483 XX(ICM_DECOMPRESSEX_QUERY
);
484 XX(ICM_DECOMPRESSEX
);
485 XX(ICM_DECOMPRESSEX_END
);
486 XX(ICM_SET_STATUS_PROC
);
488 FIXME("(%p,0x%08lx,0x%08lx,0x%08lx) unknown message\n",hic
,(DWORD
)msg
,lParam1
,lParam2
);
493 if (!whic
) return ICERR_BADHANDLE
;
495 if (whic
->driverproc
) {
496 ret
= whic
->driverproc((DWORD
)hic
, whic
->hdrv
, msg
, lParam1
, lParam2
);
498 ret
= SendDriverMessage(whic
->hdrv
, msg
, lParam1
, lParam2
);
501 GlobalUnlock16(HIC_16(hic
));
503 TRACE(" -> 0x%08lx\n",ret
);
507 /***********************************************************************
508 * ICSendMessage [MSVFW32.@]
510 LRESULT VFWAPI
ICSendMessage(HIC hic
, UINT msg
, DWORD lParam1
, DWORD lParam2
) {
511 return MSVIDEO_SendMessage(hic
,msg
,lParam1
,lParam2
);
514 /***********************************************************************
515 * ICDrawBegin [MSVFW32.@]
517 DWORD VFWAPIV
ICDrawBegin(
519 DWORD dwFlags
, /* [in] flags */
520 HPALETTE hpal
, /* [in] palette to draw with */
521 HWND hwnd
, /* [in] window to draw to */
522 HDC hdc
, /* [in] HDC to draw to */
523 INT xDst
, /* [in] destination rectangle */
525 INT dxDst
, /* [in] */
526 INT dyDst
, /* [in] */
527 LPBITMAPINFOHEADER lpbi
, /* [in] format of frame to draw */
528 INT xSrc
, /* [in] source rectangle */
530 INT dxSrc
, /* [in] */
531 INT dySrc
, /* [in] */
532 DWORD dwRate
, /* [in] frames/second = (dwRate/dwScale) */
533 DWORD dwScale
) /* [in] */
538 TRACE("(%p,%ld,%p,%p,%p,%u,%u,%u,%u,%p,%u,%u,%u,%u,%ld,%ld)\n",
539 hic
, dwFlags
, hpal
, hwnd
, hdc
, xDst
, yDst
, dxDst
, dyDst
,
540 lpbi
, xSrc
, ySrc
, dxSrc
, dySrc
, dwRate
, dwScale
);
542 icdb
.dwFlags
= dwFlags
;
555 icdb
.dwRate
= dwRate
;
556 icdb
.dwScale
= dwScale
;
557 return ICSendMessage(hic
,ICM_DRAW_BEGIN
,(DWORD
)&icdb
,sizeof(icdb
));
560 /***********************************************************************
563 DWORD VFWAPIV
ICDraw(HIC hic
, DWORD dwFlags
, LPVOID lpFormat
, LPVOID lpData
, DWORD cbData
, LONG lTime
) {
566 TRACE("(%p,%ld,%p,%p,%ld,%ld)\n",hic
,dwFlags
,lpFormat
,lpData
,cbData
,lTime
);
568 icd
.dwFlags
= dwFlags
;
569 icd
.lpFormat
= lpFormat
;
574 return ICSendMessage(hic
,ICM_DRAW
,(DWORD
)&icd
,sizeof(icd
));
577 /***********************************************************************
578 * ICClose [MSVFW32.@]
580 LRESULT WINAPI
ICClose(HIC hic
) {
581 WINE_HIC
*whic
= GlobalLock16(HIC_16(hic
));
583 if (whic
->driverproc
) {
584 ICSendMessage(hic
,DRV_CLOSE
,0,0);
585 ICSendMessage(hic
,DRV_DISABLE
,0,0);
586 ICSendMessage(hic
,DRV_FREE
,0,0);
588 CloseDriver(whic
->hdrv
,0,0);
591 GlobalUnlock16(HIC_16(hic
));
592 GlobalFree16(HIC_16(hic
));
598 /***********************************************************************
599 * ICImageCompress [MSVFW32.@]
601 HANDLE VFWAPI
ICImageCompress(
602 HIC hic
, UINT uiFlags
,
603 LPBITMAPINFO lpbiIn
, LPVOID lpBits
,
604 LPBITMAPINFO lpbiOut
, LONG lQuality
,
607 FIXME("(%p,%08x,%p,%p,%p,%ld,%p)\n",
608 hic
, uiFlags
, lpbiIn
, lpBits
, lpbiOut
, lQuality
, plSize
);
613 /***********************************************************************
614 * ICImageDecompress [MSVFW32.@]
617 HANDLE VFWAPI
ICImageDecompress(
618 HIC hic
, UINT uiFlags
, LPBITMAPINFO lpbiIn
,
619 LPVOID lpBits
, LPBITMAPINFO lpbiOut
)
621 HGLOBAL hMem
= (HGLOBAL
)NULL
;
623 BOOL bReleaseIC
= FALSE
;
626 BOOL bSucceeded
= FALSE
;
627 BOOL bInDecompress
= FALSE
;
630 TRACE("(%p,%08x,%p,%p,%p)\n",
631 hic
, uiFlags
, lpbiIn
, lpBits
, lpbiOut
);
633 if ( hic
== (HIC
)NULL
)
635 hic
= ICDecompressOpen( mmioFOURCC('V','I','D','C'), 0, &lpbiIn
->bmiHeader
, (lpbiOut
!= NULL
) ? &lpbiOut
->bmiHeader
: NULL
);
636 if ( hic
== (HIC
)NULL
)
638 WARN("no handler\n" );
645 FIXME( "unknown flag %08x\n", uiFlags
);
648 if ( lpbiIn
== NULL
|| lpBits
== NULL
)
650 WARN("invalid argument\n");
654 if ( lpbiOut
!= NULL
)
656 if ( lpbiOut
->bmiHeader
.biSize
!= sizeof(BITMAPINFOHEADER
) )
658 cbHdr
= sizeof(BITMAPINFOHEADER
);
659 if ( lpbiOut
->bmiHeader
.biCompression
== 3 )
660 cbHdr
+= sizeof(DWORD
)*3;
662 if ( lpbiOut
->bmiHeader
.biBitCount
<= 8 )
664 if ( lpbiOut
->bmiHeader
.biClrUsed
== 0 )
665 cbHdr
+= sizeof(RGBQUAD
) * (1<<lpbiOut
->bmiHeader
.biBitCount
);
667 cbHdr
+= sizeof(RGBQUAD
) * lpbiOut
->bmiHeader
.biClrUsed
;
672 TRACE( "get format\n" );
674 cbHdr
= ICDecompressGetFormatSize(hic
,lpbiIn
);
675 if ( cbHdr
< sizeof(BITMAPINFOHEADER
) )
677 pHdr
= (BYTE
*)HeapAlloc(GetProcessHeap(),0,cbHdr
+sizeof(RGBQUAD
)*256);
680 ZeroMemory( pHdr
, cbHdr
+sizeof(RGBQUAD
)*256 );
681 if ( ICDecompressGetFormat( hic
, lpbiIn
, (BITMAPINFO
*)pHdr
) != ICERR_OK
)
683 lpbiOut
= (BITMAPINFO
*)pHdr
;
684 if ( lpbiOut
->bmiHeader
.biBitCount
<= 8 &&
685 ICDecompressGetPalette( hic
, lpbiIn
, lpbiOut
) != ICERR_OK
&&
686 lpbiIn
->bmiHeader
.biBitCount
== lpbiOut
->bmiHeader
.biBitCount
)
688 if ( lpbiIn
->bmiHeader
.biClrUsed
== 0 )
689 memcpy( lpbiOut
->bmiColors
, lpbiIn
->bmiColors
, sizeof(RGBQUAD
)*(1<<lpbiOut
->bmiHeader
.biBitCount
) );
691 memcpy( lpbiOut
->bmiColors
, lpbiIn
->bmiColors
, sizeof(RGBQUAD
)*lpbiIn
->bmiHeader
.biClrUsed
);
693 if ( lpbiOut
->bmiHeader
.biBitCount
<= 8 &&
694 lpbiOut
->bmiHeader
.biClrUsed
== 0 )
695 lpbiOut
->bmiHeader
.biClrUsed
= 1<<lpbiOut
->bmiHeader
.biBitCount
;
697 lpbiOut
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
698 cbHdr
= sizeof(BITMAPINFOHEADER
) + sizeof(RGBQUAD
)*lpbiOut
->bmiHeader
.biClrUsed
;
701 biSizeImage
= lpbiOut
->bmiHeader
.biSizeImage
;
702 if ( biSizeImage
== 0 )
703 biSizeImage
= ((((lpbiOut
->bmiHeader
.biWidth
* lpbiOut
->bmiHeader
.biBitCount
+ 7) >> 3) + 3) & (~3)) * abs(lpbiOut
->bmiHeader
.biHeight
);
705 TRACE( "call ICDecompressBegin\n" );
707 if ( ICDecompressBegin( hic
, lpbiIn
, lpbiOut
) != ICERR_OK
)
709 bInDecompress
= TRUE
;
711 TRACE( "cbHdr %ld, biSizeImage %ld\n", cbHdr
, biSizeImage
);
713 hMem
= GlobalAlloc( GMEM_MOVEABLE
|GMEM_ZEROINIT
, cbHdr
+ biSizeImage
);
714 if ( hMem
== (HGLOBAL
)NULL
)
716 WARN( "out of memory\n" );
719 pMem
= (BYTE
*)GlobalLock( hMem
);
722 memcpy( pMem
, lpbiOut
, cbHdr
);
724 TRACE( "call ICDecompress\n" );
725 if ( ICDecompress( hic
, 0, &lpbiIn
->bmiHeader
, lpBits
, &lpbiOut
->bmiHeader
, pMem
+cbHdr
) != ICERR_OK
)
731 ICDecompressEnd( hic
);
735 HeapFree(GetProcessHeap(),0,pHdr
);
737 GlobalUnlock( hMem
);
738 if ( !bSucceeded
&& hMem
!= (HGLOBAL
)NULL
)
740 GlobalFree(hMem
); hMem
= (HGLOBAL
)NULL
;