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

oldstable
Alexandre Julliard 2011-12-09 16:48:28 +01:00
parent 647a4d5844
commit c441ebc21d
3 changed files with 28 additions and 40 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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;