static Bitmap *WICDecodeImageFromStream(IStream *stream) { ScopedCom com; #define HR(hr) if (FAILED(hr)) return NULL; ScopedComPtr<IWICImagingFactory> pFactory; if (!pFactory.Create(CLSID_WICImagingFactory)) return NULL; ScopedComPtr<IWICBitmapDecoder> pDecoder; HR(pFactory->CreateDecoderFromStream(stream, NULL, WICDecodeMetadataCacheOnDemand, &pDecoder)); ScopedComPtr<IWICBitmapFrameDecode> srcFrame; HR(pDecoder->GetFrame(0, &srcFrame)); ScopedComPtr<IWICFormatConverter> pConverter; HR(pFactory->CreateFormatConverter(&pConverter)); HR(pConverter->Initialize(srcFrame, GUID_WICPixelFormat32bppBGRA, WICBitmapDitherTypeNone, NULL, 0.f, WICBitmapPaletteTypeCustom)); UINT w, h; HR(pConverter->GetSize(&w, &h)); double xres, yres; HR(pConverter->GetResolution(&xres, &yres)); Bitmap bmp(w, h, PixelFormat32bppARGB); Rect bmpRect(0, 0, w, h); BitmapData bmpData; Status ok = bmp.LockBits(&bmpRect, ImageLockModeWrite, PixelFormat32bppARGB, &bmpData); if (ok != Ok) return NULL; HR(pConverter->CopyPixels(NULL, bmpData.Stride, bmpData.Stride * h, (BYTE *)bmpData.Scan0)); bmp.UnlockBits(&bmpData); bmp.SetResolution((REAL)xres, (REAL)yres); #undef HR // hack to avoid the use of ::new (because there won't be a corresponding ::delete) return bmp.Clone(0, 0, w, h, PixelFormat32bppARGB); }