From: Esme Povirk esme@codeweavers.com
--- dlls/oleaut32/olepicture.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-)
diff --git a/dlls/oleaut32/olepicture.c b/dlls/oleaut32/olepicture.c index caea1281d4d..eeb16b9785c 100644 --- a/dlls/oleaut32/olepicture.c +++ b/dlls/oleaut32/olepicture.c @@ -999,6 +999,8 @@ static HRESULT WINAPI OLEPictureImpl_IsDirty( return E_NOTIMPL; }
+HRESULT WINAPI WICCreateImagingFactory_Proxy(UINT, IWICImagingFactory**); + static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSource *src) { HRESULT hr; @@ -1141,24 +1143,19 @@ end: return hr; }
-static HRESULT OLEPictureImpl_LoadWICDecoder(OLEPictureImpl *This, REFCLSID decoder_clsid, BYTE *xbuf, ULONG xread) +static HRESULT OLEPictureImpl_LoadWICDecoder(OLEPictureImpl *This, REFGUID format_guid, BYTE *xbuf, ULONG xread) { HRESULT hr; IWICImagingFactory *factory; IWICBitmapDecoder *decoder; IWICBitmapFrameDecode *framedecode; - HRESULT initresult; IWICStream *stream;
- initresult = CoInitialize(NULL); + hr = WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory); + if (FAILED(hr)) + return hr;
- hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, - &IID_IWICImagingFactory, (void**)&factory); - if (SUCCEEDED(hr)) /* created factory */ - { - hr = IWICImagingFactory_CreateStream(factory, &stream); - IWICImagingFactory_Release(factory); - } + hr = IWICImagingFactory_CreateStream(factory, &stream);
if (SUCCEEDED(hr)) /* created stream */ { @@ -1166,8 +1163,7 @@ static HRESULT OLEPictureImpl_LoadWICDecoder(OLEPictureImpl *This, REFCLSID deco
if (SUCCEEDED(hr)) /* initialized stream */ { - hr = CoCreateInstance(decoder_clsid, NULL, CLSCTX_INPROC_SERVER, - &IID_IWICBitmapDecoder, (void**)&decoder); + hr = IWICImagingFactory_CreateDecoder(factory, format_guid, &GUID_VendorMicrosoftBuiltIn, &decoder); if (SUCCEEDED(hr)) /* created decoder */ { hr = IWICBitmapDecoder_Initialize(decoder, (IStream*)stream, WICDecodeMetadataCacheOnLoad); @@ -1188,7 +1184,8 @@ static HRESULT OLEPictureImpl_LoadWICDecoder(OLEPictureImpl *This, REFCLSID deco IWICBitmapFrameDecode_Release(framedecode); }
- if (SUCCEEDED(initresult)) CoUninitialize(); + IWICImagingFactory_Release(factory); + return hr; }
@@ -1495,16 +1492,16 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface, IStream *pStm)
switch (magic) { case BITMAP_FORMAT_GIF: /* GIF */ - hr = OLEPictureImpl_LoadWICDecoder(This, &CLSID_WICGifDecoder, xbuf, xread); + hr = OLEPictureImpl_LoadWICDecoder(This, &GUID_ContainerFormatGif, xbuf, xread); break; case BITMAP_FORMAT_JPEG: /* JPEG */ - hr = OLEPictureImpl_LoadWICDecoder(This, &CLSID_WICJpegDecoder, xbuf, xread); + hr = OLEPictureImpl_LoadWICDecoder(This, &GUID_ContainerFormatJpeg, xbuf, xread); break; case BITMAP_FORMAT_BMP: /* Bitmap */ - hr = OLEPictureImpl_LoadWICDecoder(This, &CLSID_WICBmpDecoder, xbuf, xread); + hr = OLEPictureImpl_LoadWICDecoder(This, &GUID_ContainerFormatBmp, xbuf, xread); break; case BITMAP_FORMAT_PNG: /* PNG */ - hr = OLEPictureImpl_LoadWICDecoder(This, &CLSID_WICPngDecoder, xbuf, xread); + hr = OLEPictureImpl_LoadWICDecoder(This, &GUID_ContainerFormatPng, xbuf, xread); break; case BITMAP_FORMAT_APM: /* APM */ hr = OLEPictureImpl_LoadAPM(This, xbuf, xread);
From: Esme Povirk esme@codeweavers.com
--- dlls/oleaut32/olepicture.c | 53 +++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 7 deletions(-)
diff --git a/dlls/oleaut32/olepicture.c b/dlls/oleaut32/olepicture.c index eeb16b9785c..f5fc18c2c28 100644 --- a/dlls/oleaut32/olepicture.c +++ b/dlls/oleaut32/olepicture.c @@ -104,13 +104,14 @@ typedef struct { const WICPixelFormatGUID *guid; UINT bpp; + BOOL indexed; } WICFORMAT;
const WICFORMAT wicformats[] = { - {&GUID_WICPixelFormat1bppIndexed, 1}, - {&GUID_WICPixelFormat4bppIndexed, 4}, - {&GUID_WICPixelFormat8bppIndexed, 8}, + {&GUID_WICPixelFormat1bppIndexed, 1, TRUE}, + {&GUID_WICPixelFormat4bppIndexed, 4, TRUE}, + {&GUID_WICPixelFormat8bppIndexed, 8, TRUE}, {&GUID_WICPixelFormat24bppBGR, 24}, {&GUID_WICPixelFormat32bppBGR, 32}, }; @@ -1001,19 +1002,21 @@ static HRESULT WINAPI OLEPictureImpl_IsDirty(
HRESULT WINAPI WICCreateImagingFactory_Proxy(UINT, IWICImagingFactory**);
-static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSource *src) +static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICImagingFactory *factory, IWICBitmapSource *src) { HRESULT hr; BITMAPINFOHEADER bih; + BITMAPINFO *info, *dyn_info = NULL; UINT width, height; UINT stride, buffersize; BYTE *bits, *mask = NULL; WICRect rc; WICPixelFormatGUID guid; IWICBitmapSource *real_source; + IWICPalette *palette; UINT x, y, i; COLORREF white = RGB(255, 255, 255), black = RGB(0, 0, 0); - BOOL has_alpha=FALSE; + BOOL has_alpha=FALSE, indexed=FALSE;
hr = IWICBitmapSource_GetPixelFormat(src, &guid); if (FAILED(hr)) return hr; @@ -1023,6 +1026,7 @@ static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSour if (IsEqualGUID(&guid, wicformats[i].guid)) { bih.biBitCount = wicformats[i].bpp; + indexed = wicformats[i].indexed; break; } } @@ -1060,7 +1064,41 @@ static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSour goto end; }
- This->desc.bmp.hbitmap = CreateDIBSection(0, (BITMAPINFO*)&bih, DIB_RGB_COLORS, (void **)&bits, NULL, 0); + if (indexed) + { + UINT palette_size = 1 << bih.biBitCount, source_colors; + + info = dyn_info = malloc(FIELD_OFFSET(BITMAPINFO, bmiColors[palette_size])); + if (!info) + { + hr = E_OUTOFMEMORY; + goto end; + } + + info->bmiHeader = bih; + + hr = IWICImagingFactory_CreatePalette(factory, &palette); + + if (SUCCEEDED(hr)) + { + hr = IWICBitmapSource_CopyPalette(real_source, palette); + + if (SUCCEEDED(hr)) + hr = IWICPalette_GetColors(palette, palette_size, (WICColor*)&info->bmiColors[0], &source_colors); + + IWICPalette_Release(palette); + } + + if (FAILED(hr)) + goto end; + + if (source_colors < palette_size) + memset(&info->bmiColors[source_colors], 0, sizeof(RGBQUAD) * (palette_size - source_colors)); + } + else + info = (BITMAPINFO*)&bih; + + This->desc.bmp.hbitmap = CreateDIBSection(0, info, DIB_RGB_COLORS, (void **)&bits, NULL, 0); if (This->desc.bmp.hbitmap == 0) { hr = E_FAIL; @@ -1139,6 +1177,7 @@ static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSour
end: free(mask); + free(dyn_info); IWICBitmapSource_Release(real_source); return hr; } @@ -1180,7 +1219,7 @@ static HRESULT OLEPictureImpl_LoadWICDecoder(OLEPictureImpl *This, REFGUID forma
if (SUCCEEDED(hr)) /* got framedecode */ { - hr = OLEPictureImpl_LoadWICSource(This, (IWICBitmapSource*)framedecode); + hr = OLEPictureImpl_LoadWICSource(This, factory, (IWICBitmapSource*)framedecode); IWICBitmapFrameDecode_Release(framedecode); }
There may also be issues with the alpha channel on indexed formats, but I've been having so much trouble testing this that it doesn't feel worth it for now.