Alexandre Julliard : gdi32: Fix handling of DIB_PAL_COLORS in the various DIB functions.

Alexandre Julliard julliard at winehq.org
Fri Dec 9 14:41:36 CST 2011


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Dec  9 16:48:28 2011 +0100

gdi32: Fix handling of DIB_PAL_COLORS in the various DIB functions.

---

 dlls/gdi32/dib.c         |   48 ++++++++++++++++++---------------------------
 dlls/gdi32/dibdrv/dc.c   |   18 +++++++---------
 dlls/gdi32/gdi_private.h |    2 +-
 3 files changed, 28 insertions(+), 40 deletions(-)

diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c
index 2cc89fd..4c75fc2 100644
--- a/dlls/gdi32/dib.c
+++ b/dlls/gdi32/dib.c
@@ -245,7 +245,7 @@ static int fill_color_table_from_palette( BITMAPINFO *info, HDC hdc )
     return colors;
 }
 
-int fill_color_table_from_pal_colors( HDC hdc, const BITMAPINFO *info, RGBQUAD *color_table )
+BOOL fill_color_table_from_pal_colors( BITMAPINFO *info, HDC hdc )
 {
     PALETTEENTRY entries[256];
     RGBQUAD table[256];
@@ -253,9 +253,9 @@ int fill_color_table_from_pal_colors( HDC hdc, const BITMAPINFO *info, RGBQUAD *
     const WORD *index = (const WORD *)info->bmiColors;
     int i, count, colors = info->bmiHeader.biClrUsed;
 
-    if (!colors) return 0;
-    if (!(palette = GetCurrentObject( hdc, OBJ_PAL ))) return 0;
-    if (!(count = GetPaletteEntries( palette, 0, colors, entries ))) return 0;
+    if (!colors) return TRUE;
+    if (!(palette = GetCurrentObject( hdc, OBJ_PAL ))) return FALSE;
+    if (!(count = GetPaletteEntries( palette, 0, colors, entries ))) return FALSE;
 
     for (i = 0; i < colors; i++, index++)
     {
@@ -264,9 +264,10 @@ int fill_color_table_from_pal_colors( HDC hdc, const BITMAPINFO *info, RGBQUAD *
         table[i].rgbBlue  = entries[*index % count].peBlue;
         table[i].rgbReserved = 0;
     }
-    memcpy( color_table, table, colors * sizeof(RGBQUAD) );
-    memset( color_table + colors, 0, ((1 << info->bmiHeader.biBitCount) - colors) * sizeof(RGBQUAD) );
-    return colors;
+    info->bmiHeader.biClrUsed = 1 << info->bmiHeader.biBitCount;
+    memcpy( info->bmiColors, table, colors * sizeof(RGBQUAD) );
+    memset( info->bmiColors + colors, 0, (info->bmiHeader.biClrUsed - colors) * sizeof(RGBQUAD) );
+    return TRUE;
 }
 
 static void *get_pixel_ptr( const BITMAPINFO *info, void *bits, int x, int y )
@@ -448,7 +449,7 @@ INT nulldrv_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT he
     src_bits.is_copy = FALSE;
     src_bits.free = NULL;
 
-    if (coloruse == DIB_PAL_COLORS && !fill_color_table_from_palette( src_info, dev->hdc )) return 0;
+    if (coloruse == DIB_PAL_COLORS && !fill_color_table_from_pal_colors( src_info, dev->hdc )) return 0;
 
     rect.left   = xDst;
     rect.top    = yDst;
@@ -656,7 +657,7 @@ INT WINAPI SetDIBits( HDC hdc, HBITMAP hbitmap, UINT startscan,
     src_bits.free = NULL;
     src_bits.param = NULL;
 
-    if (coloruse == DIB_PAL_COLORS && !fill_color_table_from_palette( src_info, hdc )) return 0;
+    if (coloruse == DIB_PAL_COLORS && !fill_color_table_from_pal_colors( src_info, hdc )) return 0;
 
     if (!(bitmap = GDI_GetObjPtr( hbitmap, OBJ_BITMAP ))) return 0;
 
@@ -753,7 +754,7 @@ INT nulldrv_SetDIBitsToDevice( PHYSDEV dev, INT x_dst, INT y_dst, DWORD cx, DWOR
     src_bits.free = NULL;
 
     if (!lines) return 0;
-    if (coloruse == DIB_PAL_COLORS && !fill_color_table_from_palette( src_info, dev->hdc )) return 0;
+    if (coloruse == DIB_PAL_COLORS && !fill_color_table_from_pal_colors( src_info, dev->hdc )) return 0;
 
     if (src_info->bmiHeader.biCompression == BI_RLE4 || src_info->bmiHeader.biCompression == BI_RLE8)
     {
@@ -1463,19 +1464,12 @@ HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
 
     if (info->bmiHeader.biBitCount <= 8)  /* build the color table */
     {
-        unsigned int colors = 1 << info->bmiHeader.biBitCount;
-
-        if (!(color_table = HeapAlloc( GetProcessHeap(), 0, colors * sizeof(RGBQUAD) )))
-        {
-            HeapFree( GetProcessHeap(), 0, dib );
-            return 0;
-        }
-        if (usage == DIB_RGB_COLORS)
-            memcpy( color_table, info->bmiColors, colors * sizeof(RGBQUAD) );
-        else
-            fill_color_table_from_pal_colors( hdc, info, color_table );
-
-        dib->dsBmih.biClrUsed = colors;
+        if (usage == DIB_PAL_COLORS && !fill_color_table_from_pal_colors( info, hdc ))
+            goto error;
+        dib->dsBmih.biClrUsed = info->bmiHeader.biClrUsed;
+        if (!(color_table = HeapAlloc( GetProcessHeap(), 0, dib->dsBmih.biClrUsed * sizeof(RGBQUAD) )))
+            goto error;
+        memcpy( color_table, info->bmiColors, dib->dsBmih.biClrUsed * sizeof(RGBQUAD) );
     }
 
     /* set dsBitfields values */
@@ -1488,6 +1482,7 @@ HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
     }
     else if (info->bmiHeader.biCompression == BI_BITFIELDS)
     {
+        if (usage == DIB_PAL_COLORS) goto error;
         dib->dsBitfields[0] =  *(const DWORD *)info->bmiColors;
         dib->dsBitfields[1] =  *((const DWORD *)info->bmiColors + 1);
         dib->dsBitfields[2] =  *((const DWORD *)info->bmiColors + 2);
@@ -1518,12 +1513,7 @@ HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
     dib->dshSection = section;
     dib->dsOffset = offset;
 
-    if (!dib->dsBm.bmBits)
-    {
-        HeapFree( GetProcessHeap(), 0, color_table );
-        HeapFree( GetProcessHeap(), 0, dib );
-        return 0;
-    }
+    if (!dib->dsBm.bmBits) goto error;
 
     /* If the reference hdc is null, take the desktop dc */
     if (hdc == 0)
diff --git a/dlls/gdi32/dibdrv/dc.c b/dlls/gdi32/dibdrv/dc.c
index 12d1168..384cb5e 100644
--- a/dlls/gdi32/dibdrv/dc.c
+++ b/dlls/gdi32/dibdrv/dc.c
@@ -164,20 +164,18 @@ static BOOL init_dib_info(dib_info *dib, const BITMAPINFOHEADER *bi, const DWORD
 
 BOOL init_dib_info_from_brush(dib_info *dib, const BITMAPINFO *bi, void *bits, UINT usage, HDC hdc)
 {
-    DWORD *masks = (bi->bmiHeader.biCompression == BI_BITFIELDS) ? (DWORD *)bi->bmiColors : NULL;
-    RGBQUAD *color_table = NULL, pal_table[256];
     int num_colors = get_dib_num_of_colors( bi );
 
-    if(num_colors)
+    if (num_colors && usage == DIB_PAL_COLORS)
     {
-        if(usage == DIB_PAL_COLORS)
-        {
-            fill_color_table_from_pal_colors( hdc, bi, pal_table );
-            color_table = pal_table;
-        }
-        else color_table = (RGBQUAD *)bi->bmiColors;
+        char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
+        BITMAPINFO *info = (BITMAPINFO *)buffer;
+
+        copy_bitmapinfo( info, bi );
+        fill_color_table_from_pal_colors( info, hdc );
+        return init_dib_info_from_bitmapinfo( dib, info, bits, private_color_table );
     }
-    return init_dib_info(dib, &bi->bmiHeader, masks, color_table, num_colors, bits, private_color_table);
+    return init_dib_info_from_bitmapinfo(dib, bi, bits, private_color_table );
 }
 
 BOOL init_dib_info_from_bitmapinfo(dib_info *dib, const BITMAPINFO *info, void *bits, enum dib_info_flags flags)
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index 2bed05b..23c8f38 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -235,7 +235,7 @@ extern void DC_UpdateXforms( DC * dc ) DECLSPEC_HIDDEN;
 
 /* dib.c */
 extern int bitmap_info_size( const BITMAPINFO * info, WORD coloruse ) DECLSPEC_HIDDEN;
-extern int fill_color_table_from_pal_colors( HDC hdc, const BITMAPINFO *info, RGBQUAD *color_table ) DECLSPEC_HIDDEN;
+extern BOOL fill_color_table_from_pal_colors( BITMAPINFO *info, HDC hdc ) DECLSPEC_HIDDEN;
 extern void fill_default_color_table( BITMAPINFO *info ) DECLSPEC_HIDDEN;
 extern void get_ddb_bitmapinfo( BITMAPOBJ *bmp, BITMAPINFO *info ) DECLSPEC_HIDDEN;
 extern BITMAPINFO *copy_packed_dib( const BITMAPINFO *src_info, UINT usage ) DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list