/*********************************************************************** * ICGetDisplayFormat [MSVFW32.@] */ HIC VFWAPI ICGetDisplayFormat( HIC hic,LPBITMAPINFOHEADER lpbiIn,LPBITMAPINFOHEADER lpbiOut, INT depth,INT dx,INT dy) { HIC tmphic = hic; TRACE("(%p,%p,%p,%d,%d,%d)!\n",hic,lpbiIn,lpbiOut,depth,dx,dy); if (!tmphic) { tmphic=ICLocate(ICTYPE_VIDEO,0,lpbiIn,NULL,ICMODE_DECOMPRESS); if (!tmphic) return tmphic; } if ((dy == lpbiIn->biHeight) && (dx == lpbiIn->biWidth)) dy = dx = 0; /* no resize needed */ /* Can we decompress it ? */ if (ICDecompressQuery(tmphic,lpbiIn,NULL) != 0) goto errout; /* no, sorry */ ICSendMessage(tmphic, ICM_DECOMPRESS_GET_FORMAT, (DWORD_PTR)lpbiIn, (DWORD_PTR)lpbiOut); if (lpbiOut->biCompression != 0) { FIXME("Ooch, how come decompressor outputs compressed data (%d)??\n", lpbiOut->biCompression); } if (lpbiOut->biSize < sizeof(*lpbiOut)) { FIXME("Ooch, size of output BIH is too small (%d)\n", lpbiOut->biSize); lpbiOut->biSize = sizeof(*lpbiOut); } if (!depth) { HDC hdc; hdc = GetDC(0); depth = GetDeviceCaps(hdc,BITSPIXEL)*GetDeviceCaps(hdc,PLANES); ReleaseDC(0,hdc); if (depth==15) depth = 16; if (depth<8) depth = 8; } if (lpbiIn->biBitCount == 8) depth = 8; TRACE("=> %p\n", tmphic); return tmphic; errout: if (hic!=tmphic) ICClose(tmphic); TRACE("=> 0\n"); return 0; }
/*********************************************************************** * ICLocate [MSVFW32.@] */ HIC VFWAPI ICLocate(DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut, WORD wMode) { driver_info_t info; TRACE("(%s,%s,%p,%p,0x%04x)\n", wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), lpbiIn, lpbiOut, wMode); info.fccType = fccType; info.fccHandler = fccHandler; info.lpbiIn = lpbiIn; info.lpbiOut = lpbiOut; info.wMode = wMode; switch (wMode) { case ICMODE_FASTCOMPRESS: case ICMODE_COMPRESS: info.querymsg = ICM_COMPRESS_QUERY; break; case ICMODE_FASTDECOMPRESS: case ICMODE_DECOMPRESS: info.querymsg = ICM_DECOMPRESS_QUERY; break; case ICMODE_DRAW: info.querymsg = ICM_DRAW_QUERY; break; default: WARN("Unknown mode (%d)\n", wMode); return 0; } /* Easy case: handler/type match, we just fire a query and return */ info.hic = try_driver(&info); /* If it didn't work, try each driver in turn. 32 bit codecs only. */ /* FIXME: Move this to an init routine? */ if (!info.hic) enum_drivers(fccType, ICLocate_enum_handler, &info); if (info.hic) { TRACE("=> %p\n", info.hic); return info.hic; } if (fccType == streamtypeVIDEO) return ICLocate(ICTYPE_VIDEO, fccHandler, lpbiIn, lpbiOut, wMode); WARN("(%s,%s,%p,%p,0x%04x) not found!\n", wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), lpbiIn, lpbiOut, wMode); return 0; }
/*********************************************************************** * ICLocate [MSVIDEO.213] */ HIC16 VFWAPI ICLocate16(DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut, WORD wFlags) { return HIC_16(ICLocate(fccType, fccHandler, lpbiIn, lpbiOut, wFlags)); }
static HRESULT WINAPI AVIDec_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE * pmt) { AVIDecImpl* This = (AVIDecImpl*)tf; HRESULT hr = VFW_E_TYPE_NOT_ACCEPTED; TRACE("(%p)->(%p)\n", This, pmt); if (dir != PINDIR_INPUT) return S_OK; /* Check root (GUID w/o FOURCC) */ if ((IsEqualIID(&pmt->majortype, &MEDIATYPE_Video)) && (!memcmp(((const char *)&pmt->subtype)+4, ((const char *)&MEDIATYPE_Video)+4, sizeof(GUID)-4))) { VIDEOINFOHEADER *format1 = (VIDEOINFOHEADER *)pmt->pbFormat; VIDEOINFOHEADER2 *format2 = (VIDEOINFOHEADER2 *)pmt->pbFormat; BITMAPINFOHEADER *bmi; if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)) bmi = &format1->bmiHeader; else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2)) bmi = &format2->bmiHeader; else goto failed; TRACE("Fourcc: %s\n", debugstr_an((const char *)&pmt->subtype.Data1, 4)); This->hvid = ICLocate(pmt->majortype.Data1, pmt->subtype.Data1, bmi, NULL, ICMODE_DECOMPRESS); if (This->hvid) { AM_MEDIA_TYPE* outpmt = &This->tf.pmt; const CLSID* outsubtype; DWORD bih_size; DWORD output_depth = bmi->biBitCount; DWORD result; FreeMediaType(outpmt); switch(bmi->biBitCount) { case 32: outsubtype = &MEDIASUBTYPE_RGB32; break; case 24: outsubtype = &MEDIASUBTYPE_RGB24; break; case 16: outsubtype = &MEDIASUBTYPE_RGB565; break; case 8: outsubtype = &MEDIASUBTYPE_RGB8; break; default: WARN("Non standard input depth %d, forced output depth to 32\n", bmi->biBitCount); outsubtype = &MEDIASUBTYPE_RGB32; output_depth = 32; break; } /* Copy bitmap header from media type to 1 for input and 1 for output */ bih_size = bmi->biSize + bmi->biClrUsed * 4; This->pBihIn = CoTaskMemAlloc(bih_size); if (!This->pBihIn) { hr = E_OUTOFMEMORY; goto failed; } This->pBihOut = CoTaskMemAlloc(bih_size); if (!This->pBihOut) { hr = E_OUTOFMEMORY; goto failed; } memcpy(This->pBihIn, bmi, bih_size); memcpy(This->pBihOut, bmi, bih_size); /* Update output format as non compressed bitmap */ This->pBihOut->biCompression = 0; This->pBihOut->biBitCount = output_depth; This->pBihOut->biSizeImage = This->pBihOut->biWidth * This->pBihOut->biHeight * This->pBihOut->biBitCount / 8; TRACE("Size: %u\n", This->pBihIn->biSize); result = ICDecompressQuery(This->hvid, This->pBihIn, This->pBihOut); if (result != ICERR_OK) { ERR("Unable to found a suitable output format (%d)\n", result); goto failed; } /* Update output media type */ CopyMediaType(outpmt, pmt); outpmt->subtype = *outsubtype; if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)) memcpy(&(((VIDEOINFOHEADER *)outpmt->pbFormat)->bmiHeader), This->pBihOut, This->pBihOut->biSize); else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2)) memcpy(&(((VIDEOINFOHEADER2 *)outpmt->pbFormat)->bmiHeader), This->pBihOut, This->pBihOut->biSize); else assert(0); TRACE("Connection accepted\n"); return S_OK; } TRACE("Unable to find a suitable VFW decompressor\n"); } failed: TRACE("Connection refused\n"); return hr; }
static LBXGL_VidCodecCTX *vfw_begin_decompress(int fcc, PDGL_BMPInfoHeader *in, PDGL_BMPInfoHeader *out) { LBXGL_VidCodecCTX *ctx; vfw_ctxinfo *info; int err; ctx=LBXGL_VidCodecCTX_New(); info=gcalloc(sizeof(vfw_ctxinfo)); ctx->data=info; info->ihead=malloc(sizeof(BITMAPINFOHEADER)); memset(info->ihead, 0, sizeof(BITMAPINFOHEADER)); info->ihead->biSize = sizeof(BITMAPINFOHEADER); info->ihead->biWidth = in->biWidth; info->ihead->biHeight = in->biHeight; info->ihead->biPlanes = in->biPlanes; info->ihead->biBitCount = in->biBitCount; info->ihead->biCompression = in->biCompression; info->ihead->biSizeImage = in->biWidth*in->biHeight*in->biBitCount/8; info->ohead=malloc(sizeof(BITMAPINFOHEADER)); memset(info->ohead, 0, sizeof(BITMAPINFOHEADER)); info->ohead->biSize = sizeof(BITMAPINFOHEADER); info->ohead->biWidth = out->biWidth; // info->ohead->biHeight = -out->biHeight; info->ohead->biHeight = out->biHeight; info->ohead->biPlanes = out->biPlanes; info->ohead->biBitCount = out->biBitCount; info->ohead->biCompression = out->biCompression; info->ihead->biSizeImage = out->biWidth*out->biHeight*out->biBitCount/8; info->buffer=malloc(out->biWidth*out->biHeight*out->biBitCount/8); // info->hicd = ICOpen(ICTYPE_VIDEO, fcc, ICMODE_FASTDECOMPRESS); info->hicd = ICLocate(ICTYPE_VIDEO, fcc, info->ihead, info->ohead, ICMODE_FASTDECOMPRESS); if(!info->hicd) { printf("VFW: decompress %0.4s %0.4s: fail\n", &fcc, &in->biCompression); return(NULL); } printf("VFW: decompress %0.4s %0.4s: ok\n", &fcc, &in->biCompression); err=ICDecompressBegin(info->hicd, info->ihead, info->ohead); if(err) { printf("VFW: err %d, %0.4s %0.4s: fail\n", err, &fcc, &in->biCompression); return(NULL); } vfw_hicd[vfw_n_hicd++]=info->hicd; ctx->decompress_frame=&vfw_decompress_frame; return(ctx); }
static HRESULT WINAPI IGetFrame_fnSetFormat(IGetFrame *iface, LPBITMAPINFOHEADER lpbiWanted, LPVOID lpBits, INT x, INT y, INT dx, INT dy) { IGetFrameImpl *This = impl_from_IGetFrame(iface); AVISTREAMINFOW sInfo; LPBITMAPINFOHEADER lpbi = lpbiWanted; BOOL bBestDisplay = FALSE; TRACE("(%p,%p,%p,%d,%d,%d,%d)\n", iface, lpbiWanted, lpBits, x, y, dx, dy); if (This->pStream == NULL) return AVIERR_ERROR; if (lpbiWanted == (LPBITMAPINFOHEADER)AVIGETFRAMEF_BESTDISPLAYFMT) { lpbi = NULL; bBestDisplay = TRUE; } IAVIStream_Info(This->pStream, &sInfo, sizeof(sInfo)); if (sInfo.fccType != streamtypeVIDEO) return AVIERR_UNSUPPORTED; This->bFormatChanges = (sInfo.dwFlags & AVISTREAMINFO_FORMATCHANGES) != 0; This->dwFormatChangeCount = sInfo.dwFormatChangeCount; This->dwEditCount = sInfo.dwEditCount; This->lCurrentFrame = -1; /* get input format from stream */ if (This->lpInFormat == NULL) { HRESULT hr; This->cbInBuffer = (LONG)sInfo.dwSuggestedBufferSize; if (This->cbInBuffer == 0) This->cbInBuffer = 1024; IAVIStream_ReadFormat(This->pStream, sInfo.dwStart, NULL, &This->cbInFormat); This->lpInFormat = HeapAlloc(GetProcessHeap(), 0, This->cbInFormat + This->cbInBuffer); if (This->lpInFormat == NULL) { AVIFILE_CloseCompressor(This); return AVIERR_MEMORY; } hr = IAVIStream_ReadFormat(This->pStream, sInfo.dwStart, This->lpInFormat, &This->cbInFormat); if (FAILED(hr)) { AVIFILE_CloseCompressor(This); return hr; } This->lpInBuffer = ((LPBYTE)This->lpInFormat) + This->cbInFormat; } /* check input format */ if (This->lpInFormat->biClrUsed == 0 && This->lpInFormat->biBitCount <= 8) This->lpInFormat->biClrUsed = 1u << This->lpInFormat->biBitCount; if (This->lpInFormat->biSizeImage == 0 && This->lpInFormat->biCompression == BI_RGB) { This->lpInFormat->biSizeImage = DIBWIDTHBYTES(*This->lpInFormat) * This->lpInFormat->biHeight; } /* only to pass through? */ if (This->lpInFormat->biCompression == BI_RGB && lpBits == NULL) { if (lpbi == NULL || (lpbi->biCompression == BI_RGB && lpbi->biWidth == This->lpInFormat->biWidth && lpbi->biHeight == This->lpInFormat->biHeight && lpbi->biBitCount == This->lpInFormat->biBitCount)) { This->lpOutFormat = This->lpInFormat; This->lpOutBuffer = DIBPTR(This->lpInFormat); return AVIERR_OK; } } /* need memory for output format? */ if (This->lpOutFormat == NULL) { This->lpOutFormat = HeapAlloc(GetProcessHeap(), 0, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); if (This->lpOutFormat == NULL) { AVIFILE_CloseCompressor(This); return AVIERR_MEMORY; } } /* need handle to video compressor */ if (This->hic == NULL) { FOURCC fccHandler; if (This->lpInFormat->biCompression == BI_RGB) fccHandler = comptypeDIB; else if (This->lpInFormat->biCompression == BI_RLE8) fccHandler = mmioFOURCC('R','L','E',' '); else fccHandler = sInfo.fccHandler; if (lpbi != NULL) { if (lpbi->biWidth == 0) lpbi->biWidth = This->lpInFormat->biWidth; if (lpbi->biHeight == 0) lpbi->biHeight = This->lpInFormat->biHeight; } This->hic = ICLocate(ICTYPE_VIDEO, fccHandler, This->lpInFormat, lpbi, ICMODE_DECOMPRESS); if (This->hic == NULL) { AVIFILE_CloseCompressor(This); return AVIERR_NOCOMPRESSOR; } } /* output format given? */ if (lpbi != NULL) { /* check the given output format ... */ if (lpbi->biClrUsed == 0 && lpbi->biBitCount <= 8) lpbi->biClrUsed = 1u << lpbi->biBitCount; /* ... and remember it */ memcpy(This->lpOutFormat, lpbi, lpbi->biSize + lpbi->biClrUsed * sizeof(RGBQUAD)); if (lpbi->biBitCount <= 8) ICDecompressGetPalette(This->hic, This->lpInFormat, This->lpOutFormat); return AVIERR_OK; } else { if (bBestDisplay) { ICGetDisplayFormat(This->hic, This->lpInFormat, This->lpOutFormat, 0, dx, dy); } else if (ICDecompressGetFormat(This->hic, This->lpInFormat, This->lpOutFormat) < 0) { AVIFILE_CloseCompressor(This); return AVIERR_NOCOMPRESSOR; } /* check output format */ if (This->lpOutFormat->biClrUsed == 0 && This->lpOutFormat->biBitCount <= 8) This->lpOutFormat->biClrUsed = 1u << This->lpOutFormat->biBitCount; if (This->lpOutFormat->biSizeImage == 0 && This->lpOutFormat->biCompression == BI_RGB) { This->lpOutFormat->biSizeImage = DIBWIDTHBYTES(*This->lpOutFormat) * This->lpOutFormat->biHeight; } if (lpBits == NULL) { DWORD size = This->lpOutFormat->biClrUsed * sizeof(RGBQUAD); size += This->lpOutFormat->biSize + This->lpOutFormat->biSizeImage; This->lpOutFormat = HeapReAlloc(GetProcessHeap(), 0, This->lpOutFormat, size); if (This->lpOutFormat == NULL) { AVIFILE_CloseCompressor(This); return AVIERR_MEMORY; } This->lpOutBuffer = DIBPTR(This->lpOutFormat); } else This->lpOutBuffer = lpBits; /* for user size was irrelevant */ if (dx == -1) dx = This->lpOutFormat->biWidth; if (dy == -1) dy = This->lpOutFormat->biHeight; /* need to resize? */ if (x != 0 || y != 0) { if (dy == This->lpOutFormat->biHeight && dx == This->lpOutFormat->biWidth) This->bResize = FALSE; else This->bResize = TRUE; } if (This->bResize) { This->x = x; This->y = y; This->dx = dx; This->dy = dy; if (ICDecompressExBegin(This->hic,0,This->lpInFormat,This->lpInBuffer,0, 0,This->lpInFormat->biWidth, This->lpInFormat->biHeight,This->lpOutFormat, This->lpOutBuffer, x, y, dx, dy) == ICERR_OK) return AVIERR_OK; } else if (ICDecompressBegin(This->hic, This->lpInFormat, This->lpOutFormat) == ICERR_OK) return AVIERR_OK; AVIFILE_CloseCompressor(This); return AVIERR_COMPRESSOR; } }
BOOL MCIAVI_OpenVideo(WINE_MCIAVI* wma) { HDC hDC; DWORD outSize; FOURCC fcc = wma->ash_video.fccHandler; TRACE("fcc %4.4s\n", (LPSTR)&fcc); wma->dwCachedFrame = -1; /* get the right handle */ if (fcc == mmioFOURCC('C','R','A','M')) fcc = mmioFOURCC('M','S','V','C'); /* try to get a decompressor for that type */ wma->hic = ICLocate(ICTYPE_VIDEO, fcc, wma->inbih, NULL, ICMODE_DECOMPRESS); if (!wma->hic) { /* check for builtin DIB compressions */ fcc = wma->inbih->biCompression; if ((fcc == mmioFOURCC('D','I','B',' ')) || (fcc == mmioFOURCC('R','L','E',' ')) || (fcc == BI_RGB) || (fcc == BI_RLE8) || (fcc == BI_RLE4) || (fcc == BI_BITFIELDS)) goto paint_frame; WARN("Can't locate codec for the file\n"); return FALSE; } outSize = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD); wma->outbih = HeapAlloc(GetProcessHeap(), 0, outSize); if (!wma->outbih) { WARN("Can't alloc output BIH\n"); return FALSE; } if (!ICGetDisplayFormat(wma->hic, wma->inbih, wma->outbih, 0, 0, 0)) { WARN("Can't open decompressor\n"); return FALSE; } TRACE("bih.biSize=%d\n", wma->outbih->biSize); TRACE("bih.biWidth=%d\n", wma->outbih->biWidth); TRACE("bih.biHeight=%d\n", wma->outbih->biHeight); TRACE("bih.biPlanes=%d\n", wma->outbih->biPlanes); TRACE("bih.biBitCount=%d\n", wma->outbih->biBitCount); TRACE("bih.biCompression=%x\n", wma->outbih->biCompression); TRACE("bih.biSizeImage=%d\n", wma->outbih->biSizeImage); TRACE("bih.biXPelsPerMeter=%d\n", wma->outbih->biXPelsPerMeter); TRACE("bih.biYPelsPerMeter=%d\n", wma->outbih->biYPelsPerMeter); TRACE("bih.biClrUsed=%d\n", wma->outbih->biClrUsed); TRACE("bih.biClrImportant=%d\n", wma->outbih->biClrImportant); wma->outdata = HeapAlloc(GetProcessHeap(), 0, wma->outbih->biSizeImage); if (!wma->outdata) { WARN("Can't alloc output buffer\n"); return FALSE; } if (ICSendMessage(wma->hic, ICM_DECOMPRESS_BEGIN, (DWORD_PTR)wma->inbih, (DWORD_PTR)wma->outbih) != ICERR_OK) { WARN("Can't begin decompression\n"); return FALSE; } paint_frame: hDC = wma->hWndPaint ? GetDC(wma->hWndPaint) : 0; if (hDC) { MCIAVI_PaintFrame(wma, hDC); ReleaseDC(wma->hWndPaint, hDC); } return TRUE; }
static void test_Locate(void) { static BITMAPINFOHEADER bi = {sizeof(BITMAPINFOHEADER),32,8, 1,8, BI_RLE8, 0,100000,100000, 0,0}; static BITMAPINFOHEADER bo = {sizeof(BITMAPINFOHEADER),32,8, 1,8, BI_RGB, 0,100000,100000, 0,0}; HIC h; DWORD err; /* Oddly, MSDN documents that ICLocate takes BITMAPINFOHEADER * pointers, while ICDecompressQuery takes the larger * BITMAPINFO. Probably it's all the same as long as the * variable length color quads are present when they are * needed. */ h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS); ok(h != 0, "RLE8->RGB failed\n"); if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n"); bo.biHeight = - bo.biHeight; h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS); ok(h == 0, "RLE8->RGB height<0 succeeded\n"); if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n"); bo.biHeight = - bo.biHeight; bi.biCompression = mmioFOURCC('c','v','i','d'); /* Cinepak */ h = ICOpen(ICTYPE_VIDEO, mmioFOURCC('c','v','i','d'), ICMODE_DECOMPRESS); if (h == 0) win_skip("Cinepak/ICCVID codec not found\n"); else { bo.biBitCount = bi.biBitCount = 32; err = ICDecompressQuery(h, &bi, &bo); ok(err == ICERR_OK, "Query cvid->RGB32: %d\n", err); err = ICDecompressQuery(h, &bi, NULL); ok(err == ICERR_OK, "Query cvid 32: %d\n", err); bo.biHeight = -bo.biHeight; err = ICDecompressQuery(h, &bi, &bo); ok(err == ICERR_OK, "Query cvid->RGB32 height<0: %d\n", err); bo.biHeight = -bo.biHeight; ok(ICClose(h) == ICERR_OK,"ICClose failed\n"); bo.biBitCount = bi.biBitCount = 8; h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS); todo_wine ok(h != 0, "cvid->RGB8 failed\n"); if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n"); bo.biHeight = - bo.biHeight; h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS); todo_wine ok(h != 0, "cvid->RGB8 height<0 failed\n"); if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n"); bo.biHeight = - bo.biHeight; bo.biBitCount = bi.biBitCount = 16; h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS); ok(h != 0, "cvid->RGB16 failed\n"); if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n"); bo.biHeight = - bo.biHeight; h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS); ok(h != 0, "cvid->RGB16 height<0 failed\n"); if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n"); bo.biHeight = - bo.biHeight; bo.biBitCount = bi.biBitCount = 32; h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS); ok(h != 0, "cvid->RGB32 failed\n"); if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n"); bo.biHeight = - bo.biHeight; h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS); ok(h != 0, "cvid->RGB32 height<0 failed\n"); if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n"); bo.biHeight = - bo.biHeight; bi.biCompression = mmioFOURCC('C','V','I','D'); /* Unlike ICOpen, upper case fails with ICLocate. */ h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS); ok(h == 0, "CVID->RGB32 upper case succeeded\n"); if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n"); } bi.biCompression = mmioFOURCC('M','S','V','C'); /* MS Video 1 */ bo.biBitCount = bi.biBitCount = 16; h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS); ok(h != 0, "MSVC->RGB16 failed\n"); if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n"); bo.biHeight = - bo.biHeight; h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS); todo_wine ok(h != 0, "MSVC->RGB16 height<0 failed\n"); if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n"); bo.biHeight = - bo.biHeight; bo.biHeight--; h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS); ok(h == 0, "MSVC->RGB16 height too small succeeded\n"); if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n"); bo.biHeight++; /* ICLocate wants upper case MSVC */ bi.biCompression = mmioFOURCC('m','s','v','c'); h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS); ok(h == 0, "msvc->RGB16 succeeded\n"); if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n"); bi.biCompression = mmioFOURCC('M','S','V','C'); h = ICOpen(ICTYPE_VIDEO, mmioFOURCC('M','S','V','C'), ICMODE_DECOMPRESS); ok(h != 0, "No MSVC codec installed!?\n"); if (h != 0) { err = ICDecompressQuery(h, &bi, &bo); ok(err == ICERR_OK, "Query MSVC->RGB16: %d\n", err); err = ICDecompressQuery(h, &bi, NULL); ok(err == ICERR_OK, "Query MSVC 16: %d\n", err); bo.biHeight = -bo.biHeight; err = ICDecompressQuery(h, &bi, &bo); todo_wine ok(err == ICERR_OK, "Query MSVC->RGB16 height<0: %d\n", err); bo.biHeight = -bo.biHeight; bi.biCompression = mmioFOURCC('m','s','v','c'); err = ICDecompressQuery(h, &bi, &bo); ok(err == ICERR_BADFORMAT, "Query msvc->RGB16: %d\n", err); ok(ICClose(h) == ICERR_OK,"ICClose failed\n"); } bi.biCompression = BI_RGB; bo.biBitCount = bi.biBitCount = 8; h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS); ok(h != 0, "RGB8->RGB identity failed\n"); if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n"); bi.biCompression = BI_RLE8; h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS); ok(h != 0, "RLE8->RGB again failed\n"); if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n"); }
/*********************************************************************** * ICGetDisplayFormat [MSVFW32.@] */ HIC VFWAPI ICGetDisplayFormat(HIC hic, BITMAPINFOHEADER *in, BITMAPINFOHEADER *out, int depth, int width, int height) { HIC tmphic = hic; TRACE("(%p, %p, %p, %d, %d, %d)\n", hic, in, out, depth, width, height); if (!tmphic) { tmphic = ICLocate(ICTYPE_VIDEO, 0, in, NULL, ICMODE_DECOMPRESS); if (!tmphic) return NULL; } if (ICDecompressQuery(tmphic, in, NULL)) goto err; if (width <= 0 || height <= 0) { width = in->biWidth; height = in->biHeight; } if (!depth) depth = 32; *out = *in; out->biSize = sizeof(*out); out->biWidth = width; out->biHeight = height; out->biCompression = BI_RGB; out->biSizeImage = get_size_image(width, height, depth); /* first try the given depth */ out->biBitCount = depth; out->biSizeImage = get_size_image(width, height, out->biBitCount); if (!ICDecompressQuery(tmphic, in, out)) { if (depth == 8) ICDecompressGetPalette(tmphic, in, out); return tmphic; } /* then try 16, both with BI_RGB and BI_BITFIELDS */ if (depth <= 16) { out->biBitCount = 16; out->biSizeImage = get_size_image(width, height, out->biBitCount); if (!ICDecompressQuery(tmphic, in, out)) return tmphic; out->biCompression = BI_BITFIELDS; if (!ICDecompressQuery(tmphic, in, out)) return tmphic; out->biCompression = BI_RGB; } /* then try 24 */ if (depth <= 24) { out->biBitCount = 24; out->biSizeImage = get_size_image(width, height, out->biBitCount); if (!ICDecompressQuery(tmphic, in, out)) return tmphic; } /* then try 32 */ if (depth <= 32) { out->biBitCount = 32; out->biSizeImage = get_size_image(width, height, out->biBitCount); if (!ICDecompressQuery(tmphic, in, out)) return tmphic; } /* as a last resort, try 32 bpp with the original width and height */ out->biWidth = in->biWidth; out->biHeight = in->biHeight; out->biBitCount = 32; out->biSizeImage = get_size_image(out->biWidth, out->biHeight, out->biBitCount); if (!ICDecompressQuery(tmphic, in, out)) return tmphic; /* finally, ask the compressor for its default output format */ if (!ICSendMessage(tmphic, ICM_DECOMPRESS_GET_FORMAT, (DWORD_PTR)in, (DWORD_PTR)out)) return tmphic; err: if (hic != tmphic) ICClose(tmphic); return NULL; }