From 8f6c832b3178279321140d4a79f2b66bdd069c0f Mon Sep 17 00:00:00 2001 From: Christian Costa Date: Sat, 30 Jan 2021 13:50:48 -0600 Subject: [PATCH] d3dx9: Return D3DFMT_A8R8G8B8 in D3DXGetImageInfoFromFileInMemory for 32 bpp BMP with alpha. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48563 Signed-off-by: Zebediah Figura Signed-off-by: Matteo Bruni Signed-off-by: Alexandre Julliard --- dlls/d3dx9_36/surface.c | 38 +++++++++++++++++++++++++++++++++++ dlls/d3dx9_36/tests/surface.c | 2 +- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c index 045d7267c96..362113386ea 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -887,6 +887,41 @@ static BOOL convert_dib_to_bmp(const void **data, unsigned int *size) return TRUE; } +/* windowscodecs always returns xRGB, but we should return ARGB if and only if + * at least one pixel has a non-zero alpha component. */ +static BOOL image_is_argb(IWICBitmapFrameDecode *frame, const D3DXIMAGE_INFO *info) +{ + unsigned int size, i; + BYTE *buffer; + HRESULT hr; + + if (info->Format != D3DFMT_X8R8G8B8 || info->ImageFileFormat != D3DXIFF_BMP) + return FALSE; + + size = info->Width * info->Height * 4; + if (!(buffer = malloc(size))) + return FALSE; + + if (FAILED(hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, info->Width * 4, size, buffer))) + { + ERR("Failed to copy pixels, hr %#x.\n", hr); + free(buffer); + return FALSE; + } + + for (i = 0; i < info->Width * info->Height; ++i) + { + if (buffer[i * 4 + 3]) + { + free(buffer); + return TRUE; + } + } + + free(buffer); + return FALSE; +} + /************************************************************ * D3DXGetImageInfoFromFileInMemory * @@ -1006,6 +1041,9 @@ HRESULT WINAPI D3DXGetImageInfoFromFileInMemory(const void *data, UINT datasize, } } + if (SUCCEEDED(hr) && image_is_argb(frame, info)) + info->Format = D3DFMT_A8R8G8B8; + if (frame) IWICBitmapFrameDecode_Release(frame); diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c index 4590a758d78..1d32b68c3a6 100644 --- a/dlls/d3dx9_36/tests/surface.c +++ b/dlls/d3dx9_36/tests/surface.c @@ -698,7 +698,7 @@ static void test_D3DXGetImageInfo(void) ok(info.Format == D3DFMT_X8R8G8B8, "Got unexpected format %u.\n", info.Format); hr = D3DXGetImageInfoFromFileInMemory(bmp_32bpp_argb, sizeof(bmp_32bpp_argb), &info); ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); - todo_wine ok(info.Format == D3DFMT_A8R8G8B8, "Got unexpected format %u.\n", info.Format); + ok(info.Format == D3DFMT_A8R8G8B8, "Got unexpected format %u.\n", info.Format); /* Grayscale PNG */ hr = D3DXGetImageInfoFromFileInMemory(png_grayscale, sizeof(png_grayscale), &info);