[PATCH] user32: honor bfOffBits in BITMAP_Load

Wolfram Sang wolfram at the-dreams.de
Sun May 9 20:36:27 CDT 2010


Fixes bug #14891 and adds a testcase. (Note: color_match() is just moved to the
front and the comment slightly improved)

Signed-off-by: Wolfram Sang <wolfram at the-dreams.de>
---
 dlls/user32/cursoricon.c       |    5 ++-
 dlls/user32/tests/cursoricon.c |   61 ++++++++++++++++++++++++++++-----------
 2 files changed, 47 insertions(+), 19 deletions(-)

diff --git a/dlls/user32/cursoricon.c b/dlls/user32/cursoricon.c
index 856d900..2634005 100644
--- a/dlls/user32/cursoricon.c
+++ b/dlls/user32/cursoricon.c
@@ -2393,7 +2393,7 @@ static HBITMAP BITMAP_Load( HINSTANCE instance, LPCWSTR name,
     char *bits;
     LONG width, height, new_width, new_height;
     WORD bpp_dummy;
-    DWORD compr_dummy;
+    DWORD compr_dummy, offbits = 0;
     INT bm_type;
     HDC screen_mem_dc = NULL;
 
@@ -2423,6 +2423,7 @@ static HBITMAP BITMAP_Load( HINSTANCE instance, LPCWSTR name,
             UnmapViewOfFile( ptr );
             return 0;
         }
+        offbits = bmfh->bfOffBits - sizeof(BITMAPFILEHEADER);
     }
 
     size = bitmap_info_size(info, DIB_RGB_COLORS);
@@ -2465,7 +2466,7 @@ static HBITMAP BITMAP_Load( HINSTANCE instance, LPCWSTR name,
     if (!screen_dc) screen_dc = CreateDCW( DISPLAYW, NULL, NULL, NULL );
     if (!(screen_mem_dc = CreateCompatibleDC( screen_dc ))) goto end;
 
-    bits = (char *)info + size;
+    bits = (char *)info + (offbits ? offbits : size);
 
     if (loadflags & LR_CREATEDIBSECTION)
     {
diff --git a/dlls/user32/tests/cursoricon.c b/dlls/user32/tests/cursoricon.c
index 21e0dca..e68eaac 100644
--- a/dlls/user32/tests/cursoricon.c
+++ b/dlls/user32/tests/cursoricon.c
@@ -225,6 +225,14 @@ static void test_child_process(void)
     SendMessage(child, WM_USER+1, 0, (LPARAM) cursor);
 }
 
+static BOOL color_match(COLORREF a, COLORREF b)
+{
+    /* 5-bit accuracy is a sufficient test. This will match as long as
+     * colors are never truncated to less that 3x5-bit accuracy i.e.
+     * palettized. */
+    return (a & 0x00F8F8F8) == (b & 0x00F8F8F8);
+}
+
 static void test_CopyImage_Check(HBITMAP bitmap, UINT flags, INT copyWidth, INT copyHeight,
                                   INT expectedWidth, INT expectedHeight, WORD expectedDepth, BOOL dibExpected)
 {
@@ -698,13 +706,14 @@ static const unsigned char pngimage[285] = {
 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
 };
 
-/* 1x1 pixel bmp */
-static const unsigned char bmpimage[66] = {
-0x42,0x4d,0x42,0x00,0x00,0x00,0xDE,0xAD,0xBE,0xEF,0x3e,0x00,0x00,0x00,0x28,0x00,
+/* 1x1 pixel bmp with gap between palette and bitmap. Correct bitmap contains only
+   zeroes, gap is 0xFF. */
+static const unsigned char bmpimage[70] = {
+0x42,0x4d,0x46,0x00,0x00,0x00,0xDE,0xAD,0xBE,0xEF,0x42,0x00,0x00,0x00,0x28,0x00,
 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
-0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
-0x00,0x00
+0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0x55,0x55,0x55,0x00,0xFF,0xFF,
+0xFF,0xFF,0x00,0x00,0x00,0x00
 };
 
 /* 2x2 pixel gif */
@@ -714,6 +723,29 @@ static const unsigned char gif4pixel[42] = {
 0x02,0x00,0x00,0x02,0x03,0x14,0x16,0x05,0x00,0x3b
 };
 
+static void test_LoadImageBitmap(HBITMAP hbm)
+{
+    BITMAP bm;
+    BITMAPINFO bmi;
+    DWORD ret, pixel = 0;
+    HDC hdc = GetDC(NULL);
+
+    ret = GetObject(hbm, sizeof(bm), &bm);
+    ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
+
+    memset(&bmi, 0, sizeof(bmi));
+    bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
+    bmi.bmiHeader.biWidth = bm.bmWidth;
+    bmi.bmiHeader.biHeight = bm.bmHeight;
+    bmi.bmiHeader.biPlanes = 1;
+    bmi.bmiHeader.biBitCount= 24;
+    bmi.bmiHeader.biCompression= BI_RGB;
+    ret = GetDIBits(hdc, hbm, 0, bm.bmHeight, &pixel, &bmi, DIB_RGB_COLORS);
+    ok(ret == bm.bmHeight, "%d lines were converted, not %d\n", ret, bm.bmHeight);
+
+    ok(color_match(pixel, 0x00ffffff), "Pixel is 0x%08x\n", pixel);
+}
+
 static void test_LoadImageFile(const unsigned char * image_data,
     unsigned int image_size, const char * ext, BOOL expect_success)
 {
@@ -758,15 +790,18 @@ static void test_LoadImageFile(const unsigned char * image_data,
     /* Load as bitmap. Should succeed if bmp, fail for everything else */
     SetLastError(0xdeadbeef);
     handle = LoadImageA(NULL, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
-    if (expect_success)
-	ok(handle != NULL, "LoadImage(%s) as IMAGE_BITMAP failed.\n", ext);
-    else ok(handle == NULL, "LoadImage(%s) as IMAGE_BITMAP succeeded incorrectly.\n", ext);
     error = GetLastError();
     ok(error == 0 ||
         error == 0xdeadbeef, /* Win9x, WinMe */
         "Last error: %u\n", error);
-    if (handle != NULL) DeleteObject(handle);
 
+    if (expect_success) {
+        ok(handle != NULL, "LoadImage(%s) as IMAGE_BITMAP failed.\n", ext);
+        if (handle != NULL) test_LoadImageBitmap(handle);
+    }
+    else ok(handle == NULL, "LoadImage(%s) as IMAGE_BITMAP succeeded incorrectly.\n", ext);
+
+    if (handle != NULL) DeleteObject(handle);
     DeleteFileA(filename);
 }
 
@@ -994,14 +1029,6 @@ static HICON create_test_icon(HDC hdc, int width, int height, int bpp,
     return CreateIconIndirect(&iconInfo);
 }
 
-static BOOL color_match(COLORREF a, COLORREF b)
-{
-    /* 5-bit accuracy is a sufficient test. This will match, so long as
-     * colors are never truncated to less that 3x5-bit accuracy i.e.
-     * paletized. */
-    return (a & 0x00F8F8F8) == (b & 0x00F8F8F8);
-}
-
 static void check_alpha_draw(HDC hdc, BOOL drawiconex, BOOL alpha, int bpp, int line)
 {
     HICON hicon;
-- 
1.7.0




More information about the wine-patches mailing list