Ziqing Hui : windowscodecs/tests: Add tests for decoding BC1 format.

Alexandre Julliard julliard at winehq.org
Tue Aug 18 16:34:23 CDT 2020


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

Author: Ziqing Hui <zhui at codeweavers.com>
Date:   Mon Aug 17 10:24:13 2020 +0800

windowscodecs/tests: Add tests for decoding BC1 format.

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/tests/ddsformat.c | 104 +++++++++++++++++++++++++++++++++++
 1 file changed, 104 insertions(+)

diff --git a/dlls/windowscodecs/tests/ddsformat.c b/dlls/windowscodecs/tests/ddsformat.c
index 2d5afa8e6e..989f4317c0 100644
--- a/dlls/windowscodecs/tests/ddsformat.c
+++ b/dlls/windowscodecs/tests/ddsformat.c
@@ -24,6 +24,12 @@
 #include "wincodec.h"
 #include "wine/test.h"
 
+#define GET_RGB565_R(color)   ((BYTE)(((color) >> 11) & 0x1F))
+#define GET_RGB565_G(color)   ((BYTE)(((color) >> 5)  & 0x3F))
+#define GET_RGB565_B(color)   ((BYTE)(((color) >> 0)  & 0x1F))
+#define MAKE_RGB565(r, g, b)  ((WORD)(((BYTE)(r) << 11) | ((BYTE)(g) << 5) | (BYTE)(b)))
+#define MAKE_ARGB(a, r, g, b) (((DWORD)(a) << 24) | ((DWORD)(r) << 16) | ((DWORD)(g) << 8) | (DWORD)(b))
+
 /* 1x1 uncompressed(Alpha) DDS image */
 static BYTE test_dds_alpha[] = {
     'D',  'D',  'S',  ' ',  0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,
@@ -529,6 +535,81 @@ end:
     return bpp;
 }
 
