static void test_global_gif_palette(void) { HRESULT hr; IWICBitmapDecoder *decoder; IWICBitmapFrameDecode *frame; IWICPalette *palette; GUID format; UINT count, ret; WICColor color[256]; decoder = create_decoder(gif_global_palette, sizeof(gif_global_palette)); ok(decoder != 0, "Failed to load GIF image data\n"); hr = IWICImagingFactory_CreatePalette(factory, &palette); ok(hr == S_OK, "CreatePalette error %#x\n", hr); /* global palette */ hr = IWICBitmapDecoder_CopyPalette(decoder, palette); ok(hr == S_OK, "CopyPalette error %#x\n", hr); hr = IWICPalette_GetColorCount(palette, &count); ok(hr == S_OK, "GetColorCount error %#x\n", hr); ok(count == 4, "expected 4, got %u\n", count); hr = IWICPalette_GetColors(palette, count, color, &ret); ok(hr == S_OK, "GetColors error %#x\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]); ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]); ok(color[2] == 0xff070809, "expected 0xff070809, got %#x\n", color[2]); ok(color[3] == 0xff0a0b0c, "expected 0xff0a0b0c, got %#x\n", color[3]); /* frame palette */ hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); ok(hr == S_OK, "GetFrame error %#x\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed), "wrong pixel format %s\n", wine_dbgstr_guid(&format)); hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); ok(hr == S_OK, "CopyPalette error %#x\n", hr); hr = IWICPalette_GetColorCount(palette, &count); ok(hr == S_OK, "GetColorCount error %#x\n", hr); ok(count == 4, "expected 4, got %u\n", count); hr = IWICPalette_GetColors(palette, count, color, &ret); ok(hr == S_OK, "GetColors error %#x\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]); ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]); ok(color[2] == 0xff070809, "expected 0xff070809, got %#x\n", color[2]); ok(color[3] == 0xff0a0b0c, "expected 0xff0a0b0c, got %#x\n", color[3]); IWICPalette_Release(palette); IWICBitmapFrameDecode_Release(frame); IWICBitmapDecoder_Release(decoder); }
static void test_color_formats(void) { static const struct { char bit_depth, color_type; const GUID *format; } td[] = { /* 2 - PNG_COLOR_TYPE_RGB */ { 8, 2, &GUID_WICPixelFormat24bppBGR }, /* 0 - PNG_COLOR_TYPE_GRAY */ { 1, 0, &GUID_WICPixelFormatBlackWhite }, { 2, 0, &GUID_WICPixelFormat2bppGray }, { 4, 0, &GUID_WICPixelFormat4bppGray }, { 8, 0, &GUID_WICPixelFormat8bppGray }, { 16, 0, &GUID_WICPixelFormat16bppGray }, }; char buf[sizeof(png_1x1_data)]; HRESULT hr; IWICBitmapDecoder *decoder; IWICBitmapFrameDecode *frame; GUID format; int i; for (i = 0; i < sizeof(td)/sizeof(td[0]); i++) { memcpy(buf, png_1x1_data, sizeof(png_1x1_data)); buf[24] = td[i].bit_depth; buf[25] = td[i].color_type; decoder = create_decoder(buf, sizeof(buf)); ok(decoder != NULL, "Failed to load PNG image data\n"); if (!decoder) continue; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); ok(hr == S_OK, "GetFrame error %#x\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); ok(IsEqualGUID(&format, td[i].format), "expected %s, got %s\n", wine_dbgstr_guid(td[i].format), wine_dbgstr_guid(&format)); IWICBitmapFrameDecode_Release(frame); IWICBitmapDecoder_Release(decoder); } }
static void test_png_palette(void) { HRESULT hr; IWICBitmapDecoder *decoder; IWICBitmapFrameDecode *frame; IWICPalette *palette; GUID format; UINT count, ret; WICColor color[256]; decoder = create_decoder(png_PLTE_tRNS, sizeof(png_PLTE_tRNS)); ok(decoder != 0, "Failed to load PNG image data\n"); if (!decoder) return; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); ok(hr == S_OK, "GetFrame error %#x\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat1bppIndexed), "got wrong format %s\n", wine_dbgstr_guid(&format)); hr = IWICImagingFactory_CreatePalette(factory, &palette); ok(hr == S_OK, "CreatePalette error %#x\n", hr); hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); ok(hr == S_OK, "CopyPalette error %#x\n", hr); hr = IWICPalette_GetColorCount(palette, &count); ok(hr == S_OK, "GetColorCount error %#x\n", hr); ok(count == 2, "expected 2, got %u\n", count); hr = IWICPalette_GetColors(palette, 256, color, &ret); ok(hr == S_OK, "GetColors error %#x\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]); ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]); IWICPalette_Release(palette); IWICBitmapFrameDecode_Release(frame); IWICBitmapDecoder_Release(decoder); }
static void test_local_gif_palette(void) { HRESULT hr; IWICBitmapDecoder *decoder; IWICBitmapFrameDecode *frame; IWICPalette *palette; WICBitmapPaletteType type; GUID format; UINT count, ret, i; WICColor color[256]; decoder = create_decoder(gif_local_palette, sizeof(gif_local_palette)); ok(decoder != 0, "Failed to load GIF image data\n"); hr = IWICImagingFactory_CreatePalette(factory, &palette); ok(hr == S_OK, "CreatePalette error %#x\n", hr); /* global palette */ hr = IWICBitmapDecoder_CopyPalette(decoder, palette); ok(hr == S_OK || broken(hr == WINCODEC_ERR_FRAMEMISSING), "CopyPalette %#x\n", hr); if (hr == S_OK) { type = -1; hr = IWICPalette_GetType(palette, &type); ok(hr == S_OK, "GetType error %#x\n", hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type); hr = IWICPalette_GetColorCount(palette, &count); ok(hr == S_OK, "GetColorCount error %#x\n", hr); ok(count == 256, "expected 256, got %u\n", count); hr = IWICPalette_GetColors(palette, count, color, &ret); ok(hr == S_OK, "GetColors error %#x\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff000000, "expected 0xff000000, got %#x\n", color[0]); ok(color[1] == 0x00ffffff, "expected 0x00ffffff, got %#x\n", color[1]); for (i = 2; i < 256; i++) ok(color[i] == 0xff000000, "expected 0xff000000, got %#x\n", color[i]); } /* frame palette */ hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); ok(hr == S_OK, "GetFrame error %#x\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed), "wrong pixel format %s\n", wine_dbgstr_guid(&format)); hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); ok(hr == S_OK, "CopyPalette error %#x\n", hr); hr = IWICPalette_GetColorCount(palette, &count); ok(hr == S_OK, "GetColorCount error %#x\n", hr); ok(count == 4, "expected 4, got %u\n", count); type = -1; hr = IWICPalette_GetType(palette, &type); ok(hr == S_OK, "GetType error %#x\n", hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type); hr = IWICPalette_GetColors(palette, count, color, &ret); ok(hr == S_OK, "GetColors error %#x\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]); ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]); ok(color[2] == 0xff070809, "expected 0xff070809, got %#x\n", color[2]); ok(color[3] == 0xff0a0b0c, "expected 0xff0a0b0c, got %#x\n", color[3]); IWICPalette_Release(palette); IWICBitmapFrameDecode_Release(frame); IWICBitmapDecoder_Release(decoder); }
HBITMAP LoadImageFromResources( _In_ UINT Width, _In_ UINT Height, _In_ PCWSTR Name ) { UINT width = 0; UINT height = 0; UINT frameCount = 0; BOOLEAN isSuccess = FALSE; ULONG resourceLength = 0; HGLOBAL resourceHandle = NULL; HRSRC resourceHandleSource = NULL; WICInProcPointer resourceBuffer = NULL; BITMAPINFO bitmapInfo = { 0 }; HBITMAP bitmapHandle = NULL; PBYTE bitmapBuffer = NULL; IWICStream* wicStream = NULL; IWICBitmapSource* wicBitmapSource = NULL; IWICBitmapDecoder* wicDecoder = NULL; IWICBitmapFrameDecode* wicFrame = NULL; IWICImagingFactory* wicFactory = NULL; IWICBitmapScaler* wicScaler = NULL; WICPixelFormatGUID pixelFormat; WICRect rect = { 0, 0, Width, Height }; __try { // Create the ImagingFactory if (FAILED(CoCreateInstance(&CLSID_WICImagingFactory1, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, &wicFactory))) __leave; // Find the resource if ((resourceHandleSource = FindResource(PluginInstance->DllBase, Name, L"PNG")) == NULL) __leave; // Get the resource length resourceLength = SizeofResource(PluginInstance->DllBase, resourceHandleSource); // Load the resource if ((resourceHandle = LoadResource(PluginInstance->DllBase, resourceHandleSource)) == NULL) __leave; if ((resourceBuffer = (WICInProcPointer)LockResource(resourceHandle)) == NULL) __leave; // Create the Stream if (FAILED(IWICImagingFactory_CreateStream(wicFactory, &wicStream))) __leave; // Initialize the Stream from Memory if (FAILED(IWICStream_InitializeFromMemory(wicStream, resourceBuffer, resourceLength))) __leave; if (FAILED(IWICImagingFactory_CreateDecoder(wicFactory, &GUID_ContainerFormatPng, NULL, &wicDecoder))) __leave; if (FAILED(IWICBitmapDecoder_Initialize(wicDecoder, (IStream*)wicStream, WICDecodeMetadataCacheOnLoad))) __leave; // Get the Frame count if (FAILED(IWICBitmapDecoder_GetFrameCount(wicDecoder, &frameCount)) || frameCount < 1) __leave; // Get the Frame if (FAILED(IWICBitmapDecoder_GetFrame(wicDecoder, 0, &wicFrame))) __leave; // Get the WicFrame image format if (FAILED(IWICBitmapFrameDecode_GetPixelFormat(wicFrame, &pixelFormat))) __leave; // Check if the image format is supported: if (IsEqualGUID(&pixelFormat, &GUID_WICPixelFormat32bppPBGRA)) // GUID_WICPixelFormat32bppRGB { wicBitmapSource = (IWICBitmapSource*)wicFrame; } else { // Convert the image to the correct format: if (FAILED(WICConvertBitmapSource(&GUID_WICPixelFormat32bppPBGRA, (IWICBitmapSource*)wicFrame, &wicBitmapSource))) __leave; IWICBitmapFrameDecode_Release(wicFrame); } bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bitmapInfo.bmiHeader.biWidth = rect.Width; bitmapInfo.bmiHeader.biHeight = -((LONG)rect.Height); bitmapInfo.bmiHeader.biPlanes = 1; bitmapInfo.bmiHeader.biBitCount = 32; bitmapInfo.bmiHeader.biCompression = BI_RGB; HDC hdc = CreateCompatibleDC(NULL); bitmapHandle = CreateDIBSection(hdc, &bitmapInfo, DIB_RGB_COLORS, (PVOID*)&bitmapBuffer, NULL, 0); ReleaseDC(NULL, hdc); // Check if it's the same rect as the requested size. //if (width != rect.Width || height != rect.Height) if (FAILED(IWICImagingFactory_CreateBitmapScaler(wicFactory, &wicScaler))) __leave; if (FAILED(IWICBitmapScaler_Initialize(wicScaler, wicBitmapSource, rect.Width, rect.Height, WICBitmapInterpolationModeFant))) __leave; if (FAILED(IWICBitmapScaler_CopyPixels(wicScaler, &rect, rect.Width * 4, rect.Width * rect.Height * 4, bitmapBuffer))) __leave; isSuccess = TRUE; } __finally { if (wicScaler) { IWICBitmapScaler_Release(wicScaler); } if (wicBitmapSource) { IWICBitmapSource_Release(wicBitmapSource); } if (wicStream) { IWICStream_Release(wicStream); } if (wicDecoder) { IWICBitmapDecoder_Release(wicDecoder); } if (wicFactory) { IWICImagingFactory_Release(wicFactory); } if (resourceHandle) { FreeResource(resourceHandle); } } return bitmapHandle; }
HRESULT WINAPI IWICBitmapDecoder_GetFrame_Proxy_W(IWICBitmapDecoder *iface, UINT index, IWICBitmapFrameDecode **ppIBitmapFrame) { return IWICBitmapDecoder_GetFrame(iface, index, ppIBitmapFrame); }
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); }
static void test_gif_notrailer(void) { IWICBitmapDecoder *decoder; IWICImagingFactory *factory; HRESULT hr; IWICStream *gifstream; IWICBitmapFrameDecode *framedecode; double dpiX = 0.0, dpiY = 0.0; UINT framecount; hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); if (FAILED(hr)) return; hr = IWICImagingFactory_CreateStream(factory, &gifstream); ok(hr == S_OK, "CreateStream failed, hr=%x\n", hr); if (SUCCEEDED(hr)) { hr = IWICStream_InitializeFromMemory(gifstream, gifimage_notrailer, sizeof(gifimage_notrailer)); ok(hr == S_OK, "InitializeFromMemory failed, hr=%x\n", hr); if (SUCCEEDED(hr)) { hr = CoCreateInstance(&CLSID_WICGifDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder); ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); } if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_Initialize(decoder, (IStream*)gifstream, WICDecodeMetadataCacheOnDemand); ok(hr == S_OK, "Initialize failed, hr=%x\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode); ok(hr == S_OK, "GetFrame failed, hr=%x\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapFrameDecode_GetResolution(framedecode, &dpiX, &dpiY); ok(SUCCEEDED(hr), "GetResolution failed, hr=%x\n", hr); ok(dpiX == 48.0, "expected dpiX=48.0, got %f\n", dpiX); ok(dpiY == 96.0, "expected dpiY=96.0, got %f\n", dpiY); IWICBitmapFrameDecode_Release(framedecode); } } if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_GetFrameCount(decoder, &framecount); ok(hr == S_OK, "GetFrameCount failed, hr=%x\n", hr); ok(framecount == 1, "framecount=%u\n", framecount); } IWICBitmapDecoder_Release(decoder); } IWICStream_Release(gifstream); } IWICImagingFactory_Release(factory); }
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 void test_color_contexts(void) { HRESULT hr; IWICBitmapDecoder *decoder; IWICBitmapFrameDecode *frame; IWICColorContext *context; WICColorContextType type; UINT count, colorspace, size; WCHAR *tmpfile; BYTE *buffer; BOOL ret; decoder = create_decoder(png_no_color_profile, sizeof(png_no_color_profile)); ok(decoder != 0, "Failed to load PNG image data\n"); if (!decoder) return; /* global color context */ hr = IWICBitmapDecoder_GetColorContexts(decoder, 0, NULL, NULL); ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetColorContexts error %#x\n", hr); count = 0xdeadbeef; hr = IWICBitmapDecoder_GetColorContexts(decoder, 0, NULL, &count); ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetColorContexts error %#x\n", hr); ok(count == 0xdeadbeef, "unexpected count %u\n", count); /* frame color context */ hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); ok(hr == S_OK, "GetFrame error %#x\n", hr); hr = IWICBitmapFrameDecode_GetColorContexts(frame, 0, NULL, NULL); ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); count = 0xdeadbeef; hr = IWICBitmapFrameDecode_GetColorContexts(frame, 0, NULL, &count); ok(hr == S_OK, "GetColorContexts error %#x\n", hr); ok(!count, "unexpected count %u\n", count); IWICBitmapFrameDecode_Release(frame); IWICBitmapDecoder_Release(decoder); decoder = create_decoder(png_color_profile, sizeof(png_color_profile)); ok(decoder != 0, "Failed to load PNG image data\n"); if (!decoder) return; /* global color context */ count = 0xdeadbeef; hr = IWICBitmapDecoder_GetColorContexts(decoder, 0, NULL, &count); ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetColorContexts error %#x\n", hr); ok(count == 0xdeadbeef, "unexpected count %u\n", count); /* frame color context */ hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); ok(hr == S_OK, "GetFrame error %#x\n", hr); count = 0xdeadbeef; hr = IWICBitmapFrameDecode_GetColorContexts(frame, 0, NULL, &count); ok(hr == S_OK, "GetColorContexts error %#x\n", hr); ok(count == 1, "unexpected count %u\n", count); hr = IWICImagingFactory_CreateColorContext(factory, NULL); ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); hr = IWICImagingFactory_CreateColorContext(factory, &context); ok(hr == S_OK, "CreateColorContext error %#x\n", hr); hr = IWICColorContext_GetType(context, NULL); ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); type = 0xdeadbeef; hr = IWICColorContext_GetType(context, &type); ok(hr == S_OK, "GetType error %#x\n", hr); ok(type == WICColorContextUninitialized, "unexpected type %u\n", type); hr = IWICColorContext_GetProfileBytes(context, 0, NULL, NULL); ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetProfileBytes error %#x\n", hr); size = 0; hr = IWICColorContext_GetProfileBytes(context, 0, NULL, &size); ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetProfileBytes error %#x\n", hr); ok(!size, "unexpected size %u\n", size); hr = IWICColorContext_GetExifColorSpace(context, NULL); ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); colorspace = 0xdeadbeef; hr = IWICColorContext_GetExifColorSpace(context, &colorspace); ok(hr == S_OK, "GetExifColorSpace error %#x\n", hr); ok(colorspace == 0xffffffff, "unexpected color space %u\n", colorspace); hr = IWICColorContext_InitializeFromExifColorSpace(context, 0); ok(hr == S_OK, "InitializeFromExifColorSpace error %#x\n", hr); hr = IWICColorContext_InitializeFromExifColorSpace(context, 1); ok(hr == S_OK, "InitializeFromExifColorSpace error %#x\n", hr); hr = IWICColorContext_InitializeFromExifColorSpace(context, 2); ok(hr == S_OK, "InitializeFromExifColorSpace error %#x\n", hr); colorspace = 0xdeadbeef; hr = IWICColorContext_GetExifColorSpace(context, &colorspace); ok(hr == S_OK, "GetExifColorSpace error %#x\n", hr); ok(colorspace == 2, "unexpected color space %u\n", colorspace); size = 0; hr = IWICColorContext_GetProfileBytes(context, 0, NULL, &size); ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetProfileBytes error %#x\n", hr); ok(!size, "unexpected size %u\n", size); type = 0xdeadbeef; hr = IWICColorContext_GetType(context, &type); ok(hr == S_OK, "GetType error %#x\n", hr); ok(type == WICColorContextExifColorSpace, "unexpected type %u\n", type); hr = IWICBitmapFrameDecode_GetColorContexts(frame, count, &context, &count); ok(hr == WINCODEC_ERR_WRONGSTATE, "GetColorContexts error %#x\n", hr); IWICColorContext_Release(context); IWICBitmapFrameDecode_Release(frame); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); ok(hr == S_OK, "GetFrame error %#x\n", hr); hr = IWICImagingFactory_CreateColorContext(factory, &context); ok(hr == S_OK, "CreateColorContext error %#x\n", hr); count = 1; hr = IWICBitmapFrameDecode_GetColorContexts(frame, count, &context, &count); ok(hr == S_OK, "GetColorContexts error %#x\n", hr); hr = IWICColorContext_GetProfileBytes(context, 0, NULL, NULL); ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); size = 0; hr = IWICColorContext_GetProfileBytes(context, 0, NULL, &size); ok(hr == S_OK, "GetProfileBytes error %#x\n", hr); ok(size, "unexpected size %u\n", size); buffer = HeapAlloc(GetProcessHeap(), 0, size); hr = IWICColorContext_GetProfileBytes(context, size, buffer, &size); ok(hr == S_OK, "GetProfileBytes error %#x\n", hr); tmpfile = save_profile( buffer, size ); HeapFree(GetProcessHeap(), 0, buffer); type = 0xdeadbeef; hr = IWICColorContext_GetType(context, &type); ok(hr == S_OK, "GetType error %#x\n", hr); ok(type == WICColorContextProfile, "unexpected type %u\n", type); colorspace = 0xdeadbeef; hr = IWICColorContext_GetExifColorSpace(context, &colorspace); ok(hr == S_OK, "GetExifColorSpace error %#x\n", hr); ok(colorspace == 0xffffffff, "unexpected color space %u\n", colorspace); hr = IWICColorContext_InitializeFromExifColorSpace(context, 1); ok(hr == WINCODEC_ERR_WRONGSTATE, "InitializeFromExifColorSpace error %#x\n", hr); if (tmpfile) { hr = IWICColorContext_InitializeFromFilename(context, NULL); ok(hr == E_INVALIDARG, "InitializeFromFilename error %#x\n", hr); hr = IWICColorContext_InitializeFromFilename(context, tmpfile); ok(hr == S_OK, "InitializeFromFilename error %#x\n", hr); ret = DeleteFileW(tmpfile); ok(ret, "DeleteFileW failed %u\n", GetLastError()); type = 0xdeadbeef; hr = IWICColorContext_GetType(context, &type); ok(hr == S_OK, "GetType error %#x\n", hr); ok(type == WICColorContextProfile, "unexpected type %u\n", type); colorspace = 0xdeadbeef; hr = IWICColorContext_GetExifColorSpace(context, &colorspace); ok(hr == S_OK, "GetExifColorSpace error %#x\n", hr); ok(colorspace == 0xffffffff, "unexpected color space %u\n", colorspace); hr = IWICColorContext_InitializeFromExifColorSpace(context, 1); ok(hr == WINCODEC_ERR_WRONGSTATE, "InitializeFromExifColorSpace error %#x\n", hr); size = 0; hr = IWICColorContext_GetProfileBytes(context, 0, NULL, &size); ok(hr == S_OK, "GetProfileBytes error %#x\n", hr); ok(size, "unexpected size %u\n", size); buffer = HeapAlloc(GetProcessHeap(), 0, size); hr = IWICColorContext_GetProfileBytes(context, size, buffer, &size); ok(hr == S_OK, "GetProfileBytes error %#x\n", hr); HeapFree(GetProcessHeap(), 0, buffer); HeapFree(GetProcessHeap(), 0, tmpfile); } IWICColorContext_Release(context); IWICBitmapFrameDecode_Release(frame); IWICBitmapDecoder_Release(decoder); }
static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* clsid_encoder, const struct bitmap_data **dsts, const CLSID *clsid_decoder, const char *name) { HRESULT hr; IWICBitmapEncoder *encoder; BitmapTestSrc *src_obj; HGLOBAL hglobal; IStream *stream; IWICBitmapFrameEncode *frameencode; IPropertyBag2 *options=NULL; IWICBitmapDecoder *decoder; IWICBitmapFrameDecode *framedecode; WICPixelFormatGUID pixelformat; int i; hr = CoCreateInstance(clsid_encoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapEncoder, (void**)&encoder); ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); if (SUCCEEDED(hr)) { hglobal = GlobalAlloc(GMEM_MOVEABLE, 0); ok(hglobal != NULL, "GlobalAlloc failed\n"); if (hglobal) { hr = CreateStreamOnHGlobal(hglobal, TRUE, &stream); ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr); } if (hglobal && SUCCEEDED(hr)) { hr = IWICBitmapEncoder_Initialize(encoder, stream, WICBitmapEncoderNoCache); ok(SUCCEEDED(hr), "Initialize failed, hr=%x\n", hr); i=0; while (SUCCEEDED(hr) && srcs[i]) { CreateTestBitmap(srcs[i], &src_obj); hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frameencode, &options); ok(SUCCEEDED(hr), "CreateFrame failed, hr=%x\n", hr); if (SUCCEEDED(hr)) { ok(options != NULL, "Encoder initialization has not created an property bag\n"); if(options) test_encoder_properties(clsid_encoder, options); hr = IWICBitmapFrameEncode_Initialize(frameencode, options); ok(SUCCEEDED(hr), "Initialize failed, hr=%x\n", hr); memcpy(&pixelformat, srcs[i]->format, sizeof(GUID)); hr = IWICBitmapFrameEncode_SetPixelFormat(frameencode, &pixelformat); ok(SUCCEEDED(hr), "SetPixelFormat failed, hr=%x\n", hr); ok(IsEqualGUID(&pixelformat, srcs[i]->format), "SetPixelFormat changed the format\n"); hr = IWICBitmapFrameEncode_SetSize(frameencode, srcs[i]->width, srcs[i]->height); ok(SUCCEEDED(hr), "SetSize failed, hr=%x\n", hr); hr = IWICBitmapFrameEncode_WriteSource(frameencode, &src_obj->IWICBitmapSource_iface, NULL); ok(SUCCEEDED(hr), "WriteSource failed, hr=%x\n", hr); hr = IWICBitmapFrameEncode_Commit(frameencode); ok(SUCCEEDED(hr), "Commit failed, hr=%x\n", hr); IWICBitmapFrameEncode_Release(frameencode); IPropertyBag2_Release(options); } DeleteTestBitmap(src_obj); i++; } if (SUCCEEDED(hr)) { hr = IWICBitmapEncoder_Commit(encoder); ok(SUCCEEDED(hr), "Commit failed, hr=%x\n", hr); } if (SUCCEEDED(hr)) { hr = CoCreateInstance(clsid_decoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder); ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); } if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnDemand); ok(SUCCEEDED(hr), "Initialize failed, hr=%x\n", hr); i=0; while (SUCCEEDED(hr) && dsts[i]) { hr = IWICBitmapDecoder_GetFrame(decoder, i, &framedecode); ok(SUCCEEDED(hr), "GetFrame failed, hr=%x\n", hr); if (SUCCEEDED(hr)) { compare_bitmap_data(dsts[i], (IWICBitmapSource*)framedecode, name); IWICBitmapFrameDecode_Release(framedecode); } i++; } IWICBitmapDecoder_Release(decoder); } IStream_Release(stream); } IWICBitmapEncoder_Release(encoder); } }
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; }
HBITMAP LoadPngImageFromResources( _In_ PCWSTR Name ) { BOOLEAN success = FALSE; UINT frameCount = 0; ULONG resourceLength = 0; HGLOBAL resourceHandle = NULL; HRSRC resourceHandleSource = NULL; WICInProcPointer resourceBuffer = NULL; HDC screenHdc = NULL; HDC bufferDc = NULL; BITMAPINFO bitmapInfo = { 0 }; HBITMAP bitmapHandle = NULL; PVOID bitmapBuffer = NULL; IWICStream* wicStream = NULL; IWICBitmapSource* wicBitmapSource = NULL; IWICBitmapDecoder* wicDecoder = NULL; IWICBitmapFrameDecode* wicFrame = NULL; IWICImagingFactory* wicFactory = NULL; IWICBitmapScaler* wicScaler = NULL; WICPixelFormatGUID pixelFormat; WICRect rect = { 0, 0, 164, 164 }; // Create the ImagingFactory if (FAILED(CoCreateInstance(&CLSID_WICImagingFactory1, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, &wicFactory))) goto CleanupExit; // Find the resource if ((resourceHandleSource = FindResource(PhInstanceHandle, Name, L"PNG")) == NULL) goto CleanupExit; // Get the resource length resourceLength = SizeofResource(PhInstanceHandle, resourceHandleSource); // Load the resource if ((resourceHandle = LoadResource(PhInstanceHandle, resourceHandleSource)) == NULL) goto CleanupExit; if ((resourceBuffer = (WICInProcPointer)LockResource(resourceHandle)) == NULL) goto CleanupExit; // Create the Stream if (FAILED(IWICImagingFactory_CreateStream(wicFactory, &wicStream))) goto CleanupExit; // Initialize the Stream from Memory if (FAILED(IWICStream_InitializeFromMemory(wicStream, resourceBuffer, resourceLength))) goto CleanupExit; if (FAILED(IWICImagingFactory_CreateDecoder(wicFactory, &GUID_ContainerFormatPng, NULL, &wicDecoder))) goto CleanupExit; if (FAILED(IWICBitmapDecoder_Initialize(wicDecoder, (IStream*)wicStream, WICDecodeMetadataCacheOnLoad))) goto CleanupExit; // Get the Frame count if (FAILED(IWICBitmapDecoder_GetFrameCount(wicDecoder, &frameCount)) || frameCount < 1) goto CleanupExit; // Get the Frame if (FAILED(IWICBitmapDecoder_GetFrame(wicDecoder, 0, &wicFrame))) goto CleanupExit; // Get the WicFrame image format if (FAILED(IWICBitmapFrameDecode_GetPixelFormat(wicFrame, &pixelFormat))) goto CleanupExit; // Check if the image format is supported: if (IsEqualGUID(&pixelFormat, &GUID_WICPixelFormat32bppPRGBA)) { wicBitmapSource = (IWICBitmapSource*)wicFrame; } else { IWICFormatConverter* wicFormatConverter = NULL; if (FAILED(IWICImagingFactory_CreateFormatConverter(wicFactory, &wicFormatConverter))) goto CleanupExit; if (FAILED(IWICFormatConverter_Initialize( wicFormatConverter, (IWICBitmapSource*)wicFrame, &GUID_WICPixelFormat32bppPRGBA, WICBitmapDitherTypeNone, NULL, 0.0, WICBitmapPaletteTypeCustom ))) { IWICFormatConverter_Release(wicFormatConverter); goto CleanupExit; } // Convert the image to the correct format: IWICFormatConverter_QueryInterface(wicFormatConverter, &IID_IWICBitmapSource, &wicBitmapSource); // Cleanup the converter. IWICFormatConverter_Release(wicFormatConverter); // Dispose the old frame now that the converted frame is in wicBitmapSource. IWICBitmapFrameDecode_Release(wicFrame); } bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bitmapInfo.bmiHeader.biWidth = rect.Width; bitmapInfo.bmiHeader.biHeight = -((LONG)rect.Height); bitmapInfo.bmiHeader.biPlanes = 1; bitmapInfo.bmiHeader.biBitCount = 32; bitmapInfo.bmiHeader.biCompression = BI_RGB; screenHdc = CreateIC(L"DISPLAY", NULL, NULL, NULL); bufferDc = CreateCompatibleDC(screenHdc); bitmapHandle = CreateDIBSection(screenHdc, &bitmapInfo, DIB_RGB_COLORS, &bitmapBuffer, NULL, 0); // Check if it's the same rect as the requested size. //if (width != rect.Width || height != rect.Height) if (FAILED(IWICImagingFactory_CreateBitmapScaler(wicFactory, &wicScaler))) goto CleanupExit; if (FAILED(IWICBitmapScaler_Initialize(wicScaler, wicBitmapSource, rect.Width, rect.Height, WICBitmapInterpolationModeFant))) goto CleanupExit; if (FAILED(IWICBitmapScaler_CopyPixels(wicScaler, &rect, rect.Width * 4, rect.Width * rect.Height * 4, (PBYTE)bitmapBuffer))) goto CleanupExit; success = TRUE; CleanupExit: if (wicScaler) IWICBitmapScaler_Release(wicScaler); if (bufferDc) DeleteDC(bufferDc); if (screenHdc) DeleteDC(screenHdc); if (wicBitmapSource) IWICBitmapSource_Release(wicBitmapSource); if (wicStream) IWICStream_Release(wicStream); if (wicDecoder) IWICBitmapDecoder_Release(wicDecoder); if (wicFactory) IWICImagingFactory_Release(wicFactory); if (resourceHandle) FreeResource(resourceHandle); if (success) { return bitmapHandle; } DeleteObject(bitmapHandle); return NULL; }
static void test_color_formats(void) { static const struct { char bit_depth, color_type; const GUID *format; const GUID *format_PLTE; const GUID *format_PLTE_tRNS; BOOL todo; BOOL todo_load; } td[] = { /* 2 - PNG_COLOR_TYPE_RGB */ { 1, 2, NULL, NULL, NULL }, { 2, 2, NULL, NULL, NULL }, { 4, 2, NULL, NULL, NULL }, { 8, 2, &GUID_WICPixelFormat24bppBGR, &GUID_WICPixelFormat24bppBGR, &GUID_WICPixelFormat24bppBGR }, /* libpng refuses to load our test image complaining about extra compressed data, * but libpng is still able to load the image with other combination of type/depth * making RGB 16 bpp case special for some reason. Therefore todo = TRUE. */ { 16, 2, &GUID_WICPixelFormat48bppRGB, &GUID_WICPixelFormat48bppRGB, &GUID_WICPixelFormat48bppRGB, TRUE, TRUE }, { 24, 2, NULL, NULL, NULL }, { 32, 2, NULL, NULL, NULL }, /* 0 - PNG_COLOR_TYPE_GRAY */ { 1, 0, &GUID_WICPixelFormatBlackWhite, &GUID_WICPixelFormatBlackWhite, &GUID_WICPixelFormat1bppIndexed, TRUE }, { 2, 0, &GUID_WICPixelFormat2bppGray, &GUID_WICPixelFormat2bppGray, &GUID_WICPixelFormat2bppIndexed, TRUE }, { 4, 0, &GUID_WICPixelFormat4bppGray, &GUID_WICPixelFormat4bppGray, &GUID_WICPixelFormat4bppIndexed, TRUE }, { 8, 0, &GUID_WICPixelFormat8bppGray, &GUID_WICPixelFormat8bppGray, &GUID_WICPixelFormat8bppIndexed, TRUE }, { 16, 0, &GUID_WICPixelFormat16bppGray, &GUID_WICPixelFormat16bppGray, &GUID_WICPixelFormat64bppRGBA, TRUE }, { 24, 0, NULL, NULL, NULL }, { 32, 0, NULL, NULL, NULL }, /* 3 - PNG_COLOR_TYPE_PALETTE */ { 1, 3, &GUID_WICPixelFormat1bppIndexed, &GUID_WICPixelFormat1bppIndexed, &GUID_WICPixelFormat1bppIndexed }, { 2, 3, &GUID_WICPixelFormat2bppIndexed, &GUID_WICPixelFormat2bppIndexed, &GUID_WICPixelFormat2bppIndexed }, { 4, 3, &GUID_WICPixelFormat4bppIndexed, &GUID_WICPixelFormat4bppIndexed, &GUID_WICPixelFormat4bppIndexed }, { 8, 3, &GUID_WICPixelFormat8bppIndexed, &GUID_WICPixelFormat8bppIndexed, &GUID_WICPixelFormat8bppIndexed }, { 16, 3, NULL, NULL, NULL }, { 24, 3, NULL, NULL, NULL }, { 32, 3, NULL, NULL, NULL }, }; char buf[sizeof(png_1x1_data)]; HRESULT hr; IWICBitmapDecoder *decoder; IWICBitmapFrameDecode *frame; GUID format; int i, PLTE_off = 0, tRNS_off = 0; memcpy(buf, png_1x1_data, sizeof(png_1x1_data)); for (i = 0; i < sizeof(png_1x1_data) - 4; i++) { if (!memcmp(buf + i, "tRNS", 4)) tRNS_off = i; else if (!memcmp(buf + i, "PLTE", 4)) PLTE_off = i; } ok(PLTE_off && tRNS_off, "PLTE offset %d, tRNS offset %d\n", PLTE_off, tRNS_off); if (!PLTE_off || !tRNS_off) return; /* In order to test the image data with and without PLTE and tRNS chunks * it's been decided to simply sero out the chunk id for testing puposes, * and under Windows such images get loaded just fine. But unfortunately * libpng refuses to load such images complaining about unknown chunk type. * A workaround for this libpng limitation is to mark the "disabled" chunks * with tEXt id. */ for (i = 0; i < sizeof(td)/sizeof(td[0]); i++) { /* with the tRNS and PLTE chunks */ memcpy(buf, png_1x1_data, sizeof(png_1x1_data)); buf[24] = td[i].bit_depth; buf[25] = td[i].color_type; hr = create_decoder(buf, sizeof(buf), &decoder); if (!is_valid_png_type_depth(td[i].color_type, td[i].bit_depth, TRUE)) ok(hr == WINCODEC_ERR_UNKNOWNIMAGEFORMAT, "%d: wrong error %#x\n", i, hr); else todo_wine_if(td[i].todo_load) ok(hr == S_OK, "%d: Failed to load PNG image data (type %d, bpp %d) %#x\n", i, td[i].color_type, td[i].bit_depth, hr); if (hr != S_OK) goto next_1; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); ok(hr == S_OK, "GetFrame error %#x\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); todo_wine_if(td[i].todo) ok(IsEqualGUID(&format, td[i].format_PLTE_tRNS), "PLTE+tRNS: expected %s, got %s (type %d, bpp %d)\n", wine_dbgstr_guid(td[i].format_PLTE_tRNS), wine_dbgstr_guid(&format), td[i].color_type, td[i].bit_depth); IWICBitmapFrameDecode_Release(frame); IWICBitmapDecoder_Release(decoder); next_1: /* without the tRNS chunk */ memcpy(buf, png_1x1_data, sizeof(png_1x1_data)); buf[24] = td[i].bit_depth; buf[25] = td[i].color_type; memcpy(buf + tRNS_off, "tEXt", 4); hr = create_decoder(buf, sizeof(buf), &decoder); if (!is_valid_png_type_depth(td[i].color_type, td[i].bit_depth, TRUE)) ok(hr == WINCODEC_ERR_UNKNOWNIMAGEFORMAT, "%d: wrong error %#x\n", i, hr); else todo_wine_if(td[i].todo_load) ok(hr == S_OK, "%d: Failed to load PNG image data (type %d, bpp %d) %#x\n", i, td[i].color_type, td[i].bit_depth, hr); if (hr != S_OK) goto next_2; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); ok(hr == S_OK, "GetFrame error %#x\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); ok(IsEqualGUID(&format, td[i].format_PLTE), "PLTE: expected %s, got %s (type %d, bpp %d)\n", wine_dbgstr_guid(td[i].format_PLTE), wine_dbgstr_guid(&format), td[i].color_type, td[i].bit_depth); IWICBitmapFrameDecode_Release(frame); IWICBitmapDecoder_Release(decoder); next_2: /* without the tRNS and PLTE chunks */ memcpy(buf, png_1x1_data, sizeof(png_1x1_data)); buf[24] = td[i].bit_depth; buf[25] = td[i].color_type; memcpy(buf + PLTE_off, "tEXt", 4); memcpy(buf + tRNS_off, "tEXt", 4); hr = create_decoder(buf, sizeof(buf), &decoder); if (!is_valid_png_type_depth(td[i].color_type, td[i].bit_depth, FALSE)) ok(hr == WINCODEC_ERR_UNKNOWNIMAGEFORMAT, "%d: wrong error %#x\n", i, hr); else todo_wine_if(td[i].todo_load) ok(hr == S_OK, "%d: Failed to load PNG image data (type %d, bpp %d) %#x\n", i, td[i].color_type, td[i].bit_depth, hr); if (hr != S_OK) goto next_3; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); ok(hr == S_OK, "GetFrame error %#x\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); ok(IsEqualGUID(&format, td[i].format), "expected %s, got %s (type %d, bpp %d)\n", wine_dbgstr_guid(td[i].format), wine_dbgstr_guid(&format), td[i].color_type, td[i].bit_depth); IWICBitmapFrameDecode_Release(frame); IWICBitmapDecoder_Release(decoder); next_3: /* without the PLTE chunk */ memcpy(buf, png_1x1_data, sizeof(png_1x1_data)); buf[24] = td[i].bit_depth; buf[25] = td[i].color_type; memcpy(buf + PLTE_off, "tEXt", 4); hr = create_decoder(buf, sizeof(buf), &decoder); if (!is_valid_png_type_depth(td[i].color_type, td[i].bit_depth, FALSE)) ok(hr == WINCODEC_ERR_UNKNOWNIMAGEFORMAT, "%d: wrong error %#x\n", i, hr); else todo_wine_if(td[i].todo_load) ok(hr == S_OK, "%d: Failed to load PNG image data (type %d, bpp %d) %#x\n", i, td[i].color_type, td[i].bit_depth, hr); if (hr != S_OK) continue; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); ok(hr == S_OK, "GetFrame error %#x\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); todo_wine_if(td[i].todo) ok(IsEqualGUID(&format, td[i].format_PLTE_tRNS), "tRNS: expected %s, got %s (type %d, bpp %d)\n", wine_dbgstr_guid(td[i].format_PLTE_tRNS), wine_dbgstr_guid(&format), td[i].color_type, td[i].bit_depth); IWICBitmapFrameDecode_Release(frame); IWICBitmapDecoder_Release(decoder); } }
static fz_pixmap * fz_load_jxr_or_info(fz_context *ctx, unsigned char *data, int size, int *wp, int *hp, int *xresp, int *yresp, fz_colorspace **cspacep) { #ifdef _WIN32 int info_only = wp && hp && xresp && yresp && cspacep; fz_pixmap *pix = NULL; IStream *stream = NULL; IWICImagingFactory *factory = NULL; IWICBitmapDecoder *decoder = NULL; IWICFormatConverter *converter = NULL; IWICBitmapFrameDecode *src_frame = NULL; IWICBitmapSource *src_bitmap = NULL; int codec_available = 0; LARGE_INTEGER zero = { 0 }; UINT width, height; double xres, yres; ULONG written; HRESULT hr; hr = CoInitialize(NULL); if (FAILED(hr)) fz_throw(ctx, "JPEG-XR codec is not available"); #define Check(hr) if (FAILED(hr)) goto CleanUp Check(CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_ALL, &IID_IWICImagingFactory, (void **)&factory)); Check(CreateStreamOnHGlobal(NULL, TRUE, &stream)); Check(IStream_Write(stream, data, (ULONG)size, &written)); Check(IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL)); Check(IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, WICDecodeMetadataCacheOnDemand, &decoder)); Check(IWICImagingFactory_CreateFormatConverter(factory, &converter)); Check(IWICBitmapDecoder_GetFrame(decoder, 0, &src_frame)); Check(IUnknown_QueryInterface(src_frame, &IID_IWICBitmapSource, &src_bitmap)); Check(IWICFormatConverter_Initialize(converter, src_bitmap, &GUID_WICPixelFormat32bppBGRA, WICBitmapDitherTypeNone, NULL, 0.f, WICBitmapPaletteTypeCustom)); Check(IWICFormatConverter_GetSize(converter, &width, &height)); Check(IWICFormatConverter_GetResolution(converter, &xres, &yres)); #undef Check codec_available = 1; if (info_only) { *cspacep = fz_device_bgr; *wp = width; *hp = height; *xresp = (int)(xres + 0.5); *yresp = (int)(yres + 0.5); } else { fz_try(ctx) { pix = fz_new_pixmap(ctx, fz_device_bgr, width, height); } fz_catch(ctx) { pix = NULL; goto CleanUp; } hr = IWICFormatConverter_CopyPixels(converter, NULL, pix->w * pix->n, pix->w * pix->h * pix->n, pix->samples); if (FAILED(hr)) { fz_drop_pixmap(ctx, pix); pix = NULL; goto CleanUp; } pix->xres = (int)(xres + 0.5); pix->yres = (int)(yres + 0.5); } CleanUp: #define Release(unk) if (unk) IUnknown_Release(unk) Release(src_bitmap); Release(converter); Release(src_frame); Release(decoder); Release(factory); Release(stream); #undef Release CoUninitialize(); if (codec_available) { if (!pix && !info_only) fz_throw(ctx, "JPEG-XR codec failed to decode the image"); return pix; } #endif fz_throw(ctx, "JPEG-XR codec is not available"); return NULL; }