[1/2] gdi32/dib: Respect DIB_PAL_COLORS in every case

Michael Karcher wine at mkarcher.dialup.fu-berlin.de
Sat Jun 7 18:44:10 CDT 2008


If the exported bitmap had less colors than the DDB to export from,
the default palette was always stored in RGB format. This is a buffer
overrun as RGB format palettes are twice as big than index palettes.

Testcase tested on patched wine and Windows XP (with 8, 16, 24, 32bpp;
only an already-present failure on 24 bpp has been observed)
---
This is patch one of a three patch series to close bug 6519. The third
one is based on the patch by Eric Pouech, who I am going to talk to
about it first, so only the first two get submitted now.

 dlls/gdi32/dib.c          |   33 +++++++++++++++++----------------
 dlls/gdi32/tests/bitmap.c |   42 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+), 16 deletions(-)

diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c
index ffd6f31..46be0f0 100644
--- a/dlls/gdi32/dib.c
+++ b/dlls/gdi32/dib.c
@@ -701,7 +701,11 @@ INT WINAPI GetDIBits(
             }
         }
         else {
-            if(bpp >= bmp->bitmap.bmBitsPixel) {
+            if (coloruse == DIB_PAL_COLORS) {
+                for (i = 0; i < (1 << bpp); i++)
+                    ((WORD *)colorPtr)[i] = (WORD)i;
+            }
+            else if(bpp >= bmp->bitmap.bmBitsPixel) {
                 /* Generate the color map from the selected palette */
                 PALETTEENTRY palEntry[256];
 
@@ -713,22 +717,19 @@ INT WINAPI GetDIBits(
                     return 0;
                 }
                 for (i = 0; i < (1 << bmp->bitmap.bmBitsPixel); i++) {
-                    if (coloruse == DIB_RGB_COLORS) {
-                        if (core_header)
-                        {
-                            rgbTriples[i].rgbtRed   = palEntry[i].peRed;
-                            rgbTriples[i].rgbtGreen = palEntry[i].peGreen;
-                            rgbTriples[i].rgbtBlue  = palEntry[i].peBlue;
-                        }
-                        else
-                        {
-                            rgbQuads[i].rgbRed      = palEntry[i].peRed;
-                            rgbQuads[i].rgbGreen    = palEntry[i].peGreen;
-                            rgbQuads[i].rgbBlue     = palEntry[i].peBlue;
-                            rgbQuads[i].rgbReserved = 0;
-                        }
+                    if (core_header)
+                    {
+                        rgbTriples[i].rgbtRed   = palEntry[i].peRed;
+                        rgbTriples[i].rgbtGreen = palEntry[i].peGreen;
+                        rgbTriples[i].rgbtBlue  = palEntry[i].peBlue;
+                    }
+                    else
+                    {
+                        rgbQuads[i].rgbRed      = palEntry[i].peRed;
+                        rgbQuads[i].rgbGreen    = palEntry[i].peGreen;
+                        rgbQuads[i].rgbBlue     = palEntry[i].peBlue;
+                        rgbQuads[i].rgbReserved = 0;
                     }
-                    else ((WORD *)colorPtr)[i] = (WORD)i;
                 }
             } else {
                 switch (bpp) {
diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c
index 06b1672..6685ae6 100644
--- a/dlls/gdi32/tests/bitmap.c
+++ b/dlls/gdi32/tests/bitmap.c
@@ -1301,6 +1301,28 @@ static void test_GetDIBits_selected_DDB(BOOL monochrome)
     }
     ok(equalContents, "GetDIBits with DDB selected in DC: Got different DIB bits\n");
 
+    /* Test the palette */
+    equalContents = TRUE;
+    if (info2->bmiHeader.biBitCount <= 8)
+    {
+        WORD *colors = (WORD*)info2->bmiColors;
+
+        /* Get the palette indices */
+        res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
+        ok(res, "GetDIBits failed\n");
+        
+        for (i=0;i < 1 << info->bmiHeader.biSizeImage; i++)
+        {
+            if (colors[i] != i)
+            {
+                equalContents = FALSE;
+                break;
+            }
+        }
+    }
+    
+    ok(equalContents, "GetDIBits with DDB selected in DC: non 1:1 palette indices\n");
+
     HeapFree(GetProcessHeap(), 0, bits2);
     HeapFree(GetProcessHeap(), 0, bits);
     DeleteDC(dc);
@@ -1482,6 +1504,16 @@ todo_wine
 todo_wine
     ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
 
+    /* Test the palette indices */
+    memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
+    SetLastError(0xdeadbeef);
+    lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
+    
+    ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
+    ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
+    for (i = 2; i < 256; i++)
+        ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[1]);
+
     /* retrieve 24-bit DIB data */
     memset(bi, 0, sizeof(*bi));
     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
@@ -1582,6 +1614,16 @@ todo_wine
 todo_wine
     ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
 
+    /* Test the palette indices */
+    memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
+    SetLastError(0xdeadbeef);
+    lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
+    
+    ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
+    ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
+    for (i = 2; i < 256; i++)
+        ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[i]);
+
     /* retrieve 24-bit DIB data */
     memset(bi, 0, sizeof(*bi));
     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
-- 
1.5.5.1




More information about the wine-patches mailing list