Commit 8db263d2 authored by Alexandre Julliard's avatar Alexandre Julliard

gdi32: Simplify computation of the DIB header size for internal BITMAPINFO structures.

parent 82e1a461
......@@ -83,7 +83,7 @@ static BOOL store_bitmap_bits( BRUSHOBJ *brush, BITMAPOBJ *bmp )
/* release the unneeded space */
HeapReAlloc( GetProcessHeap(), HEAP_REALLOC_IN_PLACE_ONLY, info,
bitmap_info_size( info, DIB_RGB_COLORS ));
get_dib_info_size( info, DIB_RGB_COLORS ));
brush->info = info;
brush->bits = bits;
brush->usage = DIB_RGB_COLORS;
......@@ -119,7 +119,7 @@ static BOOL copy_bitmap( BRUSHOBJ *brush, HBITMAP bitmap )
}
info = HeapAlloc( GetProcessHeap(), 0,
bitmap_info_size( (BITMAPINFO *)&bmp->dib->dsBmih, DIB_RGB_COLORS ));
get_dib_info_size( (BITMAPINFO *)&bmp->dib->dsBmih, DIB_RGB_COLORS ));
if (!info) goto done;
info->bmiHeader = bmp->dib->dsBmih;
if (info->bmiHeader.biCompression == BI_BITFIELDS)
......@@ -161,7 +161,7 @@ BOOL get_brush_bitmap_info( HBRUSH handle, BITMAPINFO *info, void **bits, UINT *
}
if (brush->info)
{
memcpy( info, brush->info, bitmap_info_size( brush->info, brush->usage ));
memcpy( info, brush->info, get_dib_info_size( brush->info, brush->usage ));
*bits = brush->bits.ptr;
*usage = brush->usage;
ret = TRUE;
......@@ -224,7 +224,7 @@ HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush )
ptr->info = copy_packed_dib( (BITMAPINFO *)ptr->logbrush.lbHatch, ptr->usage );
if (hmem) GlobalUnlock( hmem );
if (!ptr->info) goto error;
ptr->bits.ptr = (char *)ptr->info + bitmap_info_size( ptr->info, ptr->usage );
ptr->bits.ptr = (char *)ptr->info + get_dib_info_size( ptr->info, ptr->usage );
ptr->logbrush.lbStyle = BS_DIBPATTERN;
ptr->logbrush.lbColor = 0;
break;
......
......@@ -168,6 +168,12 @@ static BOOL bitmapinfoheader_from_user_bitmapinfo( BITMAPINFOHEADER *dst, const
/*******************************************************************************************
* Fill out a true BITMAPINFO from a variable sized BITMAPINFO / BITMAPCOREINFO.
*
* The resulting stanitized BITMAPINFO is guaranteed to have:
* - biSize set to sizeof(BITMAPINFOHEADER)
* - biSizeImage set to the actual image size even for non-compressed DIB
* - biClrUsed set to the size of the color table, and 0 only when there is no color table
* - color table present only for <= 8 bpp, always starts at info->bmiColors
*/
static BOOL bitmapinfo_from_user_bitmapinfo( BITMAPINFO *dst, const BITMAPINFO *info,
UINT coloruse, BOOL allow_compression )
......@@ -1122,16 +1128,16 @@ BITMAPINFO *copy_packed_dib( const BITMAPINFO *src_info, UINT usage )
{
char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
BITMAPINFO *ret, *info = (BITMAPINFO *)buffer;
int info_size, image_size;
unsigned int info_size;
if (!bitmapinfo_from_user_bitmapinfo( info, src_info, usage, FALSE )) return NULL;
info_size = bitmap_info_size( info, usage );
image_size = get_dib_image_size( info );
if ((ret = HeapAlloc( GetProcessHeap(), 0, info_size + image_size )))
info_size = get_dib_info_size( info, usage );
if ((ret = HeapAlloc( GetProcessHeap(), 0, info_size + info->bmiHeader.biSizeImage )))
{
memcpy( ret, info, info_size );
memcpy( (char *)ret + info_size, (char *)src_info + bitmap_info_size(src_info,usage), image_size );
memcpy( (char *)ret + info_size, (char *)src_info + bitmap_info_size( src_info, usage ),
info->bmiHeader.biSizeImage );
}
return ret;
}
......
......@@ -178,7 +178,7 @@ INT EMFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT hei
UINT bmi_size, emr_size;
/* calculate the size of the colour table */
bmi_size = bitmap_info_size(info, wUsage);
bmi_size = get_dib_info_size(info, wUsage);
emr_size = sizeof (EMRSTRETCHDIBITS) + bmi_size + info->bmiHeader.biSizeImage;
emr = HeapAlloc(GetProcessHeap(), 0, emr_size );
......@@ -231,7 +231,7 @@ INT EMFDRV_SetDIBitsToDevice( PHYSDEV dev, INT xDst, INT yDst, DWORD width, DWOR
LPCVOID bits, BITMAPINFO *info, UINT wUsage )
{
EMRSETDIBITSTODEVICE* pEMR;
DWORD bmiSize = bitmap_info_size(info, wUsage);
DWORD bmiSize = get_dib_info_size(info, wUsage);
DWORD size = sizeof(EMRSETDIBITSTODEVICE) + bmiSize + info->bmiHeader.biSizeImage;
pEMR = HeapAlloc(GetProcessHeap(), 0, size);
......
......@@ -138,15 +138,15 @@ DWORD EMFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush )
EMRCREATEDIBPATTERNBRUSHPT *emr;
char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
BITMAPINFO *info = (BITMAPINFO *)buffer;
DWORD info_size, image_size;
DWORD info_size;
void *bits;
UINT usage;
if (!get_brush_bitmap_info( hBrush, info, &bits, &usage )) break;
info_size = bitmap_info_size( info, usage );
image_size = get_dib_image_size( info );
info_size = get_dib_info_size( info, usage );
emr = HeapAlloc( GetProcessHeap(), 0, sizeof(EMRCREATEDIBPATTERNBRUSHPT)+info_size+image_size );
emr = HeapAlloc( GetProcessHeap(), 0,
sizeof(EMRCREATEDIBPATTERNBRUSHPT)+info_size+info->bmiHeader.biSizeImage );
if(!emr) break;
if (logbrush.lbStyle == BS_PATTERN && info->bmiHeader.biBitCount == 1)
......@@ -176,7 +176,7 @@ DWORD EMFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush )
emr->ihBrush = index = EMFDRV_AddHandle( dev, hBrush );
emr->iUsage = usage;
emr->offBits = emr->offBmi + emr->cbBmi;
emr->cbBits = image_size;
emr->cbBits = info->bmiHeader.biSizeImage;
memcpy( (BYTE *)emr + emr->offBmi, info, emr->cbBmi );
memcpy( (BYTE *)emr + emr->offBits, bits, emr->cbBits );
......
......@@ -469,11 +469,20 @@ static inline int get_dib_image_size( const BITMAPINFO *info )
* abs( info->bmiHeader.biHeight );
}
/* only for use on sanitized BITMAPINFO structures */
static inline int get_dib_info_size( const BITMAPINFO *info, UINT coloruse )
{
if (info->bmiHeader.biCompression == BI_BITFIELDS)
return sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD);
if (coloruse == DIB_PAL_COLORS)
return sizeof(BITMAPINFOHEADER) + info->bmiHeader.biClrUsed * sizeof(WORD);
return FIELD_OFFSET( BITMAPINFO, bmiColors[info->bmiHeader.biClrUsed] );
}
/* only for use on sanitized BITMAPINFO structures */
static inline void copy_bitmapinfo( BITMAPINFO *dst, const BITMAPINFO *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 );
memcpy( dst, src, get_dib_info_size( src, DIB_RGB_COLORS ));
}
static inline const struct gdi_dc_funcs *get_bitmap_funcs( const BITMAPOBJ *bitmap )
......
......@@ -90,8 +90,7 @@ BOOL MFDRV_StretchBlt( PHYSDEV devDst, struct bitblt_coords *dst,
len,rop,lpBMI->biYPelsPerMeter,GetDeviceCaps(devSrc->hdc, LOGPIXELSY));
if (GetDIBits(devSrc->hdc, hBitmap, 0, (UINT)lpBMI->biHeight,
(LPSTR)lpBMI + bitmap_info_size( (BITMAPINFO *)lpBMI,
DIB_RGB_COLORS ),
(LPSTR)lpBMI + get_dib_info_size( (BITMAPINFO *)lpBMI, DIB_RGB_COLORS ),
(LPBITMAPINFO)lpBMI, DIB_RGB_COLORS))
#else
len = sizeof(METARECORD) + 15 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight;
......@@ -135,7 +134,7 @@ INT MFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst,
INT heightSrc, const void *bits,
BITMAPINFO *info, UINT wUsage, DWORD dwRop )
{
DWORD infosize = bitmap_info_size(info, wUsage);
DWORD infosize = get_dib_info_size(info, wUsage);
DWORD len = sizeof(METARECORD) + 10 * sizeof(WORD) + infosize + info->bmiHeader.biSizeImage;
METARECORD *mr = HeapAlloc( GetProcessHeap(), 0, len );
if(!mr) return 0;
......@@ -169,7 +168,7 @@ INT MFDRV_SetDIBitsToDevice( PHYSDEV dev, INT xDst, INT yDst, DWORD cx,
UINT lines, LPCVOID bits, BITMAPINFO *info, UINT coloruse )
{
DWORD infosize = bitmap_info_size(info, coloruse);
DWORD infosize = get_dib_info_size(info, coloruse);
DWORD len = sizeof(METARECORD) + 8 * sizeof(WORD) + infosize + info->bmiHeader.biSizeImage;
METARECORD *mr = HeapAlloc( GetProcessHeap(), 0, len );
if(!mr) return 0;
......
......@@ -178,16 +178,15 @@ INT16 MFDRV_CreateBrushIndirect(PHYSDEV dev, HBRUSH hBrush )
{
char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
BITMAPINFO *dst_info, *src_info = (BITMAPINFO *)buffer;
DWORD info_size, image_size;
DWORD info_size;
char *dst_ptr;
void *bits;
UINT usage;
if (!get_brush_bitmap_info( hBrush, src_info, &bits, &usage )) goto done;
info_size = bitmap_info_size( src_info, usage );
image_size = get_dib_image_size( src_info );
size = FIELD_OFFSET( METARECORD, rdParm[2] ) + info_size + image_size;
info_size = get_dib_info_size( src_info, usage );
size = FIELD_OFFSET( METARECORD, rdParm[2] ) + info_size + src_info->bmiHeader.biSizeImage;
if (!(mr = HeapAlloc( GetProcessHeap(), 0, size ))) goto done;
mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
......@@ -210,7 +209,7 @@ INT16 MFDRV_CreateBrushIndirect(PHYSDEV dev, HBRUSH hBrush )
for (i = 0; i < dst_info->bmiHeader.biHeight; i++, dst_ptr -= width_bytes)
memcpy( dst_ptr, (char *)bits + i * width_bytes, width_bytes );
}
else memcpy( dst_ptr, bits, image_size );
else memcpy( dst_ptr, bits, src_info->bmiHeader.biSizeImage );
break;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment