Alexandre Julliard : gdi32: Always use biClrUsed for the number of colors of internal BITMAPINFO structures .

Alexandre Julliard julliard at winehq.org
Mon Dec 12 12:25:52 CST 2011


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Sat Dec 10 12:48:33 2011 +0100

gdi32: Always use biClrUsed for the number of colors of internal BITMAPINFO structures.

---

 dlls/gdi32/dib.c           |   36 +++++++++++++++++-------------------
 dlls/gdi32/dibdrv/bitblt.c |    3 +--
 dlls/gdi32/dibdrv/dc.c     |   23 +++++++++--------------
 dlls/gdi32/gdi_private.h   |    8 +-------
 4 files changed, 28 insertions(+), 42 deletions(-)

diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c
index b2d18cc..23affb1 100644
--- a/dlls/gdi32/dib.c
+++ b/dlls/gdi32/dib.c
@@ -90,7 +90,8 @@ int bitmap_info_size( const BITMAPINFO * info, WORD coloruse )
     }
     else  /* assume BITMAPINFOHEADER */
     {
-        colors = get_dib_num_of_colors( info );
+        if (info->bmiHeader.biClrUsed) colors = min( info->bmiHeader.biClrUsed, 256 );
+        else colors = info->bmiHeader.biBitCount > 8 ? 0 : 1 << info->bmiHeader.biBitCount;
         if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
         size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
         return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
@@ -225,10 +226,11 @@ static int fill_color_table_from_palette( BITMAPINFO *info, HDC hdc )
 {
     PALETTEENTRY palEntry[256];
     HPALETTE palette = GetCurrentObject( hdc, OBJ_PAL );
-    int i, colors = get_dib_num_of_colors( info );
+    int i, colors = 1 << info->bmiHeader.biBitCount;
+
+    info->bmiHeader.biClrUsed = colors;
 
     if (!palette) return 0;
-    if (!colors) return 0;
 
     memset( palEntry, 0, sizeof(palEntry) );
     if (!GetPaletteEntries( palette, 0, colors, palEntry ))
@@ -1021,24 +1023,21 @@ static int fill_query_info( BITMAPINFO *info, BITMAPOBJ *bmp )
  */
 static void copy_color_info(BITMAPINFO *dst, const BITMAPINFO *src, UINT coloruse)
 {
-    unsigned int colors = get_dib_num_of_colors( src );
-    RGBQUAD *src_colors = (RGBQUAD *)((char *)src + src->bmiHeader.biSize);
-
-    assert( src->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) );
+    assert( src->bmiHeader.biSize == sizeof(BITMAPINFOHEADER) );
 
     if (dst->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
     {
         BITMAPCOREINFO *core = (BITMAPCOREINFO *)dst;
         if (coloruse == DIB_PAL_COLORS)
-            memcpy( core->bmciColors, src_colors, colors * sizeof(WORD) );
+            memcpy( core->bmciColors, src->bmiColors, src->bmiHeader.biClrUsed * sizeof(WORD) );
         else
         {
             unsigned int i;
-            for (i = 0; i < colors; i++)
+            for (i = 0; i < src->bmiHeader.biClrUsed; i++)
             {
-                core->bmciColors[i].rgbtRed   = src_colors[i].rgbRed;
-                core->bmciColors[i].rgbtGreen = src_colors[i].rgbGreen;
-                core->bmciColors[i].rgbtBlue  = src_colors[i].rgbBlue;
+                core->bmciColors[i].rgbtRed   = src->bmiColors[i].rgbRed;
+                core->bmciColors[i].rgbtGreen = src->bmiColors[i].rgbGreen;
+                core->bmciColors[i].rgbtBlue  = src->bmiColors[i].rgbBlue;
             }
         }
     }
@@ -1050,16 +1049,16 @@ static void copy_color_info(BITMAPINFO *dst, const BITMAPINFO *src, UINT colorus
         if (src->bmiHeader.biCompression == BI_BITFIELDS)
             /* bitfields are always at bmiColors even in larger structures */
             memcpy( dst->bmiColors, src->bmiColors, 3 * sizeof(DWORD) );
-        else if (colors)
+        else if (src->bmiHeader.biClrUsed)
         {
             void *colorptr = (char *)dst + dst->bmiHeader.biSize;
             unsigned int size;
 
             if (coloruse == DIB_PAL_COLORS)
-                size = colors * sizeof(WORD);
+                size = src->bmiHeader.biClrUsed * sizeof(WORD);
             else
-                size = colors * sizeof(RGBQUAD);
-            memcpy( colorptr, src_colors, size );
+                size = src->bmiHeader.biClrUsed * sizeof(RGBQUAD);
+            memcpy( colorptr, src->bmiColors, size );
         }
     }
 }
@@ -1358,13 +1357,12 @@ INT WINAPI GetDIBits(
     if (coloruse == DIB_PAL_COLORS)
     {
         WORD *index = (WORD *)dst_info->bmiColors;
-        int colors = get_dib_num_of_colors( dst_info );
-        for (i = 0; i < colors; i++, index++)
+        for (i = 0; i < dst_info->bmiHeader.biClrUsed; i++, index++)
             *index = i;
     }
 
-    dst_info->bmiHeader.biClrUsed = 0;
     copy_color_info( info, dst_info, coloruse );
+    if (info->bmiHeader.biSize != sizeof(BITMAPCOREHEADER)) info->bmiHeader.biClrUsed = 0;
 
 done:
     release_dc_ptr( dc );
diff --git a/dlls/gdi32/dibdrv/bitblt.c b/dlls/gdi32/dibdrv/bitblt.c
index 5bd5234..28e2fac 100644
--- a/dlls/gdi32/dibdrv/bitblt.c
+++ b/dlls/gdi32/dibdrv/bitblt.c
@@ -872,7 +872,6 @@ DWORD dibdrv_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info,
     info->bmiHeader.biCompression   = BI_RGB;
     info->bmiHeader.biXPelsPerMeter = 0;
     info->bmiHeader.biYPelsPerMeter = 0;
-    info->bmiHeader.biClrUsed       = 0;
     info->bmiHeader.biClrImportant  = 0;
 
     if (hbitmap)
@@ -929,7 +928,7 @@ static BOOL matching_color_info( const dib_info *dib, const BITMAPINFO *info )
     {
         RGBQUAD *color_table = (RGBQUAD *)((char *)info + info->bmiHeader.biSize);
         if (!info->bmiHeader.biClrUsed) return FALSE;
-        if (dib->color_table_size != get_dib_num_of_colors( info )) return FALSE;
+        if (dib->color_table_size != info->bmiHeader.biClrUsed) return FALSE;
         return !memcmp( color_table, dib->color_table, dib->color_table_size * sizeof(RGBQUAD) );
     }
 
diff --git a/dlls/gdi32/dibdrv/dc.c b/dlls/gdi32/dibdrv/dc.c
index 44a4075..2f06d62 100644
--- a/dlls/gdi32/dibdrv/dc.c
+++ b/dlls/gdi32/dibdrv/dc.c
@@ -68,7 +68,7 @@ static void init_bit_fields(dib_info *dib, const DWORD *bit_fields)
 }
 
 static BOOL init_dib_info(dib_info *dib, const BITMAPINFOHEADER *bi, const DWORD *bit_fields,
-                          RGBQUAD *color_table, int color_table_size, void *bits, enum dib_info_flags flags)
+                          RGBQUAD *color_table, void *bits, enum dib_info_flags flags)
 {
     dib->bit_count    = bi->biBitCount;
     dib->width        = bi->biWidth;
@@ -141,17 +141,17 @@ static BOOL init_dib_info(dib_info *dib, const BITMAPINFOHEADER *bi, const DWORD
         return FALSE;
     }
 
-    if(color_table)
+    if (color_table && bi->biClrUsed)
     {
         if (flags & private_color_table)
         {
-            dib->color_table = HeapAlloc(GetProcessHeap(), 0, color_table_size * sizeof(dib->color_table[0]));
+            dib->color_table = HeapAlloc(GetProcessHeap(), 0, bi->biClrUsed * sizeof(dib->color_table[0]));
             if(!dib->color_table) return FALSE;
-            memcpy(dib->color_table, color_table, color_table_size * sizeof(color_table[0]));
+            memcpy(dib->color_table, color_table, bi->biClrUsed * sizeof(color_table[0]));
         }
         else
             dib->color_table = color_table;
-        dib->color_table_size = color_table_size;
+        dib->color_table_size = bi->biClrUsed;
     }
     else
     {
@@ -164,9 +164,7 @@ 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)
 {
-    int num_colors = get_dib_num_of_colors( bi );
-
-    if (num_colors && usage == DIB_PAL_COLORS)
+    if (bi->bmiHeader.biClrUsed && usage == DIB_PAL_COLORS)
     {
         char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
         BITMAPINFO *info = (BITMAPINFO *)buffer;
@@ -180,11 +178,8 @@ BOOL init_dib_info_from_brush(dib_info *dib, const BITMAPINFO *bi, void *bits, U
 
 BOOL init_dib_info_from_bitmapinfo(dib_info *dib, const BITMAPINFO *info, void *bits, enum dib_info_flags flags)
 {
-    unsigned int colors = get_dib_num_of_colors( info );
-    void *colorptr = (char *)&info->bmiHeader + info->bmiHeader.biSize;
-    const DWORD *bitfields = (info->bmiHeader.biCompression == BI_BITFIELDS) ? (DWORD *)colorptr : NULL;
-
-    return init_dib_info( dib, &info->bmiHeader, bitfields, colors ? colorptr : NULL, colors, bits, flags );
+    return init_dib_info( dib, &info->bmiHeader, (const DWORD *)info->bmiColors,
+                          (RGBQUAD *)info->bmiColors, bits, flags );
 }
 
 BOOL init_dib_info_from_bitmapobj(dib_info *dib, BITMAPOBJ *bmp, enum dib_info_flags flags)
@@ -206,7 +201,7 @@ BOOL init_dib_info_from_bitmapobj(dib_info *dib, BITMAPOBJ *bmp, enum dib_info_f
                                               flags | private_color_table );
     }
     return init_dib_info( dib, &bmp->dib->dsBmih, bmp->dib->dsBitfields,
-                          bmp->color_table, bmp->dib->dsBmih.biClrUsed, bmp->dib->dsBm.bmBits, flags );
+                          bmp->color_table, bmp->dib->dsBm.bmBits, flags );
 }
 
 static void clear_dib_info(dib_info *dib)
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index 6d47143..8589c4f 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -469,15 +469,9 @@ static inline int get_dib_image_size( const BITMAPINFO *info )
         * abs( info->bmiHeader.biHeight );
 }
 
-static inline int get_dib_num_of_colors( const BITMAPINFO *info )
-{
-    if (info->bmiHeader.biClrUsed) return min( info->bmiHeader.biClrUsed, 256 );
-    return info->bmiHeader.biBitCount > 8 ? 0 : 1 << info->bmiHeader.biBitCount;
-}
-
 static inline void copy_bitmapinfo( BITMAPINFO *dst, const BITMAPINFO *src )
 {
-    unsigned int size = FIELD_OFFSET( BITMAPINFO, bmiColors[get_dib_num_of_colors( src )] );
+    unsigned int size = FIELD_OFFSET( BITMAPINFO, bmiColors[src->bmiHeader.biClrUsed] );
     if (src->bmiHeader.biCompression == BI_BITFIELDS) size += 3 * sizeof(DWORD);
     memcpy( dst, src, size );
 }




More information about the wine-cvs mailing list