[PATCH v2] user32/tests: Add some tests for implicit stretch mode in CopyImage().

Paul Gofman gofmanp at gmail.com
Fri Dec 28 14:15:16 CST 2018


The test is related to bug https://bugs.winehq.org/show_bug.cgi?id=46375.
The values of the colored test result suggest that halftone filter is
used for shrinking: each pixel of output 2x2 image has the color value
averaged over 4 pixels from input 4x4 image.

Signed-off-by: Paul Gofman <gofmanp at gmail.com>
---
v2: Fixed some typos.

 dlls/user32/tests/cursoricon.c | 125 +++++++++++++++++++++++++++++++++
 1 file changed, 125 insertions(+)

diff --git a/dlls/user32/tests/cursoricon.c b/dlls/user32/tests/cursoricon.c
index 323db82bc3..c598b232a0 100644
--- a/dlls/user32/tests/cursoricon.c
+++ b/dlls/user32/tests/cursoricon.c
@@ -2751,6 +2751,130 @@ static void test_monochrome_icon(void)
     HeapFree(GetProcessHeap(), 0, icon_data);
 }
 
+static COLORREF get_color_from_bits(const unsigned char *bits, const BITMAPINFO *bmi,
+        unsigned int row, unsigned int column)
+{
+    const BITMAPINFOHEADER *h = &bmi->bmiHeader;
+    const unsigned char *data;
+    unsigned int stride;
+    RGBQUAD color;
+
+    ok(h->biBitCount == 1 || h->biBitCount >= 24, "Unsupported bit count %u.\n", h->biBitCount);
+    stride = ((h->biBitCount * h->biWidth + 7) / 8 + 3) & ~3;
+    data = bits + row * stride + column * h->biBitCount / 8;
+    if (h->biBitCount >= 24)
+        return RGB(data[2], data[1], data[0]);
+
+    color = bmi->bmiColors[!!(data[0] & (1u << (7 - (column % 8))))];
+    return RGB(color.rgbRed, color.rgbGreen, color.rgbBlue);
+}
+
+static void test_CopyImage_StretchMode(void)
+{
+    static const unsigned char test_bits_24[] =
+    {
+        0x00, 0xff, 0x00,  0x00, 0xff, 0x00,  0x00, 0xff, 0xff,  0x00, 0xff, 0x00,
+        0x00, 0xff, 0x00,  0xff, 0xff, 0x00,  0xff, 0xff, 0x00,  0x00, 0xff, 0x00,
+        0x00, 0xff, 0xff,  0x00, 0xff, 0x00,  0x00, 0xff, 0xff,  0x00, 0xff, 0x00,
+        0xff, 0xff, 0x00,  0x00, 0xff, 0xff,  0x00, 0xff, 0x00,  0x00, 0xff, 0x00,
+    };
+    static const unsigned char expected_bits_24[] =
+    {
+        0x3f, 0xff, 0x00,  0x3f, 0xff, 0x3f,  0x00, 0x00,
+        0x3f, 0xff, 0x7f,  0x00, 0xff, 0x3f,  0x00, 0x00,
+    };
+    static const unsigned char test_bits_1[] =
+    {
+        0x30, 0x0, 0x0, 0x0,
+        0x30, 0x0, 0x0, 0x0,
+        0x40, 0x0, 0x0, 0x0,
+        0xc0, 0x0, 0x0, 0x0,
+    };
+    static const unsigned char expected_bits_1[] =
+    {
+        0x40, 0x0, 0x0, 0x0,
+        0x0,  0x0, 0x0, 0x0,
+    };
+
+    static const struct
+    {
+        LONG width, height, output_width, output_height;
+        WORD bit_count;
+        const unsigned char *test_bits, *expected_bits;
+        size_t test_bits_size, result_bits_size;
+        BOOL todo;
+    }
+    tests[] =
+    {
+        {4, 4, 2, 2, 24, test_bits_24, expected_bits_24,
+                sizeof(test_bits_24), sizeof(expected_bits_24), TRUE},
+        {4, 4, 2, 2, 1, test_bits_1, expected_bits_1,
+                sizeof(test_bits_1), sizeof(expected_bits_1), FALSE},
+    };
+
+    HBITMAP bitmap, bitmap_copy;
+    unsigned char *result_bits;
+    unsigned int row, column;
+    unsigned int test_index;
+    unsigned char *bits;
+    BITMAPINFO *bmi;
+    HDC hdc;
+    int ret;
+
+    bmi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
+    bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+    bmi->bmiHeader.biPlanes = 1;
+    bmi->bmiHeader.biCompression = BI_RGB;
+    bmi->bmiColors[1].rgbRed = 0xff;
+    bmi->bmiColors[1].rgbGreen = 0xff;
+    bmi->bmiColors[1].rgbBlue = 0xff;
+
+    hdc = GetDC(NULL);
+
+    for (test_index = 0; test_index < ARRAY_SIZE(tests); ++test_index)
+    {
+        bmi->bmiHeader.biWidth = tests[test_index].width;
+        bmi->bmiHeader.biHeight = tests[test_index].height;
+        bmi->bmiHeader.biBitCount = tests[test_index].bit_count;
+
+        bitmap = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, (void **)&bits, NULL, 0);
+        ok(bitmap && bits, "CreateDIBSection() failed, result %u.\n", GetLastError());
+        memcpy(bits, tests[test_index].test_bits, tests[test_index].test_bits_size);
+
+        bitmap_copy = CopyImage(bitmap, IMAGE_BITMAP, tests[test_index].output_width,
+                tests[test_index].output_height, LR_CREATEDIBSECTION);
+        ok(!!bitmap_copy, "CopyImage() failed, result %u.\n", GetLastError());
+
+        result_bits = HeapAlloc(GetProcessHeap(), 0, tests[test_index].result_bits_size);
+
+        bmi->bmiHeader.biWidth = tests[test_index].output_width;
+        bmi->bmiHeader.biHeight = tests[test_index].output_height;
+        ret = GetDIBits(hdc, bitmap_copy, 0, tests[test_index].output_height,
+                result_bits, bmi, DIB_RGB_COLORS);
+        ok(ret == tests[test_index].output_height, "Unexpected GetDIBits result %d, GetLastError() %u.\n",
+                ret, GetLastError());
+
+        for (row = 0; row < tests[test_index].output_height; ++row)
+            for (column = 0; column < tests[test_index].output_width; ++column)
+            {
+                COLORREF result, expected;
+
+                result = get_color_from_bits(result_bits, bmi, row, column);
+                expected = get_color_from_bits(tests[test_index].expected_bits, bmi, row, column);
+
+                todo_wine_if(tests[test_index].todo)
+                ok(result == expected, "Colors do not match, "
+                        "got 0x%06x, expected 0x%06x, test_index %u, row %u, column %u.\n",
+                        result, expected, test_index, row, column);
+            }
+        DeleteObject(bitmap);
+        DeleteObject(bitmap_copy);
+        HeapFree(GetProcessHeap(), 0, result_bits);
+    }
+    ReleaseDC(0, hdc);
+    HeapFree(GetProcessHeap(), 0, bmi);
+}
+
 START_TEST(cursoricon)
 {
     pGetCursorInfo = (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetCursorInfo" );
@@ -2778,6 +2902,7 @@ START_TEST(cursoricon)
     test_CopyImage_Bitmap(16);
     test_CopyImage_Bitmap(24);
     test_CopyImage_Bitmap(32);
+    test_CopyImage_StretchMode();
     test_initial_cursor();
     test_CreateIcon();
     test_LoadImage();
-- 
2.19.2




More information about the wine-devel mailing list