Alexandre Julliard : gdi32: Only 16 and 32 bpp DIB sections can have bitfields.

Alexandre Julliard julliard at winehq.org
Thu May 27 10:46:39 CDT 2010


Module: wine
Branch: master
Commit: 7f19bda6ec10036f6202d7eeb64c3691082af847
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=7f19bda6ec10036f6202d7eeb64c3691082af847

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu May 27 13:38:30 2010 +0200

gdi32: Only 16 and 32 bpp DIB sections can have bitfields.

---

 dlls/gdi32/dib.c          |   42 ++++++++++++++++++++++++---------
 dlls/gdi32/tests/bitmap.c |   55 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 85 insertions(+), 12 deletions(-)

diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c
index 2725247..ce5ab8b 100644
--- a/dlls/gdi32/dib.c
+++ b/dlls/gdi32/dib.c
@@ -647,18 +647,24 @@ INT WINAPI GetDIBits(
                 DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
                                       bmp->bitmap.bmHeight,
                                       bmp->bitmap.bmBitsPixel );
-            info->bmiHeader.biCompression = (bmp->bitmap.bmBitsPixel > 8) ? BI_BITFIELDS : BI_RGB;
-            switch(bmp->bitmap.bmBitsPixel)
+            if (bmp->dib)
             {
-            case 15:
-                info->bmiHeader.biBitCount = 16;
-                break;
-            case 24:
-                info->bmiHeader.biBitCount = 32;
-                break;
-            default:
+                info->bmiHeader.biBitCount = bmp->dib->dsBm.bmBitsPixel;
+                switch (bmp->dib->dsBm.bmBitsPixel)
+                {
+                case 16:
+                case 32:
+                    info->bmiHeader.biCompression = BI_BITFIELDS;
+                    break;
+                default:
+                    info->bmiHeader.biCompression = BI_RGB;
+                    break;
+                }
+            }
+            else
+            {
+                info->bmiHeader.biCompression = (bmp->bitmap.bmBitsPixel > 8) ? BI_BITFIELDS : BI_RGB;
                 info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
-                break;
             }
             info->bmiHeader.biXPelsPerMeter = 0;
             info->bmiHeader.biYPelsPerMeter = 0;
@@ -1244,10 +1250,22 @@ HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
                                            &planes, &bpp, &compression, &sizeImage )) == -1))
         return 0;
 
-    if (compression != BI_RGB && compression != BI_BITFIELDS)
+    switch (bpp)
     {
-        TRACE("can't create a compressed (%u) dibsection\n", compression);
+    case 16:
+    case 32:
+        if (compression == BI_BITFIELDS) break;
+        /* fall through */
+    case 1:
+    case 4:
+    case 8:
+    case 24:
+        if (compression == BI_RGB) break;
+        WARN( "invalid %u bpp compression %u\n", bpp, compression );
         return 0;
+    default:
+        FIXME( "should fail %u bpp compression %u\n", bpp, compression );
+        break;
     }
 
     if (!(dib = HeapAlloc( GetProcessHeap(), 0, sizeof(*dib) ))) return 0;
diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c
index b25cfd4..8e5ad2e 100644
--- a/dlls/gdi32/tests/bitmap.c
+++ b/dlls/gdi32/tests/bitmap.c
@@ -546,6 +546,18 @@ static void test_dibsections(void)
     ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
     ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
 
+    for (i = 0; i < 128; i++)
+    {
+        pbmi->bmiHeader.biBitCount = i;
+        pbmi->bmiHeader.biCompression = BI_RGB;
+        hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
+        if (i == 1 || i == 4 || i == 8 || i == 16 || i == 24 || i == 32)
+            ok(hdib != NULL, "CreateDIBSection bpp %u\n", i);
+        else
+            todo_wine ok(hdib == NULL, "CreateDIBSection bpp %u succeeded\n", i);
+        if (hdib) DeleteObject( hdib );
+    }
+
     pbmi->bmiHeader.biBitCount = 16;
     pbmi->bmiHeader.biCompression = BI_BITFIELDS;
     ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
@@ -1978,6 +1990,49 @@ static void test_GetDIBits_BI_BITFIELDS(void)
         DeleteObject(hbm);
     }
 
+    /* 24-bpp DIB sections don't have bitfields */
+
+    dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+    dibinfo->bmiHeader.biWidth = 1;
+    dibinfo->bmiHeader.biHeight = 1;
+    dibinfo->bmiHeader.biPlanes = 1;
+    dibinfo->bmiHeader.biBitCount = 24;
+    dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
+    dibinfo->bmiHeader.biSizeImage = 0;
+    dibinfo->bmiHeader.biXPelsPerMeter = 0;
+    dibinfo->bmiHeader.biYPelsPerMeter = 0;
+    dibinfo->bmiHeader.biClrUsed = 0;
+    dibinfo->bmiHeader.biClrImportant = 0;
+    hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
+    ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
+    dibinfo->bmiHeader.biCompression = BI_RGB;
+    hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
+    ok( hbm != 0, "failed to create bitmap\n" );
+
+    memset(dibinfo, 0, sizeof(dibinfo_buf));
+    dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+    ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
+    ok(ret == 1, "GetDIBits failed\n");
+    ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
+
+    ok( dibinfo->bmiHeader.biCompression == BI_RGB,
+        "compression is %u\n", dibinfo->bmiHeader.biCompression );
+    ok( !bitmasks[0], "red mask is set\n" );
+    ok( !bitmasks[1], "green mask is set\n" );
+    ok( !bitmasks[2], "blue mask is set\n" );
+
+    dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
+    ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
+    ok(ret == 1, "GetDIBits failed\n");
+    ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
+    ok( !bitmasks[0], "red mask is set\n" );
+    ok( !bitmasks[1], "green mask is set\n" );
+    ok( !bitmasks[2], "blue mask is set\n" );
+    ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef ||
+        broken(dibinfo->bmiHeader.biSizeImage == 0xdeadbeef), /* win9x */
+        "size image not set\n" );
+
+    DeleteObject(hbm);
     ReleaseDC(NULL, hdc);
 }
 




More information about the wine-cvs mailing list