From 182a2cbf47a8562a43db6bdc8bd29e0980a9ddcd Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Thu, 21 Apr 2016 14:40:58 +0800 Subject: oleaut32: OleLoadPicture should create a DIB section for a being loaded bitmap. (v3) Application in the bug 39474 depends on this (GetObject/bmBits should not be NULL, otherwise it crashes). --- dlls/oleaut32/olepicture.c | 65 ++++++++++++++++------------------------ dlls/oleaut32/tests/olepicture.c | 2 +- 2 files changed, 27 insertions(+), 40 deletions(-) diff --git a/dlls/oleaut32/olepicture.c b/dlls/oleaut32/olepicture.c index bfca22f..1b6fb2c 100644 --- a/dlls/oleaut32/olepicture.c +++ b/dlls/oleaut32/olepicture.c @@ -999,23 +999,16 @@ static HRESULT OLEPictureImpl_LoadDIB(OLEPictureImpl *This, BYTE *xbuf, ULONG xr { BITMAPFILEHEADER *bfh = (BITMAPFILEHEADER*)xbuf; BITMAPINFO *bi = (BITMAPINFO*)(bfh+1); - HDC hdcref; + void *bits; + BITMAP bmp; - /* 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 - ); - ReleaseDC(0, hdcref); + This->desc.u.bmp.hbitmap = CreateDIBSection(0, bi, DIB_RGB_COLORS, &bits, NULL, 0); if (This->desc.u.bmp.hbitmap == 0) return E_FAIL; + + GetObjectA(This->desc.u.bmp.hbitmap, sizeof(bmp), &bmp); + memcpy(bits, xbuf + bfh->bfOffBits, bmp.bmHeight * bmp.bmWidthBytes); + This->desc.picType = PICTYPE_BITMAP; OLEPictureImpl_SetBitmap(This); return S_OK; @@ -1025,10 +1018,9 @@ static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSour { HRESULT hr; BITMAPINFOHEADER bih; - HDC hdcref; UINT width, height; UINT stride, buffersize; - LPBYTE bits=NULL; + BYTE *bits, *mask = NULL; WICRect rc; IWICBitmapSource *real_source; UINT x, y; @@ -1056,34 +1048,28 @@ static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSour stride = 4 * width; buffersize = stride * height; - bits = HeapAlloc(GetProcessHeap(), 0, buffersize); - if (!bits) + mask = HeapAlloc(GetProcessHeap(), 0, buffersize); + if (!mask) { hr = E_OUTOFMEMORY; goto end; } + This->desc.u.bmp.hbitmap = CreateDIBSection(0, (BITMAPINFO*)&bih, DIB_RGB_COLORS, (void **)&bits, NULL, 0); + if (This->desc.u.bmp.hbitmap == 0) + { + hr = E_FAIL; + 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; - - hdcref = GetDC(0); - This->desc.u.bmp.hbitmap = CreateDIBitmap( - hdcref, - &bih, - CBM_INIT, - bits, - (BITMAPINFO*)&bih, - DIB_RGB_COLORS); - - if (This->desc.u.bmp.hbitmap == 0) { - hr = E_FAIL; - ReleaseDC(0, hdcref); + DeleteObject(This->desc.u.bmp.hbitmap); goto end; } @@ -1097,23 +1083,25 @@ static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSour if((*pixel & 0x80000000) == 0) { has_alpha = TRUE; - *pixel = black; + *(DWORD *)(mask + stride * y + 4 * x) = black; } else - *pixel = white; + *(DWORD *)(mask + stride * y + 4 * x) = white; } } if (has_alpha) { - HDC hdcBmp, hdcXor, hdcMask; + HDC hdcref, hdcBmp, hdcXor, hdcMask; HBITMAP hbmoldBmp, hbmoldXor, hbmoldMask; + hdcref = GetDC(0); + This->hbmXor = CreateDIBitmap( hdcref, &bih, CBM_INIT, - bits, + mask, (BITMAPINFO*)&bih, DIB_RGB_COLORS ); @@ -1138,12 +1126,11 @@ static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSour DeleteDC(hdcBmp); DeleteDC(hdcXor); DeleteDC(hdcMask); + ReleaseDC(0, hdcref); } - ReleaseDC(0, hdcref); - end: - HeapFree(GetProcessHeap(), 0, bits); + HeapFree(GetProcessHeap(), 0, mask); IWICBitmapSource_Release(real_source); return hr; } diff --git a/dlls/oleaut32/tests/olepicture.c b/dlls/oleaut32/tests/olepicture.c index b716f25..795ee71 100644 --- a/dlls/oleaut32/tests/olepicture.c +++ b/dlls/oleaut32/tests/olepicture.c @@ -240,7 +240,7 @@ test_pic_with_stream(LPSTREAM stream, unsigned int imgsize) { BITMAP bmp; GetObjectA(UlongToHandle(handle), sizeof(BITMAP), &bmp); - todo_wine ok(bmp.bmBits != 0, "not a dib\n"); + ok(bmp.bmBits != 0, "not a dib\n"); } width = 0; -- 2.9.0