From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/surface.c | 50 ++++++++++++++++++++++++++++++----- dlls/d3dx9_36/tests/surface.c | 4 +-- 2 files changed, 46 insertions(+), 8 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c index dcffab5e5ce..5010d5990d1 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -821,7 +821,11 @@ static const char *debug_d3dx_image_file_format(D3DXIMAGE_FILEFORMAT format) static HRESULT d3dx_image_wic_frame_decode(struct d3dx_image *image, IWICImagingFactory *wic_factory, IWICBitmapFrameDecode *bitmap_frame) { + const GUID *dst_pixel_format = d3dformat_to_wic_guid(image->format); + IWICFormatConverter *wic_converter = NULL; const struct pixel_format_desc *fmt_desc; + IWICBitmapSource *wic_bitmap_src = NULL; + WICPixelFormatGUID src_pixel_format; uint32_t row_pitch, slice_pitch; IWICPalette *wic_palette = NULL; PALETTEENTRY *palette = NULL; @@ -838,13 +842,40 @@ static HRESULT d3dx_image_wic_frame_decode(struct d3dx_image *image, if (!(buffer = malloc(slice_pitch))) return E_OUTOFMEMORY;
- hr = IWICBitmapFrameDecode_CopyPixels(bitmap_frame, NULL, row_pitch, slice_pitch, buffer); + hr = IWICBitmapFrameDecode_GetPixelFormat(bitmap_frame, &src_pixel_format); if (FAILED(hr)) + goto exit; + + /* + * Needs conversion. Ignore D3DFMT_P8 because multiple different WIC + * formats map to D3DFMT_P8, and they don't require conversion. + */ + if (memcmp(&src_pixel_format, dst_pixel_format, sizeof(*dst_pixel_format)) && image->format != D3DFMT_P8) { - free(buffer); - return hr; + hr = IWICImagingFactory_CreateFormatConverter(wic_factory, &wic_converter); + if (FAILED(hr)) + goto exit; + + hr = IWICFormatConverter_Initialize(wic_converter, (IWICBitmapSource *)bitmap_frame, dst_pixel_format, + WICBitmapDitherTypeErrorDiffusion, 0, 0, WICBitmapPaletteTypeCustom); + if (FAILED(hr)) + goto exit; + + hr = IWICFormatConverter_QueryInterface(wic_converter, &IID_IWICBitmapSource, (void **)&wic_bitmap_src); + if (FAILED(hr)) + goto exit; + } + else + { + hr = IWICBitmapFrameDecode_QueryInterface(bitmap_frame, &IID_IWICBitmapSource, (void **)&wic_bitmap_src); + if (FAILED(hr)) + goto exit; }
+ hr = IWICBitmapSource_CopyPixels(wic_bitmap_src, NULL, row_pitch, slice_pitch, buffer); + if (FAILED(hr)) + goto exit; + if (is_index_format(fmt_desc)) { uint32_t nb_colors, i; @@ -853,7 +884,7 @@ static HRESULT d3dx_image_wic_frame_decode(struct d3dx_image *image, if (FAILED(hr)) goto exit;
- hr = IWICBitmapFrameDecode_CopyPalette(bitmap_frame, wic_palette); + hr = IWICBitmapSource_CopyPalette(wic_bitmap_src, wic_palette); if (FAILED(hr)) goto exit;
@@ -890,6 +921,10 @@ exit: free(colors); if (image->image_buf != buffer) free(buffer); + if (wic_converter) + IWICFormatConverter_Release(wic_converter); + if (wic_bitmap_src) + IWICBitmapSource_Release(wic_bitmap_src); if (image->image_palette != palette) free(palette); if (wic_palette) @@ -957,8 +992,8 @@ static HRESULT d3dx_initialize_image_from_wic(const void *src_data, uint32_t src goto exit; }
- if (image_is_argb(bitmap_frame, image)) - image->format = D3DFMT_A8R8G8B8; + if (image->format == D3DFMT_R8G8B8 && (d3dx_file_format == D3DXIFF_JPG || d3dx_file_format == D3DXIFF_PNG)) + image->format = D3DFMT_X8R8G8B8;
if (!(flags & D3DX_IMAGE_INFO_ONLY)) { @@ -967,6 +1002,9 @@ static HRESULT d3dx_initialize_image_from_wic(const void *src_data, uint32_t src goto exit; }
+ if (image_is_argb(bitmap_frame, image)) + image->format = D3DFMT_A8R8G8B8; + image->size.depth = 1; image->mip_levels = 1; image->layer_count = 1; diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c index b57f5e32ad8..3411f03c8e0 100644 --- a/dlls/d3dx9_36/tests/surface.c +++ b/dlls/d3dx9_36/tests/surface.c @@ -930,7 +930,7 @@ static void test_D3DXGetImageInfo(void) /* Test JPG support. */ hr = D3DXGetImageInfoFromFileInMemory(jpg_rgb_2_2, sizeof(jpg_rgb_2_2), &info); ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); - check_image_info(&info, 2, 2, 1, 1, D3DFMT_X8R8G8B8, D3DRTYPE_TEXTURE, D3DXIFF_JPG, TRUE); + check_image_info(&info, 2, 2, 1, 1, D3DFMT_X8R8G8B8, D3DRTYPE_TEXTURE, D3DXIFF_JPG, FALSE);
hr = D3DXGetImageInfoFromFileInMemory(jpg_grayscale_2_2, sizeof(jpg_grayscale_2_2), &info); ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); @@ -944,7 +944,7 @@ static void test_D3DXGetImageInfo(void)
hr = D3DXGetImageInfoFromFileInMemory(png_2_2_24bpp_bgr, sizeof(png_2_2_24bpp_bgr), &info); ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); - check_image_info(&info, 2, 2, 1, 1, D3DFMT_X8R8G8B8, D3DRTYPE_TEXTURE, D3DXIFF_PNG, TRUE); + check_image_info(&info, 2, 2, 1, 1, D3DFMT_X8R8G8B8, D3DRTYPE_TEXTURE, D3DXIFF_PNG, FALSE);
/* Grayscale PNG */ hr = D3DXGetImageInfoFromFileInMemory(png_grayscale, sizeof(png_grayscale), &info);