From 25e2fae2a844075a1a13d4b8bf0b99f677e9e610 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Sat, 10 Dec 2011 12:48:33 +0100 Subject: [PATCH] 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 b2d18cc065a..23affb13340 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 5bd5234a2b1..28e2faccd72 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 44a407565c7..2f06d627d9f 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 6d4714342f4..8589c4ff4c9 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 ); } -- 2.11.4.GIT