[6386] | 1 | /*
|
---|
| 2 | * Copyright 1998 Marcus Meissner
|
---|
[9140] | 3 | * Copyright 2000 Bradley Baetz
|
---|
[6386] | 4 | *
|
---|
[9140] | 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.
|
---|
| 9 | *
|
---|
| 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.
|
---|
| 14 | *
|
---|
| 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
|
---|
| 18 | *
|
---|
[6386] | 19 | * FIXME: This all assumes 32 bit codecs
|
---|
[6712] | 20 | * Win95 appears to prefer 32 bit codecs, even from 16 bit code.
|
---|
| 21 | * There is the ICOpenFunction16 to worry about still, though.
|
---|
[6386] | 22 | */
|
---|
| 23 |
|
---|
| 24 | #include <stdio.h>
|
---|
| 25 | #include <string.h>
|
---|
| 26 |
|
---|
| 27 | #include "winbase.h"
|
---|
| 28 | #include "windef.h"
|
---|
| 29 | #include "winnls.h"
|
---|
| 30 | #include "wingdi.h"
|
---|
| 31 | #include "winuser.h"
|
---|
| 32 | #include "winver.h"
|
---|
| 33 | #include "vfw.h"
|
---|
| 34 | #include "vfw16.h"
|
---|
| 35 | #include "wine/winbase16.h"
|
---|
[9140] | 36 | #include "wine/debug.h"
|
---|
[6386] | 37 | #include "stackframe.h"
|
---|
| 38 |
|
---|
[9140] | 39 | WINE_DEFAULT_DEBUG_CHANNEL(msvideo);
|
---|
[6386] | 40 |
|
---|
| 41 | #ifdef __WIN32OS2__
|
---|
[9140] | 42 | #define MSVIDEO_CallTo16_long_lwwll(a,b,c,d,e,f) 0
|
---|
| 43 | #else
|
---|
[6386] | 44 | /* ### start build ### */
|
---|
| 45 | extern LONG CALLBACK MSVIDEO_CallTo16_long_lwwll(FARPROC16,LONG,WORD,WORD,LONG,LONG);
|
---|
| 46 | /* ### stop build ### */
|
---|
[9140] | 47 | #endif
|
---|
[6386] | 48 |
|
---|
| 49 | LPVOID MSVIDEO_MapMsg16To32(UINT msg, LPDWORD lParam1, LPDWORD lParam2);
|
---|
| 50 | void MSVIDEO_UnmapMsg16To32(UINT msg, LPVOID lpv, LPDWORD lParam1, LPDWORD lParam2);
|
---|
| 51 | LRESULT MSVIDEO_SendMessage(HIC hic, UINT msg, DWORD lParam1, DWORD lParam2, BOOL bFrom32);
|
---|
| 52 |
|
---|
[9140] | 53 | #define HDRVR_16(h32) (LOWORD(h32))
|
---|
| 54 |
|
---|
| 55 |
|
---|
[6386] | 56 | /***********************************************************************
|
---|
[6712] | 57 | * VideoForWindowsVersion [MSVFW32.2]
|
---|
| 58 | * VideoForWindowsVersion [MSVIDEO.2]
|
---|
[6386] | 59 | * Returns the version in major.minor form.
|
---|
| 60 | * In Windows95 this returns 0x040003b6 (4.950)
|
---|
| 61 | */
|
---|
| 62 | DWORD WINAPI VideoForWindowsVersion(void) {
|
---|
[6712] | 63 | return 0x040003B6; /* 4.950 */
|
---|
[6386] | 64 | }
|
---|
| 65 |
|
---|
| 66 | /***********************************************************************
|
---|
[6712] | 67 | * VideoCapDriverDescAndVer [MSVIDEO.22]
|
---|
[6386] | 68 | */
|
---|
| 69 | DWORD WINAPI VideoCapDriverDescAndVer(
|
---|
[6712] | 70 | WORD nr,LPSTR buf1,WORD buf1len,LPSTR buf2,WORD buf2len
|
---|
[6386] | 71 | ) {
|
---|
[6712] | 72 | DWORD verhandle;
|
---|
| 73 | WORD xnr = nr;
|
---|
| 74 | DWORD infosize;
|
---|
| 75 | UINT subblocklen;
|
---|
| 76 | char *s,buf[2000],fn[260];
|
---|
| 77 | LPBYTE infobuf;
|
---|
| 78 | LPVOID subblock;
|
---|
[6386] | 79 |
|
---|
[6712] | 80 | TRACE("(%d,%p,%d,%p,%d)\n",nr,buf1,buf1len,buf2,buf2len);
|
---|
| 81 | if (GetPrivateProfileStringA("drivers32",NULL,NULL,buf,sizeof(buf),"system.ini")) {
|
---|
| 82 | s = buf;
|
---|
| 83 | while (*s) {
|
---|
| 84 | if (!strncasecmp(s,"vid",3)) {
|
---|
| 85 | if (!xnr)
|
---|
| 86 | break;
|
---|
| 87 | xnr--;
|
---|
| 88 | }
|
---|
| 89 | s=s+strlen(s)+1; /* either next char or \0 */
|
---|
| 90 | }
|
---|
| 91 | } else
|
---|
| 92 | return 20; /* hmm, out of entries even if we don't have any */
|
---|
| 93 | if (xnr) {
|
---|
| 94 | FIXME("No more VID* entries found\n");
|
---|
| 95 | return 20;
|
---|
| 96 | }
|
---|
| 97 | GetPrivateProfileStringA("drivers32",s,NULL,fn,sizeof(fn),"system.ini");
|
---|
| 98 | infosize = GetFileVersionInfoSizeA(fn,&verhandle);
|
---|
| 99 | if (!infosize) {
|
---|
| 100 | TRACE("%s has no fileversioninfo.\n",fn);
|
---|
| 101 | return 18;
|
---|
| 102 | }
|
---|
| 103 | infobuf = HeapAlloc(GetProcessHeap(),0,infosize);
|
---|
| 104 | if (GetFileVersionInfoA(fn,verhandle,infosize,infobuf)) {
|
---|
| 105 | char vbuf[200];
|
---|
| 106 | /* Yes, two space behind : */
|
---|
| 107 | /* FIXME: test for buflen */
|
---|
| 108 | sprintf(vbuf,"Version: %d.%d.%d.%d\n",
|
---|
| 109 | ((WORD*)infobuf)[0x0f],
|
---|
| 110 | ((WORD*)infobuf)[0x0e],
|
---|
| 111 | ((WORD*)infobuf)[0x11],
|
---|
| 112 | ((WORD*)infobuf)[0x10]
|
---|
| 113 | );
|
---|
| 114 | TRACE("version of %s is %s\n",fn,vbuf);
|
---|
| 115 | strncpy(buf2,vbuf,buf2len);
|
---|
| 116 | } else {
|
---|
| 117 | TRACE("GetFileVersionInfoA failed for %s.\n",fn);
|
---|
| 118 | strncpy(buf2,fn,buf2len); /* msvideo.dll appears to copy fn*/
|
---|
| 119 | }
|
---|
| 120 | /* FIXME: language problem? */
|
---|
| 121 | if (VerQueryValueA( infobuf,
|
---|
| 122 | "\\StringFileInfo\\040904E4\\FileDescription",
|
---|
| 123 | &subblock,
|
---|
| 124 | &subblocklen
|
---|
| 125 | )) {
|
---|
| 126 | TRACE("VQA returned %s\n",(LPCSTR)subblock);
|
---|
| 127 | strncpy(buf1,subblock,buf1len);
|
---|
| 128 | } else {
|
---|
| 129 | TRACE("VQA did not return on query \\StringFileInfo\\040904E4\\FileDescription?\n");
|
---|
| 130 | strncpy(buf1,fn,buf1len); /* msvideo.dll appears to copy fn*/
|
---|
| 131 | }
|
---|
| 132 | HeapFree(GetProcessHeap(),0,infobuf);
|
---|
| 133 | return 0;
|
---|
[6386] | 134 | }
|
---|
| 135 |
|
---|
| 136 | /* system.ini: [drivers] */
|
---|
| 137 |
|
---|
| 138 | /***********************************************************************
|
---|
[6712] | 139 | * ICInfo [MSVFW32.@]
|
---|
[6386] | 140 | * Get information about an installable compressor. Return TRUE if there
|
---|
| 141 | * is one.
|
---|
| 142 | */
|
---|
| 143 | BOOL VFWAPI ICInfo(
|
---|
[6712] | 144 | DWORD fccType, /* [in] type of compressor ('vidc') */
|
---|
| 145 | DWORD fccHandler, /* [in] <n>th compressor */
|
---|
| 146 | ICINFO *lpicinfo) /* [out] information about compressor */
|
---|
[6386] | 147 | {
|
---|
[6712] | 148 | char type[5],buf[2000];
|
---|
[6386] | 149 |
|
---|
[6712] | 150 | memcpy(type,&fccType,4);type[4]=0;
|
---|
| 151 | TRACE("(%s,%ld,%p).\n",type,fccHandler,lpicinfo);
|
---|
| 152 | /* does OpenDriver/CloseDriver */
|
---|
| 153 | lpicinfo->dwSize = sizeof(ICINFO);
|
---|
| 154 | lpicinfo->fccType = fccType;
|
---|
| 155 | lpicinfo->dwFlags = 0;
|
---|
| 156 | if (GetPrivateProfileStringA("drivers32",NULL,NULL,buf,2000,"system.ini")) {
|
---|
| 157 | char *s = buf;
|
---|
| 158 | while (*s) {
|
---|
| 159 | if (!strncasecmp(type,s,4)) {
|
---|
| 160 | if(!fccHandler--) {
|
---|
| 161 | lpicinfo->fccHandler = mmioStringToFOURCCA(s+5,0);
|
---|
| 162 | return TRUE;
|
---|
| 163 | }
|
---|
| 164 | }
|
---|
| 165 | s=s+strlen(s)+1; /* either next char or \0 */
|
---|
| 166 | }
|
---|
| 167 | }
|
---|
| 168 | return FALSE;
|
---|
[6386] | 169 | }
|
---|
[9140] | 170 |
|
---|
[6386] | 171 | /***********************************************************************
|
---|
[6712] | 172 | * ICInfo [MSVIDEO.200]
|
---|
[6386] | 173 | */
|
---|
| 174 | BOOL16 VFWAPI ICInfo16(
|
---|
[6712] | 175 | DWORD fccType, /* [in] */
|
---|
| 176 | DWORD fccHandler, /* [in] */
|
---|
| 177 | ICINFO16 *lpicinfo) /* [in/out] NOTE: SEGPTR */
|
---|
[6386] | 178 | {
|
---|
[6712] | 179 | BOOL16 ret;
|
---|
| 180 | LPVOID lpv;
|
---|
| 181 | DWORD lParam = (DWORD)lpicinfo;
|
---|
| 182 | DWORD size = ((ICINFO*)(MapSL((SEGPTR)lpicinfo)))->dwSize;
|
---|
[6386] | 183 |
|
---|
[6712] | 184 | /* Use the mapping functions to map the ICINFO structure */
|
---|
| 185 | lpv = MSVIDEO_MapMsg16To32(ICM_GETINFO,&lParam,&size);
|
---|
[6386] | 186 |
|
---|
[6712] | 187 | ret = ICInfo(fccType,fccHandler,(ICINFO*)lParam);
|
---|
[6386] | 188 |
|
---|
[6712] | 189 | MSVIDEO_UnmapMsg16To32(ICM_GETINFO,lpv,&lParam,&size);
|
---|
[9140] | 190 |
|
---|
[6712] | 191 | return ret;
|
---|
[6386] | 192 | }
|
---|
[9140] | 193 |
|
---|
[6386] | 194 | /***********************************************************************
|
---|
[6712] | 195 | * ICOpen [MSVFW32.@]
|
---|
[6386] | 196 | * Opens an installable compressor. Return special handle.
|
---|
| 197 | */
|
---|
| 198 | HIC VFWAPI ICOpen(DWORD fccType,DWORD fccHandler,UINT wMode) {
|
---|
[6712] | 199 | char type[5],handler[5],codecname[20];
|
---|
| 200 | ICOPEN icopen;
|
---|
| 201 | HDRVR hdrv;
|
---|
| 202 | HIC16 hic;
|
---|
| 203 | WINE_HIC *whic;
|
---|
[6386] | 204 |
|
---|
[6712] | 205 | memcpy(type,&fccType,4);type[4]=0;
|
---|
| 206 | memcpy(handler,&fccHandler,4);handler[4]=0;
|
---|
| 207 | TRACE("(%s,%s,0x%08lx)\n",type,handler,(DWORD)wMode);
|
---|
[6386] | 208 |
|
---|
[6712] | 209 | sprintf(codecname,"%s.%s",type,handler);
|
---|
[6386] | 210 |
|
---|
[9140] | 211 | /* Well, lParam2 is in fact a LPVIDEO_OPEN_PARMS, but it has the
|
---|
[6712] | 212 | * same layout as ICOPEN
|
---|
| 213 | */
|
---|
| 214 | icopen.fccType = fccType;
|
---|
| 215 | icopen.fccHandler = fccHandler;
|
---|
| 216 | icopen.dwSize = sizeof(ICOPEN);
|
---|
| 217 | icopen.dwFlags = wMode;
|
---|
| 218 | /* FIXME: do we need to fill out the rest too? */
|
---|
| 219 | hdrv=OpenDriverA(codecname,"drivers32",(LPARAM)&icopen);
|
---|
| 220 | if (!hdrv) {
|
---|
| 221 | if (!strcasecmp(type,"vids")) {
|
---|
| 222 | sprintf(codecname,"vidc.%s",handler);
|
---|
| 223 | fccType = mmioFOURCC('v','i','d','c');
|
---|
| 224 | }
|
---|
| 225 | hdrv=OpenDriverA(codecname,"drivers32",(LPARAM)&icopen);
|
---|
| 226 | if (!hdrv)
|
---|
| 227 | return 0;
|
---|
| 228 | }
|
---|
| 229 | /* The handle should be a valid 16-bit handle as well */
|
---|
| 230 | hic = GlobalAlloc16(GHND,sizeof(WINE_HIC));
|
---|
| 231 | whic = (WINE_HIC*)GlobalLock16(hic);
|
---|
| 232 | whic->hdrv = hdrv;
|
---|
| 233 | whic->driverproc= NULL;
|
---|
[6386] | 234 | #ifdef __WIN32OS2__
|
---|
[6712] | 235 | whic->privatevfw = 0;
|
---|
[6386] | 236 | #else
|
---|
[6712] | 237 | whic->private = 0;
|
---|
[6386] | 238 | #endif
|
---|
[6712] | 239 | GlobalUnlock16(hic);
|
---|
| 240 | TRACE("=> 0x%08lx\n",(DWORD)hic);
|
---|
| 241 | return hic;
|
---|
[6386] | 242 | }
|
---|
| 243 |
|
---|
| 244 | HIC MSVIDEO_OpenFunc(DWORD fccType, DWORD fccHandler, UINT wMode, FARPROC lpfnHandler, BOOL bFrom32) {
|
---|
[6712] | 245 | char type[5],handler[5],codecname[20];
|
---|
| 246 | HIC16 hic;
|
---|
[9140] | 247 | ICOPEN icopen;
|
---|
| 248 | SEGPTR seg_icopen;
|
---|
[6712] | 249 | WINE_HIC *whic;
|
---|
[6386] | 250 |
|
---|
[6712] | 251 | memcpy(type,&fccType,4);type[4]=0;
|
---|
| 252 | memcpy(handler,&fccHandler,4);handler[4]=0;
|
---|
| 253 | TRACE("(%s,%s,%d,%p,%d)\n",type,handler,wMode,lpfnHandler,bFrom32?32:16);
|
---|
[6386] | 254 |
|
---|
[9140] | 255 | icopen.fccType = fccType;
|
---|
| 256 | icopen.fccHandler = fccHandler;
|
---|
| 257 | icopen.dwSize = sizeof(ICOPEN);
|
---|
| 258 | icopen.dwFlags = wMode;
|
---|
| 259 |
|
---|
| 260 | sprintf(codecname,"%s.%s",type,handler);
|
---|
| 261 |
|
---|
[6712] | 262 | hic = GlobalAlloc16(GHND,sizeof(WINE_HIC));
|
---|
| 263 | if (!hic)
|
---|
| 264 | return 0;
|
---|
| 265 | whic = GlobalLock16(hic);
|
---|
| 266 | whic->driverproc = lpfnHandler;
|
---|
[9140] | 267 |
|
---|
[6386] | 268 | #ifdef __WIN32OS2__
|
---|
[6712] | 269 | whic->privatevfw = bFrom32;
|
---|
[6386] | 270 | #else
|
---|
[6712] | 271 | whic->private = bFrom32;
|
---|
[6386] | 272 | #endif
|
---|
[6712] | 273 | /* Now try opening/loading the driver. Taken from DRIVER_AddToList */
|
---|
| 274 | /* What if the function is used more than once? */
|
---|
[9140] | 275 |
|
---|
[6712] | 276 | if (MSVIDEO_SendMessage(hic,DRV_LOAD,0L,0L,bFrom32) != DRV_SUCCESS) {
|
---|
| 277 | WARN("DRV_LOAD failed for hic 0x%08lx\n",(DWORD)hic);
|
---|
| 278 | GlobalFree16(hic);
|
---|
| 279 | return 0;
|
---|
| 280 | }
|
---|
| 281 | /* return value is not checked */
|
---|
| 282 | MSVIDEO_SendMessage(hic,DRV_ENABLE,0L,0L,bFrom32);
|
---|
[6386] | 283 |
|
---|
[9140] | 284 | seg_icopen = MapLS( &icopen );
|
---|
| 285 | whic->hdrv = (HDRVR)MSVIDEO_SendMessage(hic,DRV_OPEN,0,seg_icopen,FALSE);
|
---|
| 286 | UnMapLS( seg_icopen );
|
---|
[6712] | 287 | if (whic->hdrv == 0) {
|
---|
| 288 | WARN("DRV_OPEN failed for hic 0x%08lx\n",(DWORD)hic);
|
---|
| 289 | GlobalFree16(hic);
|
---|
| 290 | return 0;
|
---|
| 291 | }
|
---|
[6386] | 292 |
|
---|
[6712] | 293 | GlobalUnlock16(hic);
|
---|
| 294 | TRACE("=> 0x%08lx\n",(DWORD)hic);
|
---|
| 295 | return hic;
|
---|
[6386] | 296 | }
|
---|
| 297 |
|
---|
| 298 | /***********************************************************************
|
---|
[6712] | 299 | * ICOpenFunction [MSVFW32.@]
|
---|
[6386] | 300 | */
|
---|
| 301 | HIC VFWAPI ICOpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, FARPROC lpfnHandler) {
|
---|
[6712] | 302 | return MSVIDEO_OpenFunc(fccType,fccHandler,wMode,lpfnHandler,TRUE);
|
---|
[6386] | 303 | }
|
---|
| 304 |
|
---|
| 305 | /***********************************************************************
|
---|
[6712] | 306 | * ICOpenFunction [MSVIDEO.206]
|
---|
[6386] | 307 | */
|
---|
| 308 | HIC16 VFWAPI ICOpenFunction16(DWORD fccType, DWORD fccHandler, UINT16 wMode, FARPROC16 lpfnHandler)
|
---|
| 309 | {
|
---|
[6712] | 310 | return MSVIDEO_OpenFunc(fccType, fccHandler, wMode, (FARPROC)lpfnHandler,FALSE);
|
---|
[6386] | 311 | }
|
---|
| 312 |
|
---|
| 313 | /***********************************************************************
|
---|
[6712] | 314 | * ICGetInfo [MSVFW32.@]
|
---|
[6386] | 315 | */
|
---|
| 316 | LRESULT VFWAPI ICGetInfo(HIC hic,ICINFO *picinfo,DWORD cb) {
|
---|
[6712] | 317 | LRESULT ret;
|
---|
[6386] | 318 |
|
---|
[6712] | 319 | TRACE("(0x%08lx,%p,%ld)\n",(DWORD)hic,picinfo,cb);
|
---|
| 320 | ret = ICSendMessage(hic,ICM_GETINFO,(DWORD)picinfo,cb);
|
---|
| 321 | TRACE(" -> 0x%08lx\n",ret);
|
---|
| 322 | return ret;
|
---|
[6386] | 323 | }
|
---|
| 324 |
|
---|
| 325 | /***********************************************************************
|
---|
[6712] | 326 | * ICLocate [MSVFW32.@]
|
---|
[6386] | 327 | */
|
---|
| 328 | HIC VFWAPI ICLocate(
|
---|
[6712] | 329 | DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn,
|
---|
| 330 | LPBITMAPINFOHEADER lpbiOut, WORD wMode)
|
---|
[6386] | 331 | {
|
---|
[6712] | 332 | char type[5],handler[5];
|
---|
| 333 | HIC hic;
|
---|
| 334 | DWORD querymsg;
|
---|
| 335 | LPSTR pszBuffer;
|
---|
[6386] | 336 |
|
---|
[6712] | 337 | type[4]=0;memcpy(type,&fccType,4);
|
---|
| 338 | handler[4]=0;memcpy(handler,&fccHandler,4);
|
---|
[6386] | 339 |
|
---|
[6712] | 340 | TRACE("(%s,%s,%p,%p,0x%04x)\n", type, handler, lpbiIn, lpbiOut, wMode);
|
---|
[6386] | 341 |
|
---|
[6712] | 342 | switch (wMode) {
|
---|
| 343 | case ICMODE_FASTCOMPRESS:
|
---|
[9140] | 344 | case ICMODE_COMPRESS:
|
---|
[6712] | 345 | querymsg = ICM_COMPRESS_QUERY;
|
---|
| 346 | break;
|
---|
| 347 | case ICMODE_FASTDECOMPRESS:
|
---|
| 348 | case ICMODE_DECOMPRESS:
|
---|
| 349 | querymsg = ICM_DECOMPRESS_QUERY;
|
---|
| 350 | break;
|
---|
| 351 | case ICMODE_DRAW:
|
---|
| 352 | querymsg = ICM_DRAW_QUERY;
|
---|
| 353 | break;
|
---|
| 354 | default:
|
---|
| 355 | WARN("Unknown mode (%d)\n",wMode);
|
---|
| 356 | return 0;
|
---|
| 357 | }
|
---|
[6386] | 358 |
|
---|
[6712] | 359 | /* Easy case: handler/type match, we just fire a query and return */
|
---|
| 360 | hic = ICOpen(fccType,fccHandler,wMode);
|
---|
| 361 | if (hic) {
|
---|
| 362 | if (!ICSendMessage(hic,querymsg,(DWORD)lpbiIn,(DWORD)lpbiOut))
|
---|
| 363 | return hic;
|
---|
| 364 | ICClose(hic);
|
---|
| 365 | }
|
---|
[6386] | 366 |
|
---|
[6712] | 367 | type[4]='.';memcpy(type,&fccType,4);
|
---|
| 368 | handler[4]='.';memcpy(handler,&fccHandler,4);
|
---|
[6386] | 369 |
|
---|
[6712] | 370 | /* Now try each driver in turn. 32 bit codecs only. */
|
---|
| 371 | /* FIXME: Move this to an init routine? */
|
---|
[9140] | 372 |
|
---|
[6712] | 373 | pszBuffer = (LPSTR)HeapAlloc(GetProcessHeap(),0,1024);
|
---|
| 374 | if (GetPrivateProfileSectionA("drivers32",pszBuffer,1024,"system.ini")) {
|
---|
| 375 | char* s = pszBuffer;
|
---|
| 376 | while (*s) {
|
---|
| 377 | if (!strncasecmp(type,s,5)) {
|
---|
| 378 | char *s2 = s;
|
---|
| 379 | while (*s2 != '\0' && *s2 != '.') s2++;
|
---|
| 380 | if (*s2++) {
|
---|
| 381 | HIC h;
|
---|
[6386] | 382 |
|
---|
[6712] | 383 | h = ICOpen(fccType,*(DWORD*)s2,wMode);
|
---|
| 384 | if (h) {
|
---|
| 385 | if (!ICSendMessage(h,querymsg,(DWORD)lpbiIn,(DWORD)lpbiOut))
|
---|
| 386 | return h;
|
---|
| 387 | ICClose(h);
|
---|
| 388 | }
|
---|
| 389 | }
|
---|
| 390 | }
|
---|
| 391 | s += strlen(s) + 1;
|
---|
| 392 | }
|
---|
| 393 | }
|
---|
| 394 | HeapFree(GetProcessHeap(),0,pszBuffer);
|
---|
[9140] | 395 |
|
---|
[6712] | 396 | if (fccType==streamtypeVIDEO) {
|
---|
| 397 | hic = ICLocate(ICTYPE_VIDEO,fccHandler,lpbiIn,lpbiOut,wMode);
|
---|
| 398 | if (hic)
|
---|
| 399 | return hic;
|
---|
| 400 | }
|
---|
[6386] | 401 |
|
---|
[6712] | 402 | type[4] = handler[4] = '\0';
|
---|
| 403 | WARN("(%.4s,%.4s,%p,%p,0x%04x) not found!\n",type,handler,lpbiIn,lpbiOut,wMode);
|
---|
| 404 | return 0;
|
---|
[6386] | 405 | }
|
---|
| 406 |
|
---|
| 407 | /***********************************************************************
|
---|
[6712] | 408 | * ICGetDisplayFormat [MSVFW32.@]
|
---|
[6386] | 409 | */
|
---|
| 410 | HIC VFWAPI ICGetDisplayFormat(
|
---|
[6712] | 411 | HIC hic,LPBITMAPINFOHEADER lpbiIn,LPBITMAPINFOHEADER lpbiOut,
|
---|
| 412 | INT depth,INT dx,INT dy)
|
---|
[6386] | 413 | {
|
---|
[9140] | 414 | HIC tmphic = hic;
|
---|
[6386] | 415 |
|
---|
[6712] | 416 | FIXME("(0x%08lx,%p,%p,%d,%d,%d),stub!\n",(DWORD)hic,lpbiIn,lpbiOut,depth,dx,dy);
|
---|
| 417 | if (!tmphic) {
|
---|
| 418 | tmphic=ICLocate(ICTYPE_VIDEO,0,lpbiIn,NULL,ICMODE_DECOMPRESS);
|
---|
| 419 | if (!tmphic)
|
---|
| 420 | return tmphic;
|
---|
| 421 | }
|
---|
| 422 | if ((dy == lpbiIn->biHeight) && (dx == lpbiIn->biWidth))
|
---|
| 423 | dy = dx = 0; /* no resize needed */
|
---|
[6386] | 424 |
|
---|
[6712] | 425 | /* Can we decompress it ? */
|
---|
| 426 | if (ICDecompressQuery(tmphic,lpbiIn,NULL) != 0)
|
---|
| 427 | goto errout; /* no, sorry */
|
---|
[6386] | 428 |
|
---|
[6712] | 429 | ICDecompressGetFormat(tmphic,lpbiIn,lpbiOut);
|
---|
[6386] | 430 |
|
---|
[6712] | 431 | if (lpbiOut->biCompression != 0) {
|
---|
| 432 | FIXME("Ooch, how come decompressor outputs compressed data (%ld)??\n",
|
---|
| 433 | lpbiOut->biCompression);
|
---|
| 434 | }
|
---|
| 435 | if (lpbiOut->biSize < sizeof(*lpbiOut)) {
|
---|
| 436 | FIXME("Ooch, size of output BIH is too small (%ld)\n",
|
---|
| 437 | lpbiOut->biSize);
|
---|
| 438 | lpbiOut->biSize = sizeof(*lpbiOut);
|
---|
| 439 | }
|
---|
| 440 | if (!depth) {
|
---|
| 441 | HDC hdc;
|
---|
[6386] | 442 |
|
---|
[6712] | 443 | hdc = GetDC(0);
|
---|
| 444 | depth = GetDeviceCaps(hdc,BITSPIXEL)*GetDeviceCaps(hdc,PLANES);
|
---|
| 445 | ReleaseDC(0,hdc);
|
---|
| 446 | if (depth==15) depth = 16;
|
---|
| 447 | if (depth<8) depth = 8;
|
---|
| 448 | }
|
---|
| 449 | if (lpbiIn->biBitCount == 8)
|
---|
| 450 | depth = 8;
|
---|
[9140] | 451 |
|
---|
[6712] | 452 | TRACE("=> 0x%08lx\n",(DWORD)tmphic);
|
---|
| 453 | return tmphic;
|
---|
[6386] | 454 | errout:
|
---|
[6712] | 455 | if (hic!=tmphic)
|
---|
| 456 | ICClose(tmphic);
|
---|
[6386] | 457 |
|
---|
[6712] | 458 | TRACE("=> 0\n");
|
---|
| 459 | return 0;
|
---|
[6386] | 460 | }
|
---|
| 461 |
|
---|
| 462 | /***********************************************************************
|
---|
[6712] | 463 | * ICCompress [MSVFW32.@]
|
---|
[6386] | 464 | */
|
---|
| 465 | DWORD VFWAPIV
|
---|
| 466 | ICCompress(
|
---|
[6712] | 467 | HIC hic,DWORD dwFlags,LPBITMAPINFOHEADER lpbiOutput,LPVOID lpData,
|
---|
| 468 | LPBITMAPINFOHEADER lpbiInput,LPVOID lpBits,LPDWORD lpckid,
|
---|
| 469 | LPDWORD lpdwFlags,LONG lFrameNum,DWORD dwFrameSize,DWORD dwQuality,
|
---|
| 470 | LPBITMAPINFOHEADER lpbiPrev,LPVOID lpPrev)
|
---|
[6386] | 471 | {
|
---|
[6712] | 472 | ICCOMPRESS iccmp;
|
---|
[6386] | 473 |
|
---|
[6712] | 474 | TRACE("(0x%08lx,%ld,%p,%p,%p,%p,...)\n",(DWORD)hic,dwFlags,lpbiOutput,lpData,lpbiInput,lpBits);
|
---|
[6386] | 475 |
|
---|
[6712] | 476 | iccmp.dwFlags = dwFlags;
|
---|
[6386] | 477 |
|
---|
[6712] | 478 | iccmp.lpbiOutput = lpbiOutput;
|
---|
| 479 | iccmp.lpOutput = lpData;
|
---|
| 480 | iccmp.lpbiInput = lpbiInput;
|
---|
| 481 | iccmp.lpInput = lpBits;
|
---|
[6386] | 482 |
|
---|
[6712] | 483 | iccmp.lpckid = lpckid;
|
---|
| 484 | iccmp.lpdwFlags = lpdwFlags;
|
---|
| 485 | iccmp.lFrameNum = lFrameNum;
|
---|
| 486 | iccmp.dwFrameSize = dwFrameSize;
|
---|
| 487 | iccmp.dwQuality = dwQuality;
|
---|
| 488 | iccmp.lpbiPrev = lpbiPrev;
|
---|
| 489 | iccmp.lpPrev = lpPrev;
|
---|
| 490 | return ICSendMessage(hic,ICM_COMPRESS,(DWORD)&iccmp,sizeof(iccmp));
|
---|
[6386] | 491 | }
|
---|
| 492 |
|
---|
| 493 | /***********************************************************************
|
---|
[6712] | 494 | * ICDecompress [MSVFW32.@]
|
---|
[6386] | 495 | */
|
---|
| 496 | DWORD VFWAPIV ICDecompress(HIC hic,DWORD dwFlags,LPBITMAPINFOHEADER lpbiFormat,
|
---|
[6712] | 497 | LPVOID lpData,LPBITMAPINFOHEADER lpbi,LPVOID lpBits)
|
---|
[6386] | 498 | {
|
---|
[6712] | 499 | ICDECOMPRESS icd;
|
---|
| 500 | DWORD ret;
|
---|
[6386] | 501 |
|
---|
[6712] | 502 | TRACE("(0x%08lx,%ld,%p,%p,%p,%p)\n",(DWORD)hic,dwFlags,lpbiFormat,lpData,lpbi,lpBits);
|
---|
[6386] | 503 |
|
---|
[6712] | 504 | TRACE("lpBits[0] == %ld\n",((LPDWORD)lpBits)[0]);
|
---|
[6386] | 505 |
|
---|
[6712] | 506 | icd.dwFlags = dwFlags;
|
---|
| 507 | icd.lpbiInput = lpbiFormat;
|
---|
| 508 | icd.lpInput = lpData;
|
---|
[6386] | 509 |
|
---|
[6712] | 510 | icd.lpbiOutput = lpbi;
|
---|
| 511 | icd.lpOutput = lpBits;
|
---|
| 512 | icd.ckid = 0;
|
---|
| 513 | ret = ICSendMessage(hic,ICM_DECOMPRESS,(DWORD)&icd,sizeof(ICDECOMPRESS));
|
---|
[6386] | 514 |
|
---|
[6712] | 515 | TRACE("lpBits[0] == %ld\n",((LPDWORD)lpBits)[0]);
|
---|
[6386] | 516 |
|
---|
[6712] | 517 | TRACE("-> %ld\n",ret);
|
---|
[6386] | 518 |
|
---|
[6712] | 519 | return ret;
|
---|
[6386] | 520 | }
|
---|
| 521 |
|
---|
| 522 | #define COPY(x,y) (x->y = x##16->y);
|
---|
| 523 | #define COPYPTR(x,y) (x->y = MapSL((SEGPTR)x##16->y));
|
---|
| 524 |
|
---|
| 525 | LPVOID MSVIDEO_MapICDEX16To32(LPDWORD lParam) {
|
---|
[6712] | 526 | LPVOID ret;
|
---|
[6386] | 527 |
|
---|
[6712] | 528 | ICDECOMPRESSEX *icdx = HeapAlloc(GetProcessHeap(),0,sizeof(ICDECOMPRESSEX));
|
---|
| 529 | ICDECOMPRESSEX16 *icdx16 = MapSL(*lParam);
|
---|
| 530 | ret = icdx16;
|
---|
[9140] | 531 |
|
---|
[6712] | 532 | COPY(icdx,dwFlags);
|
---|
| 533 | COPYPTR(icdx,lpbiSrc);
|
---|
| 534 | COPYPTR(icdx,lpSrc);
|
---|
| 535 | COPYPTR(icdx,lpbiDst);
|
---|
| 536 | COPYPTR(icdx,lpDst);
|
---|
| 537 | COPY(icdx,xDst);
|
---|
| 538 | COPY(icdx,yDst);
|
---|
| 539 | COPY(icdx,dxDst);
|
---|
| 540 | COPY(icdx,dyDst);
|
---|
| 541 | COPY(icdx,xSrc);
|
---|
| 542 | COPY(icdx,ySrc);
|
---|
| 543 | COPY(icdx,dxSrc);
|
---|
| 544 | COPY(icdx,dySrc);
|
---|
[9140] | 545 |
|
---|
[6712] | 546 | *lParam = (DWORD)(icdx);
|
---|
| 547 | return ret;
|
---|
[6386] | 548 | }
|
---|
| 549 |
|
---|
| 550 | LPVOID MSVIDEO_MapMsg16To32(UINT msg, LPDWORD lParam1, LPDWORD lParam2) {
|
---|
[6712] | 551 | LPVOID ret = 0;
|
---|
[9140] | 552 |
|
---|
[6712] | 553 | TRACE("Mapping %d\n",msg);
|
---|
[6386] | 554 |
|
---|
[6712] | 555 | switch (msg) {
|
---|
| 556 | case DRV_LOAD:
|
---|
| 557 | case DRV_ENABLE:
|
---|
| 558 | case DRV_CLOSE:
|
---|
| 559 | case DRV_DISABLE:
|
---|
| 560 | case DRV_FREE:
|
---|
| 561 | case ICM_ABOUT:
|
---|
| 562 | case ICM_CONFIGURE:
|
---|
| 563 | case ICM_COMPRESS_END:
|
---|
| 564 | case ICM_DECOMPRESS_END:
|
---|
| 565 | case ICM_DECOMPRESSEX_END:
|
---|
| 566 | case ICM_SETQUALITY:
|
---|
| 567 | case ICM_DRAW_START_PLAY:
|
---|
| 568 | case ICM_DRAW_STOP_PLAY:
|
---|
| 569 | case ICM_DRAW_REALIZE:
|
---|
| 570 | case ICM_DRAW_RENDERBUFFER:
|
---|
| 571 | case ICM_DRAW_END:
|
---|
| 572 | break;
|
---|
| 573 | case DRV_OPEN:
|
---|
| 574 | case ICM_GETDEFAULTQUALITY:
|
---|
| 575 | case ICM_GETQUALITY:
|
---|
| 576 | case ICM_SETSTATE:
|
---|
| 577 | case ICM_DRAW_WINDOW:
|
---|
| 578 | case ICM_GETBUFFERSWANTED:
|
---|
| 579 | *lParam1 = (DWORD)MapSL(*lParam1);
|
---|
| 580 | break;
|
---|
| 581 | case ICM_GETINFO:
|
---|
| 582 | {
|
---|
| 583 | ICINFO *ici = HeapAlloc(GetProcessHeap(),0,sizeof(ICINFO));
|
---|
| 584 | ICINFO16 *ici16;
|
---|
[6386] | 585 |
|
---|
[6712] | 586 | ici16 = MapSL(*lParam1);
|
---|
| 587 | ret = ici16;
|
---|
[6386] | 588 |
|
---|
[6712] | 589 | ici->dwSize = sizeof(ICINFO);
|
---|
| 590 | COPY(ici,fccType);
|
---|
| 591 | COPY(ici,fccHandler);
|
---|
| 592 | COPY(ici,dwFlags);
|
---|
| 593 | COPY(ici,dwVersion);
|
---|
| 594 | COPY(ici,dwVersionICM);
|
---|
[6386] | 595 | MultiByteToWideChar( CP_ACP, 0, ici16->szName, -1, ici->szName, 16 );
|
---|
| 596 | MultiByteToWideChar( CP_ACP, 0, ici16->szDescription, -1, ici->szDescription, 128 );
|
---|
| 597 | MultiByteToWideChar( CP_ACP, 0, ici16->szDriver, -1, ici->szDriver, 128 );
|
---|
[6712] | 598 | *lParam1 = (DWORD)(ici);
|
---|
| 599 | *lParam2 = sizeof(ICINFO);
|
---|
| 600 | }
|
---|
| 601 | break;
|
---|
| 602 | case ICM_COMPRESS:
|
---|
| 603 | {
|
---|
| 604 | ICCOMPRESS *icc = HeapAlloc(GetProcessHeap(),0,sizeof(ICCOMPRESS));
|
---|
| 605 | ICCOMPRESS *icc16;
|
---|
[6386] | 606 |
|
---|
[6712] | 607 | icc16 = MapSL(*lParam1);
|
---|
| 608 | ret = icc16;
|
---|
[6386] | 609 |
|
---|
[6712] | 610 | COPY(icc,dwFlags);
|
---|
| 611 | COPYPTR(icc,lpbiOutput);
|
---|
| 612 | COPYPTR(icc,lpOutput);
|
---|
| 613 | COPYPTR(icc,lpbiInput);
|
---|
| 614 | COPYPTR(icc,lpInput);
|
---|
| 615 | COPYPTR(icc,lpckid);
|
---|
| 616 | COPYPTR(icc,lpdwFlags);
|
---|
| 617 | COPY(icc,lFrameNum);
|
---|
| 618 | COPY(icc,dwFrameSize);
|
---|
| 619 | COPY(icc,dwQuality);
|
---|
| 620 | COPYPTR(icc,lpbiPrev);
|
---|
| 621 | COPYPTR(icc,lpPrev);
|
---|
[9140] | 622 |
|
---|
[6712] | 623 | *lParam1 = (DWORD)(icc);
|
---|
| 624 | *lParam2 = sizeof(ICCOMPRESS);
|
---|
| 625 | }
|
---|
| 626 | break;
|
---|
| 627 | case ICM_DECOMPRESS:
|
---|
| 628 | {
|
---|
| 629 | ICDECOMPRESS *icd = HeapAlloc(GetProcessHeap(),0,sizeof(ICDECOMPRESS));
|
---|
| 630 | ICDECOMPRESS *icd16; /* Same structure except for the pointers */
|
---|
[9140] | 631 |
|
---|
[6712] | 632 | icd16 = MapSL(*lParam1);
|
---|
| 633 | ret = icd16;
|
---|
[9140] | 634 |
|
---|
[6712] | 635 | COPY(icd,dwFlags);
|
---|
| 636 | COPYPTR(icd,lpbiInput);
|
---|
| 637 | COPYPTR(icd,lpInput);
|
---|
| 638 | COPYPTR(icd,lpbiOutput);
|
---|
| 639 | COPYPTR(icd,lpOutput);
|
---|
| 640 | COPY(icd,ckid);
|
---|
[9140] | 641 |
|
---|
[6712] | 642 | *lParam1 = (DWORD)(icd);
|
---|
| 643 | *lParam2 = sizeof(ICDECOMPRESS);
|
---|
| 644 | }
|
---|
| 645 | break;
|
---|
| 646 | case ICM_COMPRESS_BEGIN:
|
---|
| 647 | case ICM_COMPRESS_GET_FORMAT:
|
---|
| 648 | case ICM_COMPRESS_GET_SIZE:
|
---|
| 649 | case ICM_COMPRESS_QUERY:
|
---|
| 650 | case ICM_DECOMPRESS_GET_FORMAT:
|
---|
| 651 | case ICM_DECOMPRESS_QUERY:
|
---|
| 652 | case ICM_DECOMPRESS_BEGIN:
|
---|
| 653 | case ICM_DECOMPRESS_SET_PALETTE:
|
---|
| 654 | case ICM_DECOMPRESS_GET_PALETTE:
|
---|
| 655 | *lParam1 = (DWORD)MapSL(*lParam1);
|
---|
| 656 | *lParam2 = (DWORD)MapSL(*lParam2);
|
---|
| 657 | break;
|
---|
| 658 | case ICM_DECOMPRESSEX_QUERY:
|
---|
| 659 | if ((*lParam2 != sizeof(ICDECOMPRESSEX16)) && (*lParam2 != 0))
|
---|
| 660 | WARN("*lParam2 has unknown value %p\n",(ICDECOMPRESSEX16*)*lParam2);
|
---|
| 661 | /* FIXME: *lParm2 is meant to be 0 or an ICDECOMPRESSEX16*, but is sizeof(ICDECOMRPESSEX16)
|
---|
| 662 | * This is because of ICMessage(). Special case it?
|
---|
| 663 | {
|
---|
| 664 | LPVOID* addr = HeapAlloc(GetProcessHeap(),0,2*sizeof(LPVOID));
|
---|
| 665 | addr[0] = MSVIDEO_MapICDEX16To32(lParam1);
|
---|
| 666 | if (*lParam2)
|
---|
| 667 | addr[1] = MSVIDEO_MapICDEX16To32(lParam2);
|
---|
| 668 | else
|
---|
| 669 | addr[1] = 0;
|
---|
[9140] | 670 |
|
---|
[6712] | 671 | ret = addr;
|
---|
| 672 | }
|
---|
| 673 | break;*/
|
---|
| 674 | case ICM_DECOMPRESSEX_BEGIN:
|
---|
| 675 | case ICM_DECOMPRESSEX:
|
---|
| 676 | ret = MSVIDEO_MapICDEX16To32(lParam1);
|
---|
| 677 | *lParam2 = sizeof(ICDECOMPRESSEX);
|
---|
| 678 | break;
|
---|
| 679 | case ICM_DRAW_BEGIN:
|
---|
| 680 | {
|
---|
| 681 | ICDRAWBEGIN *icdb = HeapAlloc(GetProcessHeap(),0,sizeof(ICDRAWBEGIN));
|
---|
| 682 | ICDRAWBEGIN16 *icdb16 = MapSL(*lParam1);
|
---|
| 683 | ret = icdb16;
|
---|
[6386] | 684 |
|
---|
[6712] | 685 | COPY(icdb,dwFlags);
|
---|
| 686 | COPY(icdb,hpal);
|
---|
| 687 | COPY(icdb,hwnd);
|
---|
| 688 | COPY(icdb,hdc);
|
---|
| 689 | COPY(icdb,xDst);
|
---|
| 690 | COPY(icdb,yDst);
|
---|
| 691 | COPY(icdb,dxDst);
|
---|
| 692 | COPY(icdb,dyDst);
|
---|
| 693 | COPYPTR(icdb,lpbi);
|
---|
| 694 | COPY(icdb,xSrc);
|
---|
| 695 | COPY(icdb,ySrc);
|
---|
| 696 | COPY(icdb,dxSrc);
|
---|
| 697 | COPY(icdb,dySrc);
|
---|
| 698 | COPY(icdb,dwRate);
|
---|
| 699 | COPY(icdb,dwScale);
|
---|
[6386] | 700 |
|
---|
[6712] | 701 | *lParam1 = (DWORD)(icdb);
|
---|
| 702 | *lParam2 = sizeof(ICDRAWBEGIN);
|
---|
| 703 | }
|
---|
| 704 | break;
|
---|
| 705 | case ICM_DRAW_SUGGESTFORMAT:
|
---|
| 706 | {
|
---|
| 707 | ICDRAWSUGGEST *icds = HeapAlloc(GetProcessHeap(),0,sizeof(ICDRAWSUGGEST));
|
---|
| 708 | ICDRAWSUGGEST16 *icds16 = MapSL(*lParam1);
|
---|
[9140] | 709 |
|
---|
[6712] | 710 | ret = icds16;
|
---|
[6386] | 711 |
|
---|
[6712] | 712 | COPY(icds,dwFlags);
|
---|
| 713 | COPYPTR(icds,lpbiIn);
|
---|
| 714 | COPYPTR(icds,lpbiSuggest);
|
---|
| 715 | COPY(icds,dxSrc);
|
---|
| 716 | COPY(icds,dySrc);
|
---|
| 717 | COPY(icds,dxDst);
|
---|
| 718 | COPY(icds,dyDst);
|
---|
| 719 | COPY(icds,hicDecompressor);
|
---|
[6386] | 720 |
|
---|
[6712] | 721 | *lParam1 = (DWORD)(icds);
|
---|
| 722 | *lParam2 = sizeof(ICDRAWSUGGEST);
|
---|
| 723 | }
|
---|
| 724 | break;
|
---|
| 725 | case ICM_DRAW:
|
---|
| 726 | {
|
---|
| 727 | ICDRAW *icd = HeapAlloc(GetProcessHeap(),0,sizeof(ICDRAW));
|
---|
| 728 | ICDRAW *icd16 = MapSL(*lParam1);
|
---|
| 729 | ret = icd16;
|
---|
[6386] | 730 |
|
---|
[6712] | 731 | COPY(icd,dwFlags);
|
---|
| 732 | COPYPTR(icd,lpFormat);
|
---|
| 733 | COPYPTR(icd,lpData);
|
---|
| 734 | COPY(icd,cbData);
|
---|
| 735 | COPY(icd,lTime);
|
---|
[6386] | 736 |
|
---|
[6712] | 737 | *lParam1 = (DWORD)(icd);
|
---|
| 738 | *lParam2 = sizeof(ICDRAW);
|
---|
| 739 | }
|
---|
| 740 | break;
|
---|
| 741 | case ICM_DRAW_START:
|
---|
| 742 | case ICM_DRAW_STOP:
|
---|
| 743 | break;
|
---|
| 744 | default:
|
---|
| 745 | FIXME("%d is not yet handled. Expect a crash.\n",msg);
|
---|
| 746 | }
|
---|
| 747 | return ret;
|
---|
[6386] | 748 | }
|
---|
| 749 |
|
---|
| 750 | #undef COPY
|
---|
| 751 | #undef COPYPTR
|
---|
| 752 |
|
---|
| 753 | void MSVIDEO_UnmapMsg16To32(UINT msg, LPVOID data16, LPDWORD lParam1, LPDWORD lParam2) {
|
---|
[6712] | 754 | TRACE("Unmapping %d\n",msg);
|
---|
[6386] | 755 |
|
---|
| 756 | #define UNCOPY(x,y) (x##16->y = x->y);
|
---|
| 757 |
|
---|
[6712] | 758 | switch (msg) {
|
---|
| 759 | case ICM_GETINFO:
|
---|
| 760 | {
|
---|
| 761 | ICINFO *ici = (ICINFO*)(*lParam1);
|
---|
| 762 | ICINFO16 *ici16 = (ICINFO16*)data16;
|
---|
[6386] | 763 |
|
---|
[6712] | 764 | UNCOPY(ici,fccType);
|
---|
| 765 | UNCOPY(ici,fccHandler);
|
---|
| 766 | UNCOPY(ici,dwFlags);
|
---|
| 767 | UNCOPY(ici,dwVersion);
|
---|
| 768 | UNCOPY(ici,dwVersionICM);
|
---|
[6386] | 769 | WideCharToMultiByte( CP_ACP, 0, ici->szName, -1, ici16->szName,
|
---|
| 770 | sizeof(ici16->szName), NULL, NULL );
|
---|
| 771 | ici16->szName[sizeof(ici16->szName)-1] = 0;
|
---|
| 772 | WideCharToMultiByte( CP_ACP, 0, ici->szDescription, -1, ici16->szDescription,
|
---|
| 773 | sizeof(ici16->szDescription), NULL, NULL );
|
---|
| 774 | ici16->szDescription[sizeof(ici16->szDescription)-1] = 0;
|
---|
[6712] | 775 | /* This just gives garbage for some reason - BB
|
---|
| 776 | lstrcpynWtoA(ici16->szDriver,ici->szDriver,128);*/
|
---|
[6386] | 777 |
|
---|
[6712] | 778 | HeapFree(GetProcessHeap(),0,ici);
|
---|
| 779 | }
|
---|
| 780 | break;
|
---|
| 781 | case ICM_DECOMPRESS_QUERY:
|
---|
| 782 | /*{
|
---|
| 783 | LPVOID* x = data16;
|
---|
| 784 | HeapFree(GetProcessHeap(),0,x[0]);
|
---|
| 785 | if (x[1])
|
---|
| 786 | HeapFree(GetProcessHeap(),0,x[1]);
|
---|
| 787 | }
|
---|
| 788 | break;*/
|
---|
| 789 | case ICM_COMPRESS:
|
---|
| 790 | case ICM_DECOMPRESS:
|
---|
| 791 | case ICM_DECOMPRESSEX_QUERY:
|
---|
| 792 | case ICM_DECOMPRESSEX_BEGIN:
|
---|
| 793 | case ICM_DECOMPRESSEX:
|
---|
| 794 | case ICM_DRAW_BEGIN:
|
---|
| 795 | case ICM_DRAW_SUGGESTFORMAT:
|
---|
| 796 | case ICM_DRAW:
|
---|
| 797 | HeapFree(GetProcessHeap(),0,data16);
|
---|
| 798 | break;
|
---|
| 799 | default:
|
---|
| 800 | ERR("Unmapping unmapped msg %d\n",msg);
|
---|
| 801 | }
|
---|
[9140] | 802 | #undef UNCOPY
|
---|
[6386] | 803 | }
|
---|
| 804 |
|
---|
| 805 | LRESULT MSVIDEO_SendMessage(HIC hic,UINT msg,DWORD lParam1,DWORD lParam2, BOOL bFrom32) {
|
---|
[6712] | 806 | LRESULT ret;
|
---|
| 807 | WINE_HIC *whic = GlobalLock16(hic);
|
---|
| 808 | LPVOID data16 = 0;
|
---|
| 809 | BOOL bDrv32;
|
---|
[6386] | 810 |
|
---|
| 811 | #define XX(x) case x: TRACE("(0x%08lx,"#x",0x%08lx,0x%08lx,%d)\n",(DWORD)hic,lParam1,lParam2,bFrom32?32:16);break;
|
---|
| 812 |
|
---|
[6712] | 813 | switch (msg) {
|
---|
| 814 | /* DRV_* */
|
---|
| 815 | XX(DRV_LOAD);
|
---|
| 816 | XX(DRV_ENABLE);
|
---|
| 817 | XX(DRV_OPEN);
|
---|
| 818 | XX(DRV_CLOSE);
|
---|
| 819 | XX(DRV_DISABLE);
|
---|
| 820 | XX(DRV_FREE);
|
---|
| 821 | /* ICM_RESERVED+X */
|
---|
| 822 | XX(ICM_ABOUT);
|
---|
| 823 | XX(ICM_CONFIGURE);
|
---|
| 824 | XX(ICM_GET);
|
---|
| 825 | XX(ICM_GETINFO);
|
---|
| 826 | XX(ICM_GETDEFAULTQUALITY);
|
---|
| 827 | XX(ICM_GETQUALITY);
|
---|
| 828 | XX(ICM_GETSTATE);
|
---|
| 829 | XX(ICM_SETQUALITY);
|
---|
| 830 | XX(ICM_SET);
|
---|
| 831 | XX(ICM_SETSTATE);
|
---|
| 832 | /* ICM_USER+X */
|
---|
| 833 | XX(ICM_COMPRESS_FRAMES_INFO);
|
---|
| 834 | XX(ICM_COMPRESS_GET_FORMAT);
|
---|
| 835 | XX(ICM_COMPRESS_GET_SIZE);
|
---|
| 836 | XX(ICM_COMPRESS_QUERY);
|
---|
| 837 | XX(ICM_COMPRESS_BEGIN);
|
---|
| 838 | XX(ICM_COMPRESS);
|
---|
| 839 | XX(ICM_COMPRESS_END);
|
---|
| 840 | XX(ICM_DECOMPRESS_GET_FORMAT);
|
---|
| 841 | XX(ICM_DECOMPRESS_QUERY);
|
---|
| 842 | XX(ICM_DECOMPRESS_BEGIN);
|
---|
| 843 | XX(ICM_DECOMPRESS);
|
---|
| 844 | XX(ICM_DECOMPRESS_END);
|
---|
| 845 | XX(ICM_DECOMPRESS_SET_PALETTE);
|
---|
| 846 | XX(ICM_DECOMPRESS_GET_PALETTE);
|
---|
| 847 | XX(ICM_DRAW_QUERY);
|
---|
| 848 | XX(ICM_DRAW_BEGIN);
|
---|
| 849 | XX(ICM_DRAW_GET_PALETTE);
|
---|
| 850 | XX(ICM_DRAW_START);
|
---|
| 851 | XX(ICM_DRAW_STOP);
|
---|
| 852 | XX(ICM_DRAW_END);
|
---|
| 853 | XX(ICM_DRAW_GETTIME);
|
---|
| 854 | XX(ICM_DRAW);
|
---|
| 855 | XX(ICM_DRAW_WINDOW);
|
---|
| 856 | XX(ICM_DRAW_SETTIME);
|
---|
| 857 | XX(ICM_DRAW_REALIZE);
|
---|
| 858 | XX(ICM_DRAW_FLUSH);
|
---|
| 859 | XX(ICM_DRAW_RENDERBUFFER);
|
---|
| 860 | XX(ICM_DRAW_START_PLAY);
|
---|
| 861 | XX(ICM_DRAW_STOP_PLAY);
|
---|
| 862 | XX(ICM_DRAW_SUGGESTFORMAT);
|
---|
| 863 | XX(ICM_DRAW_CHANGEPALETTE);
|
---|
| 864 | XX(ICM_GETBUFFERSWANTED);
|
---|
| 865 | XX(ICM_GETDEFAULTKEYFRAMERATE);
|
---|
| 866 | XX(ICM_DECOMPRESSEX_BEGIN);
|
---|
| 867 | XX(ICM_DECOMPRESSEX_QUERY);
|
---|
| 868 | XX(ICM_DECOMPRESSEX);
|
---|
| 869 | XX(ICM_DECOMPRESSEX_END);
|
---|
| 870 | XX(ICM_SET_STATUS_PROC);
|
---|
| 871 | default:
|
---|
| 872 | FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx,%i) unknown message\n",(DWORD)hic,(DWORD)msg,lParam1,lParam2,bFrom32?32:16);
|
---|
| 873 | }
|
---|
[6386] | 874 |
|
---|
| 875 | #undef XX
|
---|
| 876 |
|
---|
[6712] | 877 | if (!whic) return ICERR_BADHANDLE;
|
---|
[6386] | 878 |
|
---|
[6712] | 879 | if (whic->driverproc) { /* IC is a function */
|
---|
[6386] | 880 | #ifdef __WIN32OS2__
|
---|
[9140] | 881 | bDrv32 = whic->privatevfw;
|
---|
[6386] | 882 | #else
|
---|
[6712] | 883 | bDrv32 = whic->private;
|
---|
[6386] | 884 | #endif
|
---|
[6712] | 885 | } else {
|
---|
| 886 | bDrv32 = ((GetDriverFlags(whic->hdrv) & (WINE_GDF_EXIST|WINE_GDF_16BIT)) == WINE_GDF_EXIST);
|
---|
| 887 | }
|
---|
[6386] | 888 |
|
---|
[6712] | 889 | if (!bFrom32) {
|
---|
| 890 | if (bDrv32)
|
---|
| 891 | data16 = MSVIDEO_MapMsg16To32(msg,&lParam1,&lParam2);
|
---|
| 892 | } else {
|
---|
| 893 | if (!bDrv32) {
|
---|
| 894 | ERR("Can't do 32->16 mappings\n");
|
---|
| 895 | ret = -1;
|
---|
| 896 | goto out;
|
---|
| 897 | }
|
---|
| 898 | }
|
---|
[9140] | 899 |
|
---|
[6712] | 900 | if (whic->driverproc) {
|
---|
| 901 | if (bDrv32) {
|
---|
| 902 | ret = whic->driverproc(whic->hdrv,hic,msg,lParam1,lParam2);
|
---|
| 903 | } else {
|
---|
[9140] | 904 | ret = MSVIDEO_CallTo16_long_lwwll((FARPROC16)whic->driverproc,HDRVR_16(whic->hdrv),hic,msg,lParam1,lParam2);
|
---|
[6712] | 905 | }
|
---|
| 906 | } else {
|
---|
| 907 | ret = SendDriverMessage(whic->hdrv,msg,lParam1,lParam2);
|
---|
| 908 | }
|
---|
[6386] | 909 |
|
---|
[6712] | 910 | if (data16)
|
---|
| 911 | MSVIDEO_UnmapMsg16To32(msg,data16,&lParam1,&lParam2);
|
---|
[9140] | 912 |
|
---|
[6386] | 913 | out:
|
---|
[6712] | 914 | GlobalUnlock16(hic);
|
---|
[9140] | 915 |
|
---|
[6712] | 916 | TRACE(" -> 0x%08lx\n",ret);
|
---|
| 917 | return ret;
|
---|
[6386] | 918 | }
|
---|
| 919 |
|
---|
| 920 | /***********************************************************************
|
---|
[6712] | 921 | * ICSendMessage [MSVFW32.@]
|
---|
[6386] | 922 | */
|
---|
| 923 | LRESULT VFWAPI ICSendMessage(HIC hic, UINT msg, DWORD lParam1, DWORD lParam2) {
|
---|
[6712] | 924 | return MSVIDEO_SendMessage(hic,msg,lParam1,lParam2,TRUE);
|
---|
[6386] | 925 | }
|
---|
[9140] | 926 |
|
---|
[6386] | 927 | /***********************************************************************
|
---|
[6712] | 928 | * ICSendMessage [MSVIDEO.205]
|
---|
[6386] | 929 | */
|
---|
| 930 | LRESULT VFWAPI ICSendMessage16(HIC16 hic, UINT16 msg, DWORD lParam1, DWORD lParam2) {
|
---|
[6712] | 931 | return MSVIDEO_SendMessage(hic,msg,lParam1,lParam2,FALSE);
|
---|
[6386] | 932 | }
|
---|
| 933 |
|
---|
| 934 | /***********************************************************************
|
---|
[6712] | 935 | * ICDrawBegin [MSVFW32.@]
|
---|
[6386] | 936 | */
|
---|
| 937 | DWORD VFWAPIV ICDrawBegin(
|
---|
[6712] | 938 | HIC hic, /* [in] */
|
---|
| 939 | DWORD dwFlags, /* [in] flags */
|
---|
| 940 | HPALETTE hpal, /* [in] palette to draw with */
|
---|
| 941 | HWND hwnd, /* [in] window to draw to */
|
---|
| 942 | HDC hdc, /* [in] HDC to draw to */
|
---|
| 943 | INT xDst, /* [in] destination rectangle */
|
---|
| 944 | INT yDst, /* [in] */
|
---|
| 945 | INT dxDst, /* [in] */
|
---|
| 946 | INT dyDst, /* [in] */
|
---|
| 947 | LPBITMAPINFOHEADER lpbi, /* [in] format of frame to draw */
|
---|
| 948 | INT xSrc, /* [in] source rectangle */
|
---|
| 949 | INT ySrc, /* [in] */
|
---|
| 950 | INT dxSrc, /* [in] */
|
---|
| 951 | INT dySrc, /* [in] */
|
---|
| 952 | DWORD dwRate, /* [in] frames/second = (dwRate/dwScale) */
|
---|
| 953 | DWORD dwScale) /* [in] */
|
---|
[6386] | 954 | {
|
---|
[9140] | 955 |
|
---|
[6712] | 956 | ICDRAWBEGIN icdb;
|
---|
[6386] | 957 |
|
---|
[6712] | 958 | TRACE("(0x%08lx,%ld,0x%08lx,0x%08lx,0x%08lx,%u,%u,%u,%u,%p,%u,%u,%u,%u,%ld,%ld)\n",
|
---|
| 959 | (DWORD)hic, dwFlags, (DWORD)hpal, (DWORD)hwnd, (DWORD)hdc, xDst, yDst, dxDst, dyDst,
|
---|
| 960 | lpbi, xSrc, ySrc, dxSrc, dySrc, dwRate, dwScale);
|
---|
[6386] | 961 |
|
---|
[6712] | 962 | icdb.dwFlags = dwFlags;
|
---|
| 963 | icdb.hpal = hpal;
|
---|
| 964 | icdb.hwnd = hwnd;
|
---|
| 965 | icdb.hdc = hdc;
|
---|
| 966 | icdb.xDst = xDst;
|
---|
| 967 | icdb.yDst = yDst;
|
---|
| 968 | icdb.dxDst = dxDst;
|
---|
| 969 | icdb.dyDst = dyDst;
|
---|
| 970 | icdb.lpbi = lpbi;
|
---|
| 971 | icdb.xSrc = xSrc;
|
---|
| 972 | icdb.ySrc = ySrc;
|
---|
| 973 | icdb.dxSrc = dxSrc;
|
---|
| 974 | icdb.dySrc = dySrc;
|
---|
| 975 | icdb.dwRate = dwRate;
|
---|
| 976 | icdb.dwScale = dwScale;
|
---|
| 977 | return ICSendMessage(hic,ICM_DRAW_BEGIN,(DWORD)&icdb,sizeof(icdb));
|
---|
[6386] | 978 | }
|
---|
| 979 |
|
---|
| 980 | /***********************************************************************
|
---|
[6712] | 981 | * ICDraw [MSVFW32.@]
|
---|
[6386] | 982 | */
|
---|
| 983 | DWORD VFWAPIV ICDraw(HIC hic, DWORD dwFlags, LPVOID lpFormat, LPVOID lpData, DWORD cbData, LONG lTime) {
|
---|
[6712] | 984 | ICDRAW icd;
|
---|
[6386] | 985 |
|
---|
[6712] | 986 | TRACE("(0x%09lx,%ld,%p,%p,%ld,%ld)\n",(DWORD)hic,dwFlags,lpFormat,lpData,cbData,lTime);
|
---|
[6386] | 987 |
|
---|
[6712] | 988 | icd.dwFlags = dwFlags;
|
---|
| 989 | icd.lpFormat = lpFormat;
|
---|
| 990 | icd.lpData = lpData;
|
---|
| 991 | icd.cbData = cbData;
|
---|
| 992 | icd.lTime = lTime;
|
---|
[6386] | 993 |
|
---|
[6712] | 994 | return ICSendMessage(hic,ICM_DRAW,(DWORD)&icd,sizeof(icd));
|
---|
[6386] | 995 | }
|
---|
| 996 |
|
---|
| 997 | /***********************************************************************
|
---|
[6712] | 998 | * ICClose [MSVFW32.@]
|
---|
[6386] | 999 | */
|
---|
| 1000 | LRESULT WINAPI ICClose(HIC hic) {
|
---|
[6712] | 1001 | WINE_HIC *whic = GlobalLock16(hic);
|
---|
| 1002 | TRACE("(0x%08lx)\n",(DWORD)hic);
|
---|
| 1003 | if (whic->driverproc) {
|
---|
| 1004 | ICSendMessage(hic,DRV_CLOSE,0,0);
|
---|
| 1005 | ICSendMessage(hic,DRV_DISABLE,0,0);
|
---|
| 1006 | ICSendMessage(hic,DRV_FREE,0,0);
|
---|
| 1007 | } else {
|
---|
| 1008 | CloseDriver(whic->hdrv,0,0);
|
---|
| 1009 | }
|
---|
[6386] | 1010 |
|
---|
[6712] | 1011 | GlobalUnlock16(hic);
|
---|
| 1012 | GlobalFree16(hic);
|
---|
| 1013 | return 0;
|
---|
[6386] | 1014 | }
|
---|
| 1015 |
|
---|
| 1016 |
|
---|
[9140] | 1017 |
|
---|
[6386] | 1018 | /***********************************************************************
|
---|
[9140] | 1019 | * ICImageCompress [MSVFW32.@]
|
---|
[6386] | 1020 | */
|
---|
[9140] | 1021 | HANDLE VFWAPI ICImageCompress(
|
---|
| 1022 | HIC hic, UINT uiFlags,
|
---|
| 1023 | LPBITMAPINFO lpbiIn, LPVOID lpBits,
|
---|
| 1024 | LPBITMAPINFO lpbiOut, LONG lQuality,
|
---|
| 1025 | LONG* plSize)
|
---|
[6386] | 1026 | {
|
---|
[9140] | 1027 | FIXME("(%08x,%08x,%p,%p,%p,%ld,%p)\n",
|
---|
| 1028 | hic, uiFlags, lpbiIn, lpBits, lpbiOut, lQuality, plSize);
|
---|
| 1029 |
|
---|
| 1030 | return (HANDLE)NULL;
|
---|
[6386] | 1031 | }
|
---|
| 1032 |
|
---|
| 1033 | /***********************************************************************
|
---|
[9140] | 1034 | * ICImageDecompress [MSVFW32.@]
|
---|
[6386] | 1035 | */
|
---|
[9140] | 1036 |
|
---|
| 1037 | HANDLE VFWAPI ICImageDecompress(
|
---|
| 1038 | HIC hic, UINT uiFlags, LPBITMAPINFO lpbiIn,
|
---|
| 1039 | LPVOID lpBits, LPBITMAPINFO lpbiOut)
|
---|
[6386] | 1040 | {
|
---|
[9140] | 1041 | HGLOBAL hMem = (HGLOBAL)NULL;
|
---|
| 1042 | BYTE* pMem = NULL;
|
---|
| 1043 | BOOL bReleaseIC = FALSE;
|
---|
| 1044 | BYTE* pHdr = NULL;
|
---|
| 1045 | LONG cbHdr = 0;
|
---|
| 1046 | BOOL bSucceeded = FALSE;
|
---|
| 1047 | BOOL bInDecompress = FALSE;
|
---|
| 1048 | DWORD biSizeImage;
|
---|
| 1049 |
|
---|
| 1050 | TRACE("(%08x,%08x,%p,%p,%p)\n",
|
---|
| 1051 | hic, uiFlags, lpbiIn, lpBits, lpbiOut);
|
---|
| 1052 |
|
---|
| 1053 | if ( hic == (HIC)NULL )
|
---|
| 1054 | {
|
---|
| 1055 | hic = ICDecompressOpen( mmioFOURCC('V','I','D','C'), 0, &lpbiIn->bmiHeader, (lpbiOut != NULL) ? &lpbiOut->bmiHeader : NULL );
|
---|
| 1056 | if ( hic == (HIC)NULL )
|
---|
| 1057 | {
|
---|
| 1058 | WARN("no handler\n" );
|
---|
| 1059 | goto err;
|
---|
| 1060 | }
|
---|
| 1061 | bReleaseIC = TRUE;
|
---|
| 1062 | }
|
---|
| 1063 | if ( uiFlags != 0 )
|
---|
| 1064 | {
|
---|
| 1065 | FIXME( "unknown flag %08x\n", uiFlags );
|
---|
| 1066 | goto err;
|
---|
| 1067 | }
|
---|
| 1068 | if ( lpbiIn == NULL || lpBits == NULL )
|
---|
| 1069 | {
|
---|
| 1070 | WARN("invalid argument\n");
|
---|
| 1071 | goto err;
|
---|
| 1072 | }
|
---|
| 1073 |
|
---|
| 1074 | if ( lpbiOut != NULL )
|
---|
| 1075 | {
|
---|
| 1076 | if ( lpbiOut->bmiHeader.biSize != sizeof(BITMAPINFOHEADER) )
|
---|
| 1077 | goto err;
|
---|
| 1078 | cbHdr = sizeof(BITMAPINFOHEADER);
|
---|
| 1079 | if ( lpbiOut->bmiHeader.biCompression == 3 )
|
---|
| 1080 | cbHdr += sizeof(DWORD)*3;
|
---|
| 1081 | else
|
---|
| 1082 | if ( lpbiOut->bmiHeader.biBitCount <= 8 )
|
---|
| 1083 | {
|
---|
| 1084 | if ( lpbiOut->bmiHeader.biClrUsed == 0 )
|
---|
| 1085 | cbHdr += sizeof(RGBQUAD) * (1<<lpbiOut->bmiHeader.biBitCount);
|
---|
| 1086 | else
|
---|
| 1087 | cbHdr += sizeof(RGBQUAD) * lpbiOut->bmiHeader.biClrUsed;
|
---|
| 1088 | }
|
---|
| 1089 | }
|
---|
| 1090 | else
|
---|
| 1091 | {
|
---|
| 1092 | TRACE( "get format\n" );
|
---|
| 1093 |
|
---|
| 1094 | cbHdr = ICDecompressGetFormatSize(hic,lpbiIn);
|
---|
| 1095 | if ( cbHdr < sizeof(BITMAPINFOHEADER) )
|
---|
| 1096 | goto err;
|
---|
| 1097 | pHdr = (BYTE*)HeapAlloc(GetProcessHeap(),0,cbHdr+sizeof(RGBQUAD)*256);
|
---|
| 1098 | if ( pHdr == NULL )
|
---|
| 1099 | goto err;
|
---|
| 1100 | ZeroMemory( pHdr, cbHdr+sizeof(RGBQUAD)*256 );
|
---|
| 1101 | if ( ICDecompressGetFormat( hic, lpbiIn, (BITMAPINFO*)pHdr ) != ICERR_OK )
|
---|
| 1102 | goto err;
|
---|
| 1103 | lpbiOut = (BITMAPINFO*)pHdr;
|
---|
| 1104 | if ( lpbiOut->bmiHeader.biBitCount <= 8 &&
|
---|
| 1105 | ICDecompressGetPalette( hic, lpbiIn, lpbiOut ) != ICERR_OK &&
|
---|
| 1106 | lpbiIn->bmiHeader.biBitCount == lpbiOut->bmiHeader.biBitCount )
|
---|
| 1107 | {
|
---|
| 1108 | if ( lpbiIn->bmiHeader.biClrUsed == 0 )
|
---|
| 1109 | memcpy( lpbiOut->bmiColors, lpbiIn->bmiColors, sizeof(RGBQUAD)*(1<<lpbiOut->bmiHeader.biBitCount) );
|
---|
| 1110 | else
|
---|
| 1111 | memcpy( lpbiOut->bmiColors, lpbiIn->bmiColors, sizeof(RGBQUAD)*lpbiIn->bmiHeader.biClrUsed );
|
---|
| 1112 | }
|
---|
| 1113 | if ( lpbiOut->bmiHeader.biBitCount <= 8 &&
|
---|
| 1114 | lpbiOut->bmiHeader.biClrUsed == 0 )
|
---|
| 1115 | lpbiOut->bmiHeader.biClrUsed = 1<<lpbiOut->bmiHeader.biBitCount;
|
---|
| 1116 |
|
---|
| 1117 | lpbiOut->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
---|
| 1118 | cbHdr = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*lpbiOut->bmiHeader.biClrUsed;
|
---|
| 1119 | }
|
---|
| 1120 |
|
---|
| 1121 | biSizeImage = lpbiOut->bmiHeader.biSizeImage;
|
---|
| 1122 | if ( biSizeImage == 0 )
|
---|
| 1123 | biSizeImage = ((((lpbiOut->bmiHeader.biWidth * lpbiOut->bmiHeader.biBitCount + 7) >> 3) + 3) & (~3)) * abs(lpbiOut->bmiHeader.biHeight);
|
---|
| 1124 |
|
---|
| 1125 | TRACE( "call ICDecompressBegin\n" );
|
---|
| 1126 |
|
---|
| 1127 | if ( ICDecompressBegin( hic, lpbiIn, lpbiOut ) != ICERR_OK )
|
---|
| 1128 | goto err;
|
---|
| 1129 | bInDecompress = TRUE;
|
---|
| 1130 |
|
---|
| 1131 | TRACE( "cbHdr %ld, biSizeImage %ld\n", cbHdr, biSizeImage );
|
---|
| 1132 |
|
---|
| 1133 | hMem = GlobalAlloc( GMEM_MOVEABLE|GMEM_ZEROINIT, cbHdr + biSizeImage );
|
---|
| 1134 | if ( hMem == (HGLOBAL)NULL )
|
---|
| 1135 | {
|
---|
| 1136 | WARN( "out of memory\n" );
|
---|
| 1137 | goto err;
|
---|
| 1138 | }
|
---|
| 1139 | pMem = (BYTE*)GlobalLock( hMem );
|
---|
| 1140 | if ( pMem == NULL )
|
---|
| 1141 | goto err;
|
---|
| 1142 | memcpy( pMem, lpbiOut, cbHdr );
|
---|
| 1143 |
|
---|
| 1144 | TRACE( "call ICDecompress\n" );
|
---|
| 1145 | if ( ICDecompress( hic, 0, &lpbiIn->bmiHeader, lpBits, &lpbiOut->bmiHeader, pMem+cbHdr ) != ICERR_OK )
|
---|
| 1146 | goto err;
|
---|
| 1147 |
|
---|
| 1148 | bSucceeded = TRUE;
|
---|
| 1149 | err:
|
---|
| 1150 | if ( bInDecompress )
|
---|
| 1151 | ICDecompressEnd( hic );
|
---|
| 1152 | if ( bReleaseIC )
|
---|
| 1153 | ICClose(hic);
|
---|
| 1154 | if ( pHdr != NULL )
|
---|
| 1155 | HeapFree(GetProcessHeap(),0,pHdr);
|
---|
| 1156 | if ( pMem != NULL )
|
---|
| 1157 | GlobalUnlock( hMem );
|
---|
| 1158 | if ( !bSucceeded && hMem != (HGLOBAL)NULL )
|
---|
| 1159 | {
|
---|
| 1160 | GlobalFree(hMem); hMem = (HGLOBAL)NULL;
|
---|
| 1161 | }
|
---|
| 1162 |
|
---|
| 1163 | return (HANDLE)hMem;
|
---|
[6386] | 1164 | }
|
---|