Instead of 32-bit or 16-bit per pixel format with BI_BITFIELDS.
From: Akihiro Sagawa sagawa.aki@gmail.com
--- dlls/oleaut32/tests/olepicture.c | 120 +++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+)
diff --git a/dlls/oleaut32/tests/olepicture.c b/dlls/oleaut32/tests/olepicture.c index 07d9ba98f1b..1d591b971cd 100644 --- a/dlls/oleaut32/tests/olepicture.c +++ b/dlls/oleaut32/tests/olepicture.c @@ -1496,6 +1496,125 @@ static void test_load_save_empty_picture(void) IStream_Release(stream); }
+static void test_load_save_dib(void) +{ + IPicture *pic; + PICTDESC desc; + short type; + OLE_HANDLE handle; + HGLOBAL hmem; + DWORD *mem; + IPersistStream *src_stream; + IStream *dst_stream; + LARGE_INTEGER offset; + HRESULT hr; + LONG size; + ULARGE_INTEGER maxsize; + unsigned int bpp; + + for (bpp = 4; bpp <= 32; bpp <<= 1) { + char buffer[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256]; + BITMAPINFO *info = (BITMAPINFO *)buffer; + RGBQUAD *colors = info->bmiColors; + DWORD expected_size, expected_bpp; + void *bits; + + winetest_push_context("bpp %u", bpp); + expected_size = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + + (bpp <= 8 ? sizeof(RGBQUAD) * (1u << bpp) : 0) + + sizeof(DWORD); /* pixels */; + expected_bpp = bpp <= 8 ? bpp : 24; + + memset(info, 0, sizeof(*info)); + info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + info->bmiHeader.biWidth = 1; + info->bmiHeader.biHeight = 1; + info->bmiHeader.biPlanes = 1; + info->bmiHeader.biBitCount = bpp; + info->bmiHeader.biCompression = BI_RGB; + memset(colors, 0xaa, sizeof(RGBQUAD) * 256); + + desc.cbSizeofstruct = sizeof(desc); + desc.picType = PICTYPE_BITMAP; + desc.bmp.hpal = 0; + desc.bmp.hbitmap = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0); + hr = OleCreatePictureIndirect(&desc, &IID_IPicture, TRUE, (void**)&pic); + + hr = IPicture_get_Type(pic, &type); + ok(hr == S_OK,"get_Type error %#8lx\n", hr); + ok(type == PICTYPE_BITMAP,"expected picture type PICTYPE_BITMAP, got %d\n", type); + + hr = IPicture_get_Handle(pic, &handle); + ok(hr == S_OK,"get_Handle error %#8lx\n", hr); + ok(IntToPtr(handle) == desc.bmp.hbitmap, "get_Handle returned wrong handle %#x\n", handle); + + hmem = GlobalAlloc(GMEM_ZEROINIT, 4096); + hr = CreateStreamOnHGlobal(hmem, FALSE, &dst_stream); + ok(hr == S_OK, "createstreamonhglobal error %#lx\n", hr); + + size = -1; + hr = IPicture_SaveAsFile(pic, dst_stream, TRUE, &size); + ok(hr == S_OK, "IPicture_SaveasFile error %#lx\n", hr); + todo_wine + ok(size == expected_size, "expected %ld, got %ld\n", expected_size, size); + if (size == expected_size) { + mem = GlobalLock(hmem); + ok(!memcmp(&mem[0], "BM", 2), "got wrong bmp header %04lx\n", mem[0]); + info = (BITMAPINFO *)(((BITMAPFILEHEADER *)&mem[0]) + 1); + ok(info->bmiHeader.biBitCount == expected_bpp, "expected bpp %lu, got %hu\n", expected_bpp, info->bmiHeader.biBitCount); + ok(info->bmiHeader.biCompression == BI_RGB, "expected BI_RGB, got %lu\n", info->bmiHeader.biCompression); + GlobalUnlock(hmem); + } + + size = -1; + hr = IPicture_SaveAsFile(pic, dst_stream, FALSE, &size); + todo_wine + ok(hr == E_FAIL, "expected E_FAIL, got %#lx\n", hr); + todo_wine + ok(size == -1, "expected -1, got %ld\n", size); + + offset.QuadPart = 0; + hr = IStream_Seek(dst_stream, offset, SEEK_SET, NULL); + ok(hr == S_OK, "IStream_Seek %#lx\n", hr); + + hr = IPicture_QueryInterface(pic, &IID_IPersistStream, (void **)&src_stream); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); + + maxsize.QuadPart = 0; + hr = IPersistStream_GetSizeMax(src_stream, &maxsize); + ok(hr == S_OK, "GetSizeMax error %#lx\n", hr); + ok(maxsize.QuadPart == expected_size + 8, "expected %lx, got %s\n", expected_size + 8, wine_dbgstr_longlong(maxsize.QuadPart)); + + hr = IPersistStream_Save(src_stream, dst_stream, TRUE); + ok(hr == S_OK, "Save error %#lx\n", hr); + + maxsize.QuadPart = 0; + hr = IPersistStream_GetSizeMax(src_stream, &maxsize); + ok(hr == S_OK, "GetSizeMax error %#lx\n", hr); + ok(maxsize.QuadPart == expected_size + 8, "expected %lx, got %s\n", expected_size + 8, wine_dbgstr_longlong(maxsize.QuadPart)); + + IPersistStream_Release(src_stream); + IStream_Release(dst_stream); + + mem = GlobalLock(hmem); + ok(!memcmp(mem, "lt\0\0", 4), "got wrong stream header %04lx\n", mem[0]); + ok(mem[1] == expected_size, "expected stream size %lu, got %lu\n", expected_size, mem[1]); + ok(!memcmp(&mem[2], "BM", 2), "got wrong bmp header %04lx\n", mem[2]); + info = (BITMAPINFO *)(((BITMAPFILEHEADER *)&mem[2]) + 1); + todo_wine_if(bpp != expected_bpp) + ok(info->bmiHeader.biBitCount == expected_bpp, "expected bpp %lu, got %hu\n", expected_bpp, info->bmiHeader.biBitCount); + todo_wine_if(bpp == 16 || bpp == 32) + ok(info->bmiHeader.biCompression == BI_RGB, "expected BI_RGB, got %lu\n", info->bmiHeader.biCompression); + + GlobalUnlock(hmem); + GlobalFree(hmem); + + DeleteObject(desc.bmp.hbitmap); + IPicture_Release(pic); + winetest_pop_context(); + } +} + START_TEST(olepicture) { hOleaut32 = GetModuleHandleA("oleaut32.dll"); @@ -1533,6 +1652,7 @@ START_TEST(olepicture) test_OleLoadPicturePath(); test_himetric(); test_load_save_bmp(); + test_load_save_dib(); test_load_save_icon(); test_load_save_empty_picture(); }
From: Akihiro Sagawa sagawa.aki@gmail.com
Instead of 32-bit or 16-bit per pixel format with BI_BITFIELDS.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56246 --- dlls/oleaut32/olepicture.c | 41 +++++++++++++++++++++++++++++++- dlls/oleaut32/tests/olepicture.c | 2 -- 2 files changed, 40 insertions(+), 3 deletions(-)
diff --git a/dlls/oleaut32/olepicture.c b/dlls/oleaut32/olepicture.c index e4bfafe6fd0..03679ad91cb 100644 --- a/dlls/oleaut32/olepicture.c +++ b/dlls/oleaut32/olepicture.c @@ -1538,6 +1538,8 @@ static HRESULT serializeBMP(HBITMAP hbmp, void **buffer, unsigned int *length) { char infobuf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)] = { 0 }; BITMAPINFO *info = (BITMAPINFO *)infobuf; + BITMAP bm; + HBITMAP hdib = NULL; BITMAPINFO *bitmap; BITMAPFILEHEADER *filehdr; int numentries; @@ -1545,8 +1547,43 @@ static HRESULT serializeBMP(HBITMAP hbmp, void **buffer, unsigned int *length) HRESULT hr = S_OK; unsigned char *data = NULL;
- /* Find out bitmap size and padded length */ hdc = GetDC(0); + if (!GetObjectW(hbmp, sizeof(bm), &bm)) { + hr = E_INVALIDARG; + goto done; + } + + /* Convert 16bpp/32bpp bitmap to 24bpp */ + if (bm.bmBitsPixel == 16 || bm.bmBitsPixel == 32) { + void *bits; + info->bmiHeader.biSize = sizeof(info->bmiHeader); + info->bmiHeader.biWidth = bm.bmWidth; + info->bmiHeader.biHeight = bm.bmHeight; + info->bmiHeader.biPlanes = 1; + info->bmiHeader.biBitCount = 24; + info->bmiHeader.biCompression = BI_RGB; + hdib = CreateDIBSection(hdc, info, DIB_RGB_COLORS, &bits, NULL, 0); + if (!hdib) { + hr = E_OUTOFMEMORY; + goto done; + } + if (buffer) { + HDC src, dst; + src = CreateCompatibleDC(hdc); + dst = CreateCompatibleDC(hdc); + SelectObject(src, hbmp); + SelectObject(dst, hdib); + if (!BitBlt(dst, 0, 0, bm.bmWidth, bm.bmHeight, src, 0, 0, SRCCOPY)) + hr = E_INVALIDARG; + DeleteDC(src); + DeleteDC(dst); + if (FAILED(hr)) + goto done; + } + hbmp = hdib; + } + + /* Find out bitmap size and padded length */ info->bmiHeader.biSize = sizeof(info->bmiHeader); if (!GetDIBits(hdc, hbmp, 0, 0, NULL, info, DIB_RGB_COLORS)) { hr = E_INVALIDARG; @@ -1607,6 +1644,8 @@ static HRESULT serializeBMP(HBITMAP hbmp, void **buffer, unsigned int *length) done: free(data); ReleaseDC(0, hdc); + if (hdib && hbmp == hdib) + DeleteObject(hdib); return hr; }
diff --git a/dlls/oleaut32/tests/olepicture.c b/dlls/oleaut32/tests/olepicture.c index 1d591b971cd..f0468a6f83c 100644 --- a/dlls/oleaut32/tests/olepicture.c +++ b/dlls/oleaut32/tests/olepicture.c @@ -1601,9 +1601,7 @@ static void test_load_save_dib(void) ok(mem[1] == expected_size, "expected stream size %lu, got %lu\n", expected_size, mem[1]); ok(!memcmp(&mem[2], "BM", 2), "got wrong bmp header %04lx\n", mem[2]); info = (BITMAPINFO *)(((BITMAPFILEHEADER *)&mem[2]) + 1); - todo_wine_if(bpp != expected_bpp) ok(info->bmiHeader.biBitCount == expected_bpp, "expected bpp %lu, got %hu\n", expected_bpp, info->bmiHeader.biBitCount); - todo_wine_if(bpp == 16 || bpp == 32) ok(info->bmiHeader.biCompression == BI_RGB, "expected BI_RGB, got %lu\n", info->bmiHeader.biCompression);
GlobalUnlock(hmem);
From: Akihiro Sagawa sagawa.aki@gmail.com
--- dlls/oleaut32/olepicture.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/dlls/oleaut32/olepicture.c b/dlls/oleaut32/olepicture.c index 03679ad91cb..08a7fd73883 100644 --- a/dlls/oleaut32/olepicture.c +++ b/dlls/oleaut32/olepicture.c @@ -1631,6 +1631,8 @@ static HRESULT serializeBMP(HBITMAP hbmp, void **buffer, unsigned int *length) filehdr = *buffer; filehdr->bfType = BITMAP_FORMAT_BMP; filehdr->bfSize = *length; + filehdr->bfReserved1 = 0; + filehdr->bfReserved2 = 0; filehdr->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=147083
Your paranoid android.
=== debian11b (64 bit WoW report) ===
secur32: schannel.c:1138: Test failed: Wrong buffer size schannel.c:1187: Test failed: InitializeSecurityContext failed: 80090304 schannel.c:1575: Test failed: got 80090304
urlmon: protocol.c:857: Test failed: szStatusText = L"text/javascript"
user32: input.c:4305: Test succeeded inside todo block: button_down_hwnd_todo 1: got MSG_TEST_WIN hwnd 00000000012B00DC, msg WM_LBUTTONDOWN, wparam 0x1, lparam 0x320032