+static DWORD rgb565_to_argb(WORD color, BOOL has_alpha)
+{
+    return (has_alpha && !color) ? 0: MAKE_ARGB(0xFF, (GET_RGB565_R(color) * 0xFF + 0x0F) / 0x1F,
+                                                      (GET_RGB565_G(color) * 0xFF + 0x1F) / 0x3F,
+                                                      (GET_RGB565_B(color) * 0xFF + 0x0F) / 0x1F);
+}
+
+static void decode_bc1(const BYTE *blocks, UINT block_count, UINT width, UINT height, DWORD *buffer)
+{
+    static const UINT BLOCK_SIZE = 8;
+
+    UINT stride = (width + 3) / 4 * 4;
+    int i, j, color_index, pixel_index = 0;
+    const BYTE *block, *color_indices;
+    DWORD *pixel = buffer;
+    BOOL has_alpha;
+    WORD color[4];
+
+    for (i = 0; i < block_count; i++)
+    {
+        block = blocks + i * BLOCK_SIZE;
+        color[0] = *((WORD *)block);
+        color[1] = *((WORD *)block + 1);
+        has_alpha = color[0] <= color[1];
+        if (has_alpha) {
+            color[2] = MAKE_RGB565(((GET_RGB565_R(color[0]) + GET_RGB565_R(color[1]) + 1) / 2),
+                                   ((GET_RGB565_G(color[0]) + GET_RGB565_G(color[1]) + 1) / 2),
+                                   ((GET_RGB565_B(color[0]) + GET_RGB565_B(color[1]) + 1) / 2));
+            color[3] = 0;
+        } else {
+            color[2] = MAKE_RGB565(((GET_RGB565_R(color[0]) * 2 + GET_RGB565_R(color[1]) + 1) / 3),
+                                   ((GET_RGB565_G(color[0]) * 2 + GET_RGB565_G(color[1]) + 1) / 3),
+                                   ((GET_RGB565_B(color[0]) * 2 + GET_RGB565_B(color[1]) + 1) / 3));
+            color[3] = MAKE_RGB565(((GET_RGB565_R(color[0]) + GET_RGB565_R(color[1]) * 2 + 1) / 3),
+                                   ((GET_RGB565_G(color[0]) + GET_RGB565_G(color[1]) * 2 + 1) / 3),
+                                   ((GET_RGB565_B(color[0]) + GET_RGB565_B(color[1]) * 2 + 1) / 3));
+        }
+
+        color_indices = blocks + 4;
+        for (j = 0; j < 16; j++, pixel_index++)
+        {
+            if ((pixel_index % stride >= width) ||
+                (pixel_index / stride >= height)) continue;
+
+            color_index = (color_indices[j / 4] >> ((j % 4) * 2)) & 0x3;
+            *pixel = rgb565_to_argb(color[color_index], has_alpha);
+            pixel++;
+        }
+    }
+}
+
+static BOOL color_match(DWORD color_a, DWORD color_b)
+{
+    static const int tolerance = 8;
+
+    const int da = abs((int)((color_a & 0xFF000000) >> 24) - (int)((color_b & 0xFF000000) >> 24));
+    const int dr = abs((int)((color_a & 0x00FF0000) >> 16) - (int)((color_b & 0x00FF0000) >> 16));
+    const int dg = abs((int)((color_a & 0x0000FF00) >> 8)  - (int)((color_b & 0x0000FF00) >> 8));
+    const int db = abs((int)((color_a & 0x000000FF) >> 0)  - (int)((color_b & 0x000000FF) >> 0));
+
+    return (da <= tolerance && dr <= tolerance && dg <= tolerance && db <= tolerance);
+}
+
+static BOOL color_buffer_match(DWORD *color_buffer_a, DWORD *color_buffer_b, UINT color_count)
+{
+    UINT i;
+
+    for (i = 0; i < color_count; i++)
+    {
+        if (!color_match(color_buffer_a[i], color_buffer_b[i])) return FALSE;
+    }
+
+    return TRUE;
+}
+
 static void test_dds_decoder_initialize(void)
 {
     int i;
@@ -799,6 +880,7 @@ static void test_dds_decoder_frame_data(IWICBitmapFrameDecode* frame, IWICDdsFra
     WICRect rect = { 0, 0, 1, 1 }, rect_test_a = { 0, 0, 0, 0 }, rect_test_b = { 0, 0, 0xdeadbeaf, 0xdeadbeaf };
     WICRect rect_test_c = { -0xdeadbeaf, -0xdeadbeaf, 1, 1 }, rect_test_d = { 0xdeadbeaf, 0xdeadbeaf, 1, 1 };
     BYTE buffer[2048];
+    DWORD pixels[2048];
     UINT stride, frame_stride, frame_size, frame_width, frame_height, width_in_blocks, height_in_blocks, bpp;
     UINT width, height, depth, array_index;
     UINT block_offset;
@@ -909,6 +991,7 @@ static void test_dds_decoder_frame_data(IWICBitmapFrameDecode* frame, IWICDdsFra
     bpp = get_pixel_format_bpp(&pixel_format);
     stride = rect.Width * bpp / 8;
     frame_stride = frame_width * bpp / 8;
+    frame_size = frame_stride * frame_height;
 
     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);
@@ -952,6 +1035,27 @@ static void test_dds_decoder_frame_data(IWICBitmapFrameDecode* frame, IWICDdsFra
 
     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);
+
+    if (format_info.DxgiFormat == DXGI_FORMAT_BC1_UNORM) {
+        decode_bc1(test_data[i].data + block_offset, width_in_blocks * height_in_blocks, frame_width, frame_height, pixels);
+
+        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);
+        if (hr == S_OK) {
+            todo_wine
+            ok(color_buffer_match((DWORD *)pixels, (DWORD *)buffer, 1),
+               "Test %u, frame %u: Pixels mismatch\n", i, frame_index);
+        }
+
+
+        hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, frame_stride, sizeof(buffer), buffer);
+        ok(hr == S_OK, "Test %u, frame %u: CopyPixels failed, hr %#x\n", i, frame_index, hr);
+        if (hr == S_OK) {
+            todo_wine
+            ok(color_buffer_match((DWORD *)pixels, (DWORD *)buffer, frame_size / (bpp / 8)),
+              "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