From 1e6b33923f19a4c041ef7babe6bf8060a18e9209 Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Thu, 9 Jul 2009 15:03:22 -0500 Subject: [PATCH] oleaut32: use WIC to decode bmp files --- dlls/oleaut32/Makefile.in | 2 +- dlls/oleaut32/olepicture.c | 130 ++++++++++++++++++++++++++++++++++++++------ dlls/oleaut32/regsvr.c | 1 + 3 files changed, 115 insertions(+), 18 deletions(-) diff --git a/dlls/oleaut32/Makefile.in b/dlls/oleaut32/Makefile.in index 0f2be7f..0f06449 100644 --- a/dlls/oleaut32/Makefile.in +++ b/dlls/oleaut32/Makefile.in @@ -5,7 +5,7 @@ VPATH = @srcdir@ MODULE = oleaut32.dll IMPORTLIB = oleaut32 IMPORTS = uuid ole32 rpcrt4 user32 gdi32 advapi32 kernel32 ntdll -DELAYIMPORTS = comctl32 urlmon +DELAYIMPORTS = comctl32 urlmon windowscodecs EXTRADEFS = -D_OLEAUT32_ -DCOM_NO_WINDOWS_H \ -DENTRY_PREFIX=OLEAUTPS_ -DPROXY_CLSID=CLSID_PSDispatch -DPROXY_DELEGATION -DREGISTER_PROXY_DLL EXTRAINCL = @PNGINCL@ diff --git a/dlls/oleaut32/olepicture.c b/dlls/oleaut32/olepicture.c index 54baf12..f9c490d 100644 --- a/dlls/oleaut32/olepicture.c +++ b/dlls/oleaut32/olepicture.c @@ -82,6 +82,7 @@ #include "oleauto.h" #include "connpt.h" #include "urlmon.h" +#include "wincodec.h" #include "wine/debug.h" #include "wine/unicode.h" #include "wine/library.h" @@ -1378,30 +1379,125 @@ static HRESULT OLEPictureImpl_LoadJpeg(OLEPictureImpl *This, BYTE *xbuf, ULONG x #endif } -static HRESULT OLEPictureImpl_LoadDIB(OLEPictureImpl *This, BYTE *xbuf, ULONG xread) -{ - BITMAPFILEHEADER *bfh = (BITMAPFILEHEADER*)xbuf; - BITMAPINFO *bi = (BITMAPINFO*)(bfh+1); - HDC hdcref; +static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSource *src) +{ + HRESULT hr; + BITMAPINFOHEADER bih; + HDC hdcref; + UINT width, height; + UINT stride, buffersize; + LPBYTE bits=NULL; + WICRect rc; + IWICBitmapSource *real_source; + + hr = WICConvertBitmapSource(&GUID_WICPixelFormat32bppBGRA, src, &real_source); + if (FAILED(hr)) return hr; + + hr = IWICBitmapSource_GetSize(real_source, &width, &height); + if (FAILED(hr)) goto end; + + bih.biSize = sizeof(bih); + bih.biWidth = width; + bih.biHeight = -height; + bih.biPlanes = 1; + bih.biBitCount = 32; + bih.biCompression = BI_RGB; + bih.biSizeImage = 0; + bih.biXPelsPerMeter = 4085; /* olepicture ignores the stored resolution */ + bih.biYPelsPerMeter = 4085; + bih.biClrUsed = 0; + bih.biClrImportant = 0; + + stride = 4 * width; + buffersize = stride * height; + + bits = HeapAlloc(GetProcessHeap(), 0, buffersize); + if (!bits) + { + hr = E_OUTOFMEMORY; + goto end; + } + + rc.X = 0; + rc.Y = 0; + rc.Width = width; + rc.Height = height; + hr = IWICBitmapSource_CopyPixels(real_source, &rc, stride, buffersize, bits); + if (FAILED(hr)) + goto end; - /* Does not matter whether this is a coreheader or not, we only use - * components which are in both - */ hdcref = GetDC(0); This->desc.u.bmp.hbitmap = CreateDIBitmap( - hdcref, - &(bi->bmiHeader), - CBM_INIT, - xbuf+bfh->bfOffBits, - bi, - DIB_RGB_COLORS - ); + hdcref, + &bih, + CBM_INIT, + bits, + (BITMAPINFO*)&bih, + DIB_RGB_COLORS); ReleaseDC(0, hdcref); + if (This->desc.u.bmp.hbitmap == 0) - return E_FAIL; + { + hr = E_FAIL; + goto end; + } + This->desc.picType = PICTYPE_BITMAP; OLEPictureImpl_SetBitmap(This); - return S_OK; + +end: + HeapFree(GetProcessHeap(), 0, bits); + IWICBitmapSource_Release(real_source); + return hr; +} + +static HRESULT OLEPictureImpl_LoadWICDecoder(OLEPictureImpl *This, REFCLSID decoder_clsid, BYTE *xbuf, ULONG xread) +{ + HRESULT hr; + IWICBitmapDecoder *decoder; + IWICBitmapFrameDecode *framedecode; + HRESULT initresult; + HGLOBAL hdata; + BYTE *data; + IStream *stream; + + hdata = GlobalAlloc(GMEM_MOVEABLE, xread); + if (!hdata) return E_OUTOFMEMORY; + + data = GlobalLock(hdata); + memcpy(data, xbuf, xread); + GlobalUnlock(hdata); + + hr = CreateStreamOnHGlobal(hdata, TRUE, &stream); + if (FAILED(hr)) + { + GlobalFree(hdata); + return hr; + } + + initresult = CoInitialize(NULL); + + hr = CoCreateInstance(decoder_clsid, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICBitmapDecoder, (void**)&decoder); + if (FAILED(hr)) goto end; + + hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnLoad); + if (SUCCEEDED(hr)) + { + hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode); + if (SUCCEEDED(hr)) + { + hr = OLEPictureImpl_LoadWICSource(This, (IWICBitmapSource*)framedecode); + IWICBitmapFrameDecode_Release(framedecode); + } + } + + IWICBitmapDecoder_Release(decoder); + +end: + IStream_Release(stream); + if (SUCCEEDED(initresult)) CoUninitialize(); + return hr; } /***************************************************** @@ -1931,7 +2027,7 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) { hr = OLEPictureImpl_LoadJpeg(This, xbuf, xread); break; case BITMAP_FORMAT_BMP: /* Bitmap */ - hr = OLEPictureImpl_LoadDIB(This, xbuf, xread); + hr = OLEPictureImpl_LoadWICDecoder(This, &CLSID_WICBmpDecoder, xbuf, xread); break; case BITMAP_FORMAT_PNG: /* PNG */ hr = OLEPictureImpl_LoadPNG(This, xbuf, xread); diff --git a/dlls/oleaut32/regsvr.c b/dlls/oleaut32/regsvr.c index 9ee36b5..3c5fabc 100644 --- a/dlls/oleaut32/regsvr.c +++ b/dlls/oleaut32/regsvr.c @@ -32,6 +32,7 @@ #include "oleauto.h" #include "initguid.h" #include "typelib.h" +#include "wincodec.h" #include "wine/debug.h" #include "wine/unicode.h" -- 1.5.4.3