wine-staging/patches/oleaut32-OleLoadPicture/0001-oleaut32-OleLoadPicture-should-create-a-DIB-section-.patch
2023-07-05 13:05:46 +10:00

167 lines
4.8 KiB
Diff

From a9cd52667f49a57900a08591cd66b40747a12db0 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Thu, 21 Apr 2016 14:40:58 +0800
Subject: [PATCH] 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 45baa74a439..22a34d6e380 100644
--- a/dlls/oleaut32/olepicture.c
+++ b/dlls/oleaut32/olepicture.c
@@ -983,23 +983,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.bmp.hbitmap = CreateDIBitmap(
- hdcref,
- &(bi->bmiHeader),
- CBM_INIT,
- xbuf+bfh->bfOffBits,
- bi,
- DIB_RGB_COLORS
- );
- ReleaseDC(0, hdcref);
+ This->desc.bmp.hbitmap = CreateDIBSection(0, bi, DIB_RGB_COLORS, &bits, NULL, 0);
if (This->desc.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;
@@ -1009,10 +1002,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;
@@ -1040,34 +1032,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.bmp.hbitmap = CreateDIBSection(0, (BITMAPINFO*)&bih, DIB_RGB_COLORS, (void **)&bits, NULL, 0);
+ if (This->desc.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.bmp.hbitmap = CreateDIBitmap(
- hdcref,
- &bih,
- CBM_INIT,
- bits,
- (BITMAPINFO*)&bih,
- DIB_RGB_COLORS);
-
- if (This->desc.bmp.hbitmap == 0)
{
- hr = E_FAIL;
- ReleaseDC(0, hdcref);
+ DeleteObject(This->desc.bmp.hbitmap);
goto end;
}
@@ -1081,23 +1067,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
);
@@ -1122,12 +1110,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 7b45b690935..fa7e8009cbd 100644
--- a/dlls/oleaut32/tests/olepicture.c
+++ b/dlls/oleaut32/tests/olepicture.c
@@ -239,7 +239,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.40.1