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);