Ziqing Hui : windowscodecs: Correctly set pixel format of uncompressed DDS with extended header.

Alexandre Julliard julliard at winehq.org
Mon Nov 9 15:11:50 CST 2020


Module: wine
Branch: master
Commit: 3b531c06e009a15d0f77c55bf724d4772ae68038
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=3b531c06e009a15d0f77c55bf724d4772ae68038

Author: Ziqing Hui <zhui at codeweavers.com>
Date:   Fri Nov  6 11:43:47 2020 +0800

windowscodecs: Correctly set pixel format of uncompressed DDS with extended header.

Signed-off-by: Ziqing Hui <zhui at codeweavers.com>
Signed-off-by: Esme Povirk <esme at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/windowscodecs/ddsformat.c       | 36 ++++++++++++++++++++++++++++++++----
 dlls/windowscodecs/tests/ddsformat.c |  5 -----
 2 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/dlls/windowscodecs/ddsformat.c b/dlls/windowscodecs/ddsformat.c
index 9e6886e7ea7..d0932767d6f 100644
--- a/dlls/windowscodecs/ddsformat.c
+++ b/dlls/windowscodecs/ddsformat.c
@@ -251,7 +251,24 @@ static struct dds_format {
       &GUID_WICPixelFormatUndefined,        0,  DXGI_FORMAT_R8G8_UNORM },
     { { sizeof(DDS_PIXELFORMAT), DDPF_LUMINANCE, 0, 8,  0xFF,0,0,0 },
       &GUID_WICPixelFormat8bppGray,         8,  DXGI_FORMAT_R8_UNORM },
-    { { 0 }, &GUID_WICPixelFormatUndefined, 0,  DXGI_FORMAT_UNKNOWN }
+    { { 0 }, &GUID_WICPixelFormat8bppAlpha,          8,   DXGI_FORMAT_A8_UNORM },
+    { { 0 }, &GUID_WICPixelFormat8bppGray,           8,   DXGI_FORMAT_R8_UNORM },
+    { { 0 }, &GUID_WICPixelFormat16bppGray,          16,  DXGI_FORMAT_R16_UNORM },
+    { { 0 }, &GUID_WICPixelFormat16bppGrayHalf,      16,  DXGI_FORMAT_R16_FLOAT },
+    { { 0 }, &GUID_WICPixelFormat16bppBGR565,        16,  DXGI_FORMAT_B5G6R5_UNORM },
+    { { 0 }, &GUID_WICPixelFormat16bppBGRA5551,      16,  DXGI_FORMAT_B5G5R5A1_UNORM },
+    { { 0 }, &GUID_WICPixelFormat32bppGrayFloat,     32,  DXGI_FORMAT_R32_FLOAT },
+    { { 0 }, &GUID_WICPixelFormat32bppRGBA,          32,  DXGI_FORMAT_R8G8B8A8_UNORM },
+    { { 0 }, &GUID_WICPixelFormat32bppBGRA,          32,  DXGI_FORMAT_B8G8R8A8_UNORM },
+    { { 0 }, &GUID_WICPixelFormat32bppBGR,           32,  DXGI_FORMAT_B8G8R8X8_UNORM },
+    { { 0 }, &GUID_WICPixelFormat32bppR10G10B10A2,   32,  DXGI_FORMAT_R10G10B10A2_UNORM },
+    { { 0 }, &GUID_WICPixelFormat32bppRGBE,          32,  DXGI_FORMAT_R9G9B9E5_SHAREDEXP },
+    { { 0 }, &GUID_WICPixelFormat32bppRGBA1010102XR, 32,  DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM },
+    { { 0 }, &GUID_WICPixelFormat64bppRGBA,          64,  DXGI_FORMAT_R16G16B16A16_UNORM },
+    { { 0 }, &GUID_WICPixelFormat64bppRGBAHalf,      64,  DXGI_FORMAT_R16G16B16A16_FLOAT },
+    { { 0 }, &GUID_WICPixelFormat96bppRGBFloat,      96,  DXGI_FORMAT_R32G32B32_FLOAT },
+    { { 0 }, &GUID_WICPixelFormat128bppRGBAFloat,    128, DXGI_FORMAT_R32G32B32A32_FLOAT },
+    { { 0 }, &GUID_WICPixelFormatUndefined,          0,   DXGI_FORMAT_UNKNOWN }
 };
 
 static DXGI_FORMAT compressed_formats[] = {
@@ -449,6 +466,18 @@ static UINT get_bytes_per_block_from_format(DXGI_FORMAT format)
     }
 }
 
