static IWICBitmapDecoder *create_decoder(const void *image_data, UINT image_size) { HGLOBAL hmem; BYTE *data; HRESULT hr; IWICBitmapDecoder *decoder = NULL; IStream *stream; GUID format; hmem = GlobalAlloc(0, image_size); data = GlobalLock(hmem); memcpy(data, image_data, image_size); GlobalUnlock(hmem); hr = CreateStreamOnHGlobal(hmem, TRUE, &stream); ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr); hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder); ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr); hr = IWICBitmapDecoder_GetContainerFormat(decoder, &format); ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatGif), "wrong container format %s\n", wine_dbgstr_guid(&format)); IStream_Release(stream); return decoder; }
static HRESULT create_decoder(const void *image_data, UINT image_size, IWICBitmapDecoder **decoder) { HGLOBAL hmem; BYTE *data; HRESULT hr; IStream *stream; GUID format; LONG refcount; *decoder = NULL; hmem = GlobalAlloc(0, image_size); data = GlobalLock(hmem); memcpy(data, image_data, image_size); GlobalUnlock(hmem); hr = CreateStreamOnHGlobal(hmem, TRUE, &stream); ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr); hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, decoder); if (hr == S_OK) { hr = IWICBitmapDecoder_GetContainerFormat(*decoder, &format); ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatPng), "wrong container format %s\n", wine_dbgstr_guid(&format)); refcount = IStream_Release(stream); ok(refcount > 0, "expected stream refcount > 0\n"); } return hr; }
static void test_createfromstream(void) { IWICBitmapDecoder *decoder; IWICImagingFactory *factory; HRESULT hr; HGLOBAL hbmpdata; char *bmpdata; IStream *bmpstream; GUID guidresult; hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); if (FAILED(hr)) return; hbmpdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(testbmp_1bpp)); ok(hbmpdata != 0, "GlobalAlloc failed\n"); if (hbmpdata) { bmpdata = GlobalLock(hbmpdata); memcpy(bmpdata, testbmp_1bpp, sizeof(testbmp_1bpp)); GlobalUnlock(hbmpdata); hr = CreateStreamOnHGlobal(hbmpdata, FALSE, &bmpstream); ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr); if (SUCCEEDED(hr)) { hr = IWICImagingFactory_CreateDecoderFromStream(factory, bmpstream, NULL, WICDecodeMetadataCacheOnDemand, &decoder); ok(SUCCEEDED(hr), "CreateDecoderFromStream failed, hr=%x\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult); ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr); ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatBmp), "unexpected container format\n"); IWICBitmapDecoder_Release(decoder); } IStream_Release(bmpstream); } GlobalFree(hbmpdata); } IWICImagingFactory_Release(factory); }
static void test_componentinfo(void) { IWICImagingFactory *factory; IWICComponentInfo *info; IWICBitmapDecoderInfo *decoderinfo; IWICBitmapDecoder *decoder; HRESULT hr; WICBitmapPattern *patterns; UINT pattern_count, pattern_size; WICComponentType type; GUID guidresult; HGLOBAL hbmpdata; char *bmpdata; IStream *bmpstream; BOOL boolresult; hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); if (SUCCEEDED(hr)) { hr = IWICImagingFactory_CreateComponentInfo(factory, &CLSID_WICBmpDecoder, &info); ok(SUCCEEDED(hr), "CreateComponentInfo failed, hr=%x\n", hr); if (SUCCEEDED(hr)) { hr = IWICComponentInfo_GetComponentType(info, &type); ok(SUCCEEDED(hr), "GetComponentType failed, hr=%x\n", hr); ok(type == WICDecoder, "got %i, expected WICDecoder\n", type); hr = IWICComponentInfo_QueryInterface(info, &IID_IWICBitmapDecoderInfo, (void**)&decoderinfo); ok(SUCCEEDED(hr), "QueryInterface failed, hr=%x\n", hr); if (SUCCEEDED(hr)) { pattern_count = 0; pattern_size = 0; hr = IWICBitmapDecoderInfo_GetPatterns(decoderinfo, 0, NULL, &pattern_count, &pattern_size); ok(SUCCEEDED(hr), "GetPatterns failed, hr=%x\n", hr); ok(pattern_count != 0, "pattern count is 0\n"); ok(pattern_size > pattern_count * sizeof(WICBitmapPattern), "size=%i, count=%i\n", pattern_size, pattern_count); patterns = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pattern_size); hr = IWICBitmapDecoderInfo_GetPatterns(decoderinfo, pattern_size, patterns, &pattern_count, &pattern_size); ok(SUCCEEDED(hr), "GetPatterns failed, hr=%x\n", hr); ok(pattern_count != 0, "pattern count is 0\n"); ok(pattern_size > pattern_count * sizeof(WICBitmapPattern), "size=%i, count=%i\n", pattern_size, pattern_count); ok(patterns[0].Length != 0, "pattern length is 0\n"); ok(patterns[0].Pattern != NULL, "pattern is NULL\n"); ok(patterns[0].Mask != NULL, "mask is NULL\n"); pattern_size -= 1; hr = IWICBitmapDecoderInfo_GetPatterns(decoderinfo, pattern_size, patterns, &pattern_count, &pattern_size); ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "GetPatterns returned %x, expected WINCODEC_ERR_INSUFFICIENTBUFFER\n", hr); HeapFree(GetProcessHeap(), 0, patterns); hr = IWICBitmapDecoderInfo_CreateInstance(decoderinfo, &decoder); ok(SUCCEEDED(hr), "CreateInstance failed, hr=%x\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult); ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr); ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatBmp), "unexpected container format\n"); IWICBitmapDecoder_Release(decoder); } hbmpdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(testbmp_rle4)); ok(hbmpdata != 0, "GlobalAlloc failed\n"); if (hbmpdata) { bmpdata = GlobalLock(hbmpdata); memcpy(bmpdata, testbmp_rle4, sizeof(testbmp_rle4)); GlobalUnlock(hbmpdata); hr = CreateStreamOnHGlobal(hbmpdata, FALSE, &bmpstream); ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr); if (SUCCEEDED(hr)) { boolresult = 0; hr = IWICBitmapDecoderInfo_MatchesPattern(decoderinfo, bmpstream, &boolresult); ok(SUCCEEDED(hr), "MatchesPattern failed, hr=%x\n", hr); ok(boolresult, "pattern not matched\n"); IStream_Release(bmpstream); } GlobalFree(hbmpdata); } IWICBitmapDecoderInfo_Release(decoderinfo); } IWICComponentInfo_Release(info); } IWICImagingFactory_Release(factory); } }
static void test_decode_rle4(void) { IWICBitmapDecoder *decoder, *decoder2; IWICBitmapFrameDecode *framedecode; HRESULT hr; HGLOBAL hbmpdata; char *bmpdata; IStream *bmpstream; DWORD capability=0; GUID guidresult; UINT count=0, width=0, height=0; double dpiX, dpiY; DWORD imagedata[64] = {1}; const DWORD expected_imagedata[64] = { 0x0000ff,0xffffff,0x0000ff,0xffffff,0xff0000,0xff0000,0xff0000,0xff0000, 0xffffff,0x0000ff,0xffffff,0x0000ff,0xff0000,0xff0000,0xff0000,0xff0000, 0x0000ff,0xffffff,0x0000ff,0xffffff,0xff0000,0xff0000,0xff0000,0xff0000, 0xffffff,0x0000ff,0xffffff,0x0000ff,0xff0000,0xff0000,0xff0000,0xff0000, 0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x000000,0x000000,0x000000,0x000000, 0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x000000,0xff00ff,0xff00ff,0x000000, 0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x000000,0xff00ff,0xff00ff,0x000000, 0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x000000,0x000000,0x000000,0x000000}; WICColor palettedata[6] = {1}; const WICColor expected_palettedata[6] = { 0xff000000,0xff0000ff,0xffff0000,0xffff00ff,0xff00ff00,0xffffffff}; WICRect rc; hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder); ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); if (FAILED(hr)) return; hbmpdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(testbmp_rle4)); ok(hbmpdata != 0, "GlobalAlloc failed\n"); if (hbmpdata) { bmpdata = GlobalLock(hbmpdata); memcpy(bmpdata, testbmp_rle4, sizeof(testbmp_rle4)); GlobalUnlock(hbmpdata); hr = CreateStreamOnHGlobal(hbmpdata, FALSE, &bmpstream); ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_Initialize(decoder, bmpstream, WICDecodeMetadataCacheOnLoad); ok(hr == S_OK, "Initialize failed, hr=%x\n", hr); hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult); ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr); ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatBmp), "unexpected container format\n"); hr = IWICBitmapDecoder_GetFrameCount(decoder, &count); ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%x\n", hr); ok(count == 1, "unexpected count %u\n", count); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode); ok(SUCCEEDED(hr), "GetFrame failed, hr=%x\n", hr); if (SUCCEEDED(hr)) { IWICImagingFactory *factory; IWICPalette *palette; hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height); ok(SUCCEEDED(hr), "GetSize failed, hr=%x\n", hr); ok(width == 8, "expected width=8, got %u\n", width); ok(height == 8, "expected height=8, got %u\n", height); hr = IWICBitmapFrameDecode_GetResolution(framedecode, &dpiX, &dpiY); ok(SUCCEEDED(hr), "GetResolution failed, hr=%x\n", hr); ok(fabs(dpiX - 72.0) < 0.01, "expected dpiX=96.0, got %f\n", dpiX); ok(fabs(dpiY - 72.0) < 0.01, "expected dpiY=96.0, got %f\n", dpiY); hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &guidresult); ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%x\n", hr); ok(IsEqualGUID(&guidresult, &GUID_WICPixelFormat32bppBGR), "unexpected pixel format\n"); hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); if (SUCCEEDED(hr)) { hr = IWICImagingFactory_CreatePalette(factory, &palette); ok(SUCCEEDED(hr), "CreatePalette failed, hr=%x\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_CopyPalette(decoder, palette); ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %x\n", hr); hr = IWICBitmapFrameDecode_CopyPalette(framedecode, palette); ok(SUCCEEDED(hr), "CopyPalette failed, hr=%x\n", hr); hr = IWICPalette_GetColorCount(palette, &count); ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); ok(count == 6, "expected count=6, got %u\n", count); hr = IWICPalette_GetColors(palette, 6, palettedata, &count); ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); ok(count == 6, "expected count=6, got %u\n", count); ok(!memcmp(palettedata, expected_palettedata, sizeof(palettedata)), "unexpected palette data\n"); IWICPalette_Release(palette); } IWICImagingFactory_Release(factory); } rc.X = 0; rc.Y = 0; rc.Width = 8; rc.Height = 8; hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 32, sizeof(imagedata), (BYTE*)imagedata); ok(SUCCEEDED(hr), "CopyPixels failed, hr=%x\n", hr); ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)), "unexpected image data\n"); IWICBitmapFrameDecode_Release(framedecode); } hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder2); ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_QueryCapability(decoder2, bmpstream, &capability); ok(hr == S_OK, "QueryCapability failed, hr=%x\n", hr); ok(capability == (WICBitmapDecoderCapabilityCanDecodeAllImages), "unexpected capabilities: %x\n", capability); IWICBitmapDecoder_Release(decoder2); } IStream_Release(bmpstream); } GlobalFree(hbmpdata); } IWICBitmapDecoder_Release(decoder); }
static void test_decode_24bpp(void) { IWICBitmapDecoder *decoder, *decoder2; IWICBitmapFrameDecode *framedecode; IWICMetadataQueryReader *queryreader; IWICColorContext *colorcontext; IWICBitmapSource *thumbnail; HRESULT hr; HGLOBAL hbmpdata; char *bmpdata; IStream *bmpstream; DWORD capability=0; GUID guidresult; UINT count=0, width=0, height=0; double dpiX, dpiY; BYTE imagedata[36] = {1}; const BYTE expected_imagedata[36] = { 255,0,255, 255,255,255, 255,0,0, 255,255,0, 0,0,0, 0,255,0}; WICRect rc; hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder); ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); if (FAILED(hr)) return; hbmpdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(testbmp_24bpp)); ok(hbmpdata != 0, "GlobalAlloc failed\n"); if (hbmpdata) { bmpdata = GlobalLock(hbmpdata); memcpy(bmpdata, testbmp_24bpp, sizeof(testbmp_24bpp)); GlobalUnlock(hbmpdata); hr = CreateStreamOnHGlobal(hbmpdata, FALSE, &bmpstream); ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_Initialize(decoder, bmpstream, WICDecodeMetadataCacheOnLoad); ok(hr == S_OK || broken(hr == WINCODEC_ERR_BADIMAGE) /* XP */, "Initialize failed, hr=%x\n", hr); if (FAILED(hr)) { win_skip("BMP decoder failed to initialize\n"); GlobalFree(hbmpdata); IWICBitmapDecoder_Release(decoder); return; } hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult); ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr); ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatBmp), "unexpected container format\n"); hr = IWICBitmapDecoder_GetMetadataQueryReader(decoder, &queryreader); ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %x\n", hr); hr = IWICBitmapDecoder_GetColorContexts(decoder, 1, &colorcontext, &count); ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %x\n", hr); hr = IWICBitmapDecoder_GetThumbnail(decoder, &thumbnail); ok(hr == WINCODEC_ERR_CODECNOTHUMBNAIL, "expected WINCODEC_ERR_CODECNOTHUMBNAIL, got %x\n", hr); hr = IWICBitmapDecoder_GetPreview(decoder, &thumbnail); ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %x\n", hr); hr = IWICBitmapDecoder_GetFrameCount(decoder, &count); ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%x\n", hr); ok(count == 1, "unexpected count %u\n", count); hr = IWICBitmapDecoder_GetFrame(decoder, 1, &framedecode); ok(hr == E_INVALIDARG || hr == WINCODEC_ERR_FRAMEMISSING, "GetFrame returned %x\n", hr); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode); ok(SUCCEEDED(hr), "GetFrame failed, hr=%x\n", hr); if (SUCCEEDED(hr)) { IWICImagingFactory *factory; IWICPalette *palette; hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height); ok(SUCCEEDED(hr), "GetSize failed, hr=%x\n", hr); ok(width == 2, "expected width=2, got %u\n", width); ok(height == 3, "expected height=2, got %u\n", height); hr = IWICBitmapFrameDecode_GetResolution(framedecode, &dpiX, &dpiY); ok(SUCCEEDED(hr), "GetResolution failed, hr=%x\n", hr); ok(dpiX == 96.0, "expected dpiX=96.0, got %f\n", dpiX); ok(dpiY == 96.0, "expected dpiY=96.0, got %f\n", dpiY); hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &guidresult); ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%x\n", hr); ok(IsEqualGUID(&guidresult, &GUID_WICPixelFormat24bppBGR), "unexpected pixel format\n"); hr = IWICBitmapFrameDecode_GetMetadataQueryReader(framedecode, &queryreader); ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %x\n", hr); hr = IWICBitmapFrameDecode_GetColorContexts(framedecode, 1, &colorcontext, &count); ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %x\n", hr); hr = IWICBitmapFrameDecode_GetThumbnail(framedecode, &thumbnail); ok(hr == WINCODEC_ERR_CODECNOTHUMBNAIL, "expected WINCODEC_ERR_CODECNOTHUMBNAIL, got %x\n", hr); hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); if (SUCCEEDED(hr)) { hr = IWICImagingFactory_CreatePalette(factory, &palette); ok(SUCCEEDED(hr), "CreatePalette failed, hr=%x\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_CopyPalette(decoder, palette); ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %x\n", hr); hr = IWICBitmapFrameDecode_CopyPalette(framedecode, palette); ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %x\n", hr); IWICPalette_Release(palette); } IWICImagingFactory_Release(factory); } rc.X = 0; rc.Y = 0; rc.Width = 3; rc.Height = 3; hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 6, sizeof(imagedata), imagedata); ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); rc.X = -1; rc.Y = 0; rc.Width = 2; rc.Height = 3; hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 6, sizeof(imagedata), imagedata); ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); rc.X = 0; rc.Y = 0; rc.Width = 2; rc.Height = 3; hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 4, sizeof(imagedata), imagedata); ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); rc.X = 0; rc.Y = 0; rc.Width = 2; rc.Height = 3; hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 4, 5, imagedata); ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); rc.X = 0; rc.Y = 0; rc.Width = 2; rc.Height = 3; hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 6, sizeof(imagedata), imagedata); ok(SUCCEEDED(hr), "CopyPixels failed, hr=%x\n", hr); ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)), "unexpected image data\n"); hr = IWICBitmapFrameDecode_CopyPixels(framedecode, NULL, 6, sizeof(imagedata), imagedata); ok(SUCCEEDED(hr), "CopyPixels(rect=NULL) failed, hr=%x\n", hr); ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)), "unexpected image data\n"); IWICBitmapFrameDecode_Release(framedecode); } /* cannot initialize twice */ hr = IWICBitmapDecoder_Initialize(decoder, bmpstream, WICDecodeMetadataCacheOnLoad); ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%x\n", hr); /* cannot querycapability after initialize */ hr = IWICBitmapDecoder_QueryCapability(decoder, bmpstream, &capability); ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%x\n", hr); hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder2); ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_QueryCapability(decoder2, bmpstream, &capability); ok(hr == S_OK, "QueryCapability failed, hr=%x\n", hr); ok(capability == (WICBitmapDecoderCapabilityCanDecodeAllImages), "unexpected capabilities: %x\n", capability); /* cannot initialize after querycapability */ hr = IWICBitmapDecoder_Initialize(decoder2, bmpstream, WICDecodeMetadataCacheOnLoad); ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%x\n", hr); /* cannot querycapability twice */ hr = IWICBitmapDecoder_QueryCapability(decoder2, bmpstream, &capability); ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%x\n", hr); IWICBitmapDecoder_Release(decoder2); } IStream_Release(bmpstream); } GlobalFree(hbmpdata); } IWICBitmapDecoder_Release(decoder); }
int ReadPictureWithWIC(const char* const filename, WebPPicture* const pic, int keep_alpha, Metadata* const metadata) { // From Microsoft SDK 6.0a -- ks.h // Define a local copy to avoid link errors under mingw. WEBP_DEFINE_GUID(GUID_NULL_, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); static const WICFormatImporter kAlphaFormatImporters[] = { { &GUID_WICPixelFormat32bppBGRA_, 4, WebPPictureImportBGRA }, { &GUID_WICPixelFormat32bppRGBA_, 4, WebPPictureImportRGBA }, { NULL, 0, NULL }, }; static const WICFormatImporter kNonAlphaFormatImporters[] = { { &GUID_WICPixelFormat24bppBGR_, 3, WebPPictureImportBGR }, { &GUID_WICPixelFormat24bppRGB_, 3, WebPPictureImportRGB }, { NULL, 0, NULL }, }; HRESULT hr = S_OK; IWICBitmapFrameDecode* frame = NULL; IWICFormatConverter* converter = NULL; IWICImagingFactory* factory = NULL; IWICBitmapDecoder* decoder = NULL; IStream* stream = NULL; UINT frame_count = 0; UINT width = 0, height = 0; BYTE* rgb = NULL; WICPixelFormatGUID src_pixel_format = GUID_WICPixelFormatUndefined; const WICFormatImporter* importer = NULL; GUID src_container_format = GUID_NULL_; static const GUID* kAlphaContainers[] = { &GUID_ContainerFormatBmp, &GUID_ContainerFormatPng, &GUID_ContainerFormatTiff, NULL }; int has_alpha = 0; int64_t stride; IFS(CoInitialize(NULL)); IFS(CoCreateInstance(MAKE_REFGUID(CLSID_WICImagingFactory), NULL, CLSCTX_INPROC_SERVER, MAKE_REFGUID(IID_IWICImagingFactory), (LPVOID*)&factory)); if (hr == REGDB_E_CLASSNOTREG) { fprintf(stderr, "Couldn't access Windows Imaging Component (are you running " "Windows XP SP3 or newer?). Most formats not available. " "Use -s for the available YUV input.\n"); } // Prepare for image decoding. IFS(OpenInputStream(filename, &stream)); IFS(IWICImagingFactory_CreateDecoderFromStream( factory, stream, NULL, WICDecodeMetadataCacheOnDemand, &decoder)); IFS(IWICBitmapDecoder_GetFrameCount(decoder, &frame_count)); if (SUCCEEDED(hr) && frame_count == 0) { fprintf(stderr, "No frame found in input file.\n"); hr = E_FAIL; } IFS(IWICBitmapDecoder_GetFrame(decoder, 0, &frame)); IFS(IWICBitmapFrameDecode_GetPixelFormat(frame, &src_pixel_format)); IFS(IWICBitmapDecoder_GetContainerFormat(decoder, &src_container_format)); if (SUCCEEDED(hr) && keep_alpha) { const GUID** guid; for (guid = kAlphaContainers; *guid != NULL; ++guid) { if (IsEqualGUID(MAKE_REFGUID(src_container_format), MAKE_REFGUID(**guid))) { has_alpha = HasAlpha(factory, decoder, frame, src_pixel_format); break; } } } // Prepare for pixel format conversion (if necessary). IFS(IWICImagingFactory_CreateFormatConverter(factory, &converter)); for (importer = has_alpha ? kAlphaFormatImporters : kNonAlphaFormatImporters; hr == S_OK && importer->import != NULL; ++importer) { BOOL can_convert; const HRESULT cchr = IWICFormatConverter_CanConvert( converter, MAKE_REFGUID(src_pixel_format), MAKE_REFGUID(*importer->pixel_format), &can_convert); if (SUCCEEDED(cchr) && can_convert) break; } if (importer->import == NULL) hr = E_FAIL; IFS(IWICFormatConverter_Initialize(converter, (IWICBitmapSource*)frame, importer->pixel_format, WICBitmapDitherTypeNone, NULL, 0.0, WICBitmapPaletteTypeCustom)); // Decode. IFS(IWICFormatConverter_GetSize(converter, &width, &height)); stride = (int64_t)importer->bytes_per_pixel * width * sizeof(*rgb); if (stride != (int)stride || !ImgIoUtilCheckSizeArgumentsOverflow(stride, height)) { hr = E_FAIL; } if (SUCCEEDED(hr)) { rgb = (BYTE*)malloc((size_t)stride * height); if (rgb == NULL) hr = E_OUTOFMEMORY; } IFS(IWICFormatConverter_CopyPixels(converter, NULL, (UINT)stride, (UINT)stride * height, rgb)); // WebP conversion. if (SUCCEEDED(hr)) { int ok; pic->width = width; pic->height = height; pic->use_argb = 1; // For WIC, we always force to argb ok = importer->import(pic, rgb, (int)stride); if (!ok) hr = E_FAIL; } if (SUCCEEDED(hr)) { if (metadata != NULL) { hr = ExtractMetadata(factory, frame, metadata); if (FAILED(hr)) { fprintf(stderr, "Error extracting image metadata using WIC!\n"); } } } // Cleanup. if (converter != NULL) IUnknown_Release(converter); if (frame != NULL) IUnknown_Release(frame); if (decoder != NULL) IUnknown_Release(decoder); if (factory != NULL) IUnknown_Release(factory); if (stream != NULL) IUnknown_Release(stream); free(rgb); return SUCCEEDED(hr); }
static HRESULT ReadPictureWithWIC(const char* filename, WebPPicture* const pic, int keep_alpha) { HRESULT hr = S_OK; IWICBitmapFrameDecode* pFrame = NULL; IWICFormatConverter* pConverter = NULL; IWICImagingFactory* pFactory = NULL; IWICBitmapDecoder* pDecoder = NULL; IStream* pStream = NULL; UINT frameCount = 0; UINT width, height = 0; BYTE* rgb = NULL; WICPixelFormatGUID srcPixelFormat = { 0 }; GUID srcContainerFormat = { 0 }; const GUID* alphaContainers[] = { &GUID_ContainerFormatBmp, &GUID_ContainerFormatPng, &GUID_ContainerFormatTiff }; int has_alpha = 0; int i, stride; IFS(CoInitialize(NULL)); IFS(CoCreateInstance(MAKE_REFGUID(CLSID_WICImagingFactory), NULL, CLSCTX_INPROC_SERVER, MAKE_REFGUID(IID_IWICImagingFactory), (LPVOID*)&pFactory)); if (hr == REGDB_E_CLASSNOTREG) { printf("Couldn't access Windows Imaging Component (are you running \n"); printf("Windows XP SP3 or newer?). Most formats not available.\n"); printf("Use -s for the available YUV input.\n"); } // Prepare for image decoding. IFS(OpenInputStream(filename, &pStream)); IFS(IWICImagingFactory_CreateDecoderFromStream(pFactory, pStream, NULL, WICDecodeMetadataCacheOnDemand, &pDecoder)); IFS(IWICBitmapDecoder_GetFrameCount(pDecoder, &frameCount)); if (SUCCEEDED(hr) && frameCount == 0) { printf("No frame found in input file.\n"); hr = E_FAIL; } IFS(IWICBitmapDecoder_GetFrame(pDecoder, 0, &pFrame)); IFS(IWICBitmapFrameDecode_GetPixelFormat(pFrame, &srcPixelFormat)); IFS(IWICBitmapDecoder_GetContainerFormat(pDecoder, &srcContainerFormat)); has_alpha = keep_alpha; for (i = 0; has_alpha && i < sizeof(alphaContainers)/sizeof(alphaContainers[0]); ++i) { if (IsEqualGUID(&srcContainerFormat, alphaContainers[i])) { has_alpha = IsEqualGUID(&srcPixelFormat, &GUID_WICPixelFormat32bppRGBA) || IsEqualGUID(&srcPixelFormat, &GUID_WICPixelFormat32bppBGRA); break; } } // Prepare for pixel format conversion (if necessary). IFS(IWICImagingFactory_CreateFormatConverter(pFactory, &pConverter)); IFS(IWICFormatConverter_Initialize(pConverter, (IWICBitmapSource*)pFrame, has_alpha ? MAKE_REFGUID(GUID_WICPixelFormat32bppRGBA) : MAKE_REFGUID(GUID_WICPixelFormat24bppRGB), WICBitmapDitherTypeNone, NULL, 0.0, WICBitmapPaletteTypeCustom)); // Decode. IFS(IWICFormatConverter_GetSize(pConverter, &width, &height)); stride = (has_alpha ? 4 : 3) * width * sizeof(*rgb); if (SUCCEEDED(hr)) { rgb = (BYTE*)malloc(stride * height); if (rgb == NULL) hr = E_OUTOFMEMORY; } IFS(IWICFormatConverter_CopyPixels(pConverter, NULL, stride, stride * height, rgb)); // WebP conversion. if (SUCCEEDED(hr)) { int ok; #ifdef WEBP_EXPERIMENTAL_FEATURES if (has_alpha) { pic->colorspace |= WEBP_CSP_ALPHA_BIT; } #endif pic->width = width; pic->height = height; ok = has_alpha ? WebPPictureImportRGBA(pic, rgb, stride) : WebPPictureImportRGB(pic, rgb, stride); if (!ok) hr = E_FAIL; } // Cleanup. if (pConverter != NULL) IUnknown_Release(pConverter); if (pFrame != NULL) IUnknown_Release(pFrame); if (pDecoder != NULL) IUnknown_Release(pDecoder); if (pFactory != NULL) IUnknown_Release(pFactory); if (pStream != NULL) IUnknown_Release(pStream); free(rgb); return hr; }