HBITMAP ImageDecoder::convertFrameToBitmap(IWICBitmapFrameDecode *frame) { IWICBitmapSource *bitmapSource = frame; if (FAILED(WICConvertBitmapSource(GUID_WICPixelFormat32bppPBGRA, frame, &bitmapSource))) { throw Exception("could not convert bitmap"); } UINT width = 0; UINT height = 0; if (FAILED(bitmapSource->GetSize(&width, &height)) || width == 0 || height == 0) { throw Exception("could not get image size"); } std::vector<BYTE> buffer(width * height * 4); if (FAILED(bitmapSource->CopyPixels(NULL, width * 4, buffer.size(), &buffer[0]))) { throw Exception("could not get image size"); } bitmapSource->Release(); return CreateBitmap(width, height, 1, 32, &buffer[0]); }
Image::Buffer * WIC::Api::CreateImage(char * buffer, unsigned bufferLength) { if(!factory) return 0; // Create input stream for memory IWICStream * stream = 0; factory->CreateStream(&stream); if(!stream) return 0; stream->InitializeFromMemory((unsigned char*)(buffer), static_cast<DWORD>(bufferLength)); IWICBitmapDecoder * decoder = 0; factory->CreateDecoderFromStream(stream, 0, WICDecodeMetadataCacheOnDemand, &decoder); if(!decoder) return 0; IWICBitmapFrameDecode * bitmapSource = 0; decoder->GetFrame(0, &bitmapSource); if(!bitmapSource) { decoder->Release(); return 0; } IWICBitmapSource * convertedSource = 0; WICConvertBitmapSource(GUID_WICPixelFormat32bppRGBA, bitmapSource, &convertedSource); bitmapSource->Release(); if(!convertedSource) { decoder->Release(); return 0; } // Create the bitmap from the image frame. IWICBitmap * bitmap = 0; factory->CreateBitmapFromSource( convertedSource, // Create a bitmap from the image frame WICBitmapCacheOnDemand, // Cache metadata when needed &bitmap); // Pointer to the bitmap convertedSource->Release(); decoder->Release(); if(!bitmap) return 0; unsigned width = 0, height = 0; bitmap->GetSize(&width, &height); WICRect lockRect = { 0, 0, width, height }; IWICBitmapLock * lock = 0; bitmap->Lock(&lockRect, WICBitmapLockWrite, &lock); if(!lock) { bitmap->Release(); return 0; } return new WIC::Buffer(bitmap, lock, width, height); }
Image::Buffer * WIC::Api::CreateImage(char * data, unsigned dataSize, unsigned w, unsigned h, Image::Format format) { IWICBitmap * bitmap = 0; factory->CreateBitmap(w, h, IMAGE_FORMAT_TO_WIC_GUID[format], WICBitmapCacheOnLoad, &bitmap); if(!bitmap) return 0; WICRect lockRect = { 0, 0, w, h }; IWICBitmapLock * lock = 0; bitmap->Lock(&lockRect, WICBitmapLockWrite, &lock); if(!lock) { bitmap->Release(); return 0; } unsigned bufferSize = 0; WICInProcPointer dataPointer = 0; lock->GetDataPointer(&bufferSize, &dataPointer); memcpy(dataPointer, data, dataSize); lock->Release(); lock = 0; if(format != Image::Format_4x8intRGBA) { IWICBitmapSource * convertedSource = 0; WICConvertBitmapSource(GUID_WICPixelFormat32bppRGBA, bitmap, &convertedSource); bitmap->Release(); bitmap = 0; if(!convertedSource) return 0; // Create the bitmap from the image frame. factory->CreateBitmapFromSource( convertedSource, // Create a bitmap from the image frame WICBitmapCacheOnDemand, // Cache metadata when needed &bitmap); // Pointer to the bitmap convertedSource->Release(); if(!bitmap) return 0; } bitmap->Lock(&lockRect, WICBitmapLockWrite, &lock); if(!lock) { bitmap->Release(); return 0; } return new WIC::Buffer(bitmap, lock, w, h); }
static void test_invalid_conversion(void) { BitmapTestSrc *src_obj; IWICBitmapSource *dst_bitmap; HRESULT hr; CreateTestBitmap(&testdata_32bppBGRA, &src_obj); /* convert to a non-pixel-format GUID */ hr = WICConvertBitmapSource(&GUID_VendorMicrosoft, &src_obj->IWICBitmapSource_iface, &dst_bitmap); ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "WICConvertBitmapSource returned %x\n", hr); DeleteTestBitmap(src_obj); }
// Loads a PNG image from the specified stream (using Windows Imaging Component). IWICBitmapSource * LoadBitmapFromStream(IStream * ipImageStream) { // initialize return value IWICBitmapSource * ipBitmap = NULL; // load WIC's PNG decoder IWICBitmapDecoder * ipDecoder = NULL; IID i = IID_IWICBitmapDecoder; if (FAILED(CoCreateInstance(CLSID_WICPngDecoder, NULL, CLSCTX_INPROC_SERVER, i,//__uuidof(ipDecoder) (void **)&ipDecoder))) goto Return; // load the PNG if (FAILED(ipDecoder->Initialize(ipImageStream, WICDecodeMetadataCacheOnLoad))) goto ReleaseDecoder; // check for the presence of the first frame in the bitmap UINT nFrameCount = 0; if (FAILED(ipDecoder->GetFrameCount(&nFrameCount)) || nFrameCount != 1) goto ReleaseDecoder; // load the first frame (i.e., the image) IWICBitmapFrameDecode * ipFrame = NULL; if (FAILED(ipDecoder->GetFrame(0, &ipFrame))) goto ReleaseDecoder; // convert the image to 32bpp BGRA format with pre-multiplied alpha // (it may not be stored in that format natively in the PNG resource, // but we need this format to create the DIB to use on-screen) WICConvertBitmapSource(GUID_WICPixelFormat32bppPBGRA, ipFrame, &ipBitmap); ipFrame->Release(); ReleaseDecoder: ipDecoder->Release(); Return: return ipBitmap; }
HBITMAP ImageDecoder::loadImage(IWICBitmapDecoder *decoder) { IWICBitmapFrameDecode *frame = NULL; if (FAILED(decoder->GetFrame(0, &frame))) { throw Exception("could not get frame"); } IWICBitmapSource *bitmapSource = NULL; if (FAILED(WICConvertBitmapSource(GUID_WICPixelFormat32bppPBGRA, frame, &bitmapSource))) { throw Exception("could not convert bitmap"); } HBITMAP bitmap = convertFrameToBitmap(frame); frame->Release(); return bitmap; }
static HRESULT WINAPI ColorTransform_Initialize(IWICColorTransform *iface, IWICBitmapSource *pIBitmapSource, IWICColorContext *pIContextSource, IWICColorContext *pIContextDest, REFWICPixelFormatGUID pixelFmtDest) { ColorTransform *This = impl_from_IWICColorTransform(iface); IWICBitmapSource *dst; HRESULT hr; TRACE("(%p,%p,%p,%p,%s)\n", iface, pIBitmapSource, pIContextSource, pIContextDest, debugstr_guid(pixelFmtDest)); FIXME("ignoring color contexts\n"); hr = WICConvertBitmapSource(pixelFmtDest, pIBitmapSource, &dst); if (FAILED(hr)) return hr; if (This->dst) IWICBitmapSource_Release(This->dst); This->dst = dst; return S_OK; }
HRESULT WINAPI WICSetEncoderFormat_Proxy(IWICBitmapSource *pSourceIn, IWICPalette *pIPalette, IWICBitmapFrameEncode *pIFrameEncode, IWICBitmapSource **ppSourceOut) { HRESULT hr; WICPixelFormatGUID pixelformat, framepixelformat; TRACE("%p,%p,%p,%p\n", pSourceIn, pIPalette, pIFrameEncode, ppSourceOut); if (pIPalette) FIXME("ignoring palette\n"); if (!pSourceIn || !pIFrameEncode || !ppSourceOut) return E_INVALIDARG; *ppSourceOut = NULL; hr = IWICBitmapSource_GetPixelFormat(pSourceIn, &pixelformat); if (SUCCEEDED(hr)) { framepixelformat = pixelformat; hr = IWICBitmapFrameEncode_SetPixelFormat(pIFrameEncode, &framepixelformat); } if (SUCCEEDED(hr)) { if (IsEqualGUID(&pixelformat, &framepixelformat)) { *ppSourceOut = pSourceIn; IWICBitmapSource_AddRef(pSourceIn); } else { hr = WICConvertBitmapSource(&framepixelformat, pSourceIn, ppSourceOut); } } return hr; }
static void test_conversion(const struct bitmap_data *src, const struct bitmap_data *dst, const char *name, BOOL todo) { BitmapTestSrc *src_obj; IWICBitmapSource *dst_bitmap; HRESULT hr; CreateTestBitmap(src, &src_obj); hr = WICConvertBitmapSource(dst->format, &src_obj->IWICBitmapSource_iface, &dst_bitmap); if (todo) todo_wine ok(SUCCEEDED(hr), "WICConvertBitmapSource(%s) failed, hr=%x\n", name, hr); else ok(SUCCEEDED(hr), "WICConvertBitmapSource(%s) failed, hr=%x\n", name, hr); if (SUCCEEDED(hr)) { compare_bitmap_data(dst, dst_bitmap, name); IWICBitmapSource_Release(dst_bitmap); } DeleteTestBitmap(src_obj); }
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; }
HBITMAP ImageUtil::LoadImage(string path) { size_t pathFileExtDot = path.find_last_of('.'); if (pathFileExtDot == string::npos || pathFileExtDot + 1 >= path.length()) throw INETRException("[imgLoadFailed]"); string ext = path.substr(pathFileExtDot + 1); const GUID *decoderCLSID = nullptr; if (ext == "png") decoderCLSID = &CLSID_WICPngDecoder; else if (ext == "bmp") decoderCLSID = &CLSID_WICBmpDecoder; else if (ext == "gif") decoderCLSID = &CLSID_WICGifDecoder; else if (ext == "jpg" || ext == "jpeg") decoderCLSID = &CLSID_WICJpegDecoder; if (decoderCLSID == nullptr) throw INETRException("[unsupportedImg]: " + ext); IStream *pngFileStream; if (FAILED(SHCreateStreamOnFile(path.c_str(), STGM_READ, &pngFileStream))) throw INETRException("[imgLoadFailed]:\n" + path); IWICBitmapDecoder *bmpDecoder = nullptr; if (FAILED(CoCreateInstance(*decoderCLSID, nullptr, CLSCTX_INPROC_SERVER, __uuidof(bmpDecoder), reinterpret_cast<void**>(&bmpDecoder)))) throw INETRException("[imgDecFailed]"); if (FAILED(bmpDecoder->Initialize(pngFileStream, WICDecodeMetadataCacheOnLoad))) { bmpDecoder->Release(); throw INETRException("[imgDecFailed]"); } UINT bmpFrameCount = 0; if (FAILED(bmpDecoder->GetFrameCount(&bmpFrameCount)) && bmpFrameCount != 1) { bmpDecoder->Release(); throw INETRException("[imgDecFailed]"); } IWICBitmapFrameDecode *bmpFrame = nullptr; if (FAILED(bmpDecoder->GetFrame(0, &bmpFrame))) { bmpDecoder->Release(); throw INETRException("[imgDecFailed]"); } IWICBitmapSource *bmpSource = nullptr; WICConvertBitmapSource(GUID_WICPixelFormat32bppPBGRA, bmpFrame, &bmpSource); bmpFrame->Release(); bmpDecoder->Release(); UINT width = 0, height = 0; if (FAILED(bmpSource->GetSize(&width, &height)) || width == 0 || height == 0) throw INETRException("[imgDecFailed]"); BITMAPINFO bmInfo; ZeroMemory(&bmInfo, sizeof(bmInfo)); bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmInfo.bmiHeader.biWidth = width; bmInfo.bmiHeader.biHeight = -((LONG)height); bmInfo.bmiHeader.biPlanes = 1; bmInfo.bmiHeader.biBitCount = 32; bmInfo.bmiHeader.biCompression = BI_RGB; HBITMAP hbmp = nullptr; void *imageBits = nullptr; HDC screenDC = GetDC(nullptr); hbmp = CreateDIBSection(screenDC, &bmInfo, DIB_RGB_COLORS, &imageBits, nullptr, 0); ReleaseDC(nullptr, screenDC); if (hbmp == nullptr) throw INETRException("[imgDecFailed]"); const UINT bmpStride = width * 4; const UINT bmpSize = bmpStride * height; if (FAILED(bmpSource->CopyPixels(nullptr, bmpStride, bmpSize, static_cast<BYTE*>(imageBits)))) { DeleteObject(hbmp); hbmp = nullptr; throw INETRException("[imgDecFailed]"); } bmpSource->Release(); return hbmp; }
static HRESULT WINAPI BitmapScaler_Initialize(IWICBitmapScaler *iface, IWICBitmapSource *pISource, UINT uiWidth, UINT uiHeight, WICBitmapInterpolationMode mode) { BitmapScaler *This = impl_from_IWICBitmapScaler(iface); HRESULT hr; GUID src_pixelformat; TRACE("(%p,%p,%u,%u,%u)\n", iface, pISource, uiWidth, uiHeight, mode); EnterCriticalSection(&This->lock); if (This->source) { hr = WINCODEC_ERR_WRONGSTATE; goto end; } This->width = uiWidth; This->height = uiHeight; This->mode = mode; hr = IWICBitmapSource_GetSize(pISource, &This->src_width, &This->src_height); if (SUCCEEDED(hr)) hr = IWICBitmapSource_GetPixelFormat(pISource, &src_pixelformat); if (SUCCEEDED(hr)) { hr = get_pixelformat_bpp(&src_pixelformat, &This->bpp); } if (SUCCEEDED(hr)) { switch (mode) { default: FIXME("unsupported mode %i\n", mode); /* fall-through */ case WICBitmapInterpolationModeNearestNeighbor: if ((This->bpp % 8) == 0) { IWICBitmapSource_AddRef(pISource); This->source = pISource; } else { hr = WICConvertBitmapSource(&GUID_WICPixelFormat32bppBGRA, pISource, &This->source); This->bpp = 32; } This->fn_get_required_source_rect = NearestNeighbor_GetRequiredSourceRect; This->fn_copy_scanline = NearestNeighbor_CopyScanline; break; } } end: LeaveCriticalSection(&This->lock); return hr; }