+static const GUID *dxgi_format_to_wic_format(DXGI_FORMAT dxgi_format)
+{
+    UINT i;
+    for (i = 0; i < ARRAY_SIZE(dds_format_table); i++)
+    {
+        if (dds_format_table[i].pixel_format.size == 0 &&
+            dds_format_table[i].dxgi_format == dxgi_format)
+            return dds_format_table[i].wic_format;
+    }
+    return &GUID_WICPixelFormatUndefined;
+}
+
 static BOOL is_compressed(DXGI_FORMAT format)
 {
     UINT i;
@@ -485,9 +514,8 @@ static void get_dds_info(dds_info* info, DDS_HEADER *header, DDS_HEADER_DXT10 *h
                                  &GUID_WICPixelFormat32bppPBGRA : &GUID_WICPixelFormat32bppBGRA;
             info->pixel_format_bpp = 32;
         } else {
-            info->pixel_format = &GUID_WICPixelFormatUndefined;
-            info->pixel_format_bpp = 0;
-            FIXME("Pixel format is incorrect for uncompressed DDS image with extended header\n");
+            info->pixel_format = dxgi_format_to_wic_format(info->format);
+            info->pixel_format_bpp = get_bytes_per_block_from_format(info->format) * 8;
         }
     } else {
         format_info = get_dds_format(&header->ddspf);
diff --git a/dlls/windowscodecs/tests/ddsformat.c b/dlls/windowscodecs/tests/ddsformat.c
index 2e7304b9d42..b7b002d380d 100644
--- a/dlls/windowscodecs/tests/ddsformat.c
+++ b/dlls/windowscodecs/tests/ddsformat.c
@@ -941,7 +941,6 @@ static void test_dds_decoder_frame_properties(IWICBitmapFrameDecode *frame_decod
     hr = IWICBitmapFrameDecode_GetPixelFormat(frame_decode, &pixel_format);
     ok(hr == S_OK, "Test %u, frame %u: GetPixelFormat failed, hr %#x\n", i, frame_index, hr);
     if (hr != S_OK) return;
-    todo_wine_if(IsEqualGUID(test_data[i].expected_pixel_format, &GUID_WICPixelFormat96bppRGBFloat))
     ok(IsEqualGUID(&pixel_format, test_data[i].expected_pixel_format),
        "Test %u, frame %u: Expected pixel format %s, got %s\n",
        i, frame_index, debugstr_guid(test_data[i].expected_pixel_format), debugstr_guid(&pixel_format));
@@ -1076,7 +1075,6 @@ static void test_dds_decoder_frame_data(IWICBitmapFrameDecode* frame, IWICDdsFra
     hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, 0, 0, NULL);
     ok(hr == E_INVALIDARG, "Test %u, frame %u: CopyPixels got unexpected hr %#x\n", i, frame_index, hr);
 
-    todo_wine_if(IsEqualGUID(test_data[i].expected_pixel_format, &GUID_WICPixelFormat96bppRGBFloat)) {
     hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect_test_a, stride, sizeof(buffer), buffer);
     ok(hr == E_INVALIDARG, "Test %u, frame %u: CopyPixels got unexpected hr %#x\n", i, frame_index, hr);
     hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect_test_b, stride, sizeof(buffer), buffer);
@@ -1113,7 +1111,6 @@ static void test_dds_decoder_frame_data(IWICBitmapFrameDecode* frame, IWICDdsFra
     ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "Test %u, frame %u: CopyPixels got unexpected hr %#x\n", i, frame_index, hr);
     hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, stride, stride * rect.Height, buffer);
     ok(hr == S_OK, "Test %u, frame %u: CopyPixels got unexpected hr %#x\n", i, frame_index, hr);
-    }
 
     hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, stride, sizeof(buffer), NULL);
     ok(hr == E_INVALIDARG, "Test %u, frame %u: CopyBlocks got unexpected hr %#x\n", i, frame_index, hr);
@@ -1126,7 +1123,6 @@ static void test_dds_decoder_frame_data(IWICBitmapFrameDecode* frame, IWICDdsFra
         memcpy(pixels, test_data[i].data + block_offset, frame_size);
     }
 
-    todo_wine_if(IsEqualGUID(test_data[i].expected_pixel_format, &GUID_WICPixelFormat96bppRGBFloat)) {
     memset(buffer, 0, sizeof(buffer));
     hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, stride, sizeof(buffer), buffer);
     ok(hr == S_OK, "Test %u, frame %u: CopyPixels failed, hr %#x\n", i, frame_index, hr);
@@ -1152,7 +1148,6 @@ static void test_dds_decoder_frame_data(IWICBitmapFrameDecode* frame, IWICDdsFra
                "Test %u, frame %u: Pixels mismatch\n", i, frame_index);
         };
     }
-    }
 }
 
 static void test_dds_decoder_frame(IWICBitmapDecoder *decoder, int i)




More information about the wine-cvs mailing list