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

This commit is contained in:
Alexandre Julliard 2011-12-10 13:28:08 +01:00
parent 82e1a4616c
commit 8db263d2eb
7 changed files with 41 additions and 28 deletions

View File

@ -83,7 +83,7 @@ static BOOL store_bitmap_bits( BRUSHOBJ *brush, BITMAPOBJ *bmp )
/* release the unneeded space */ /* release the unneeded space */
HeapReAlloc( GetProcessHeap(), HEAP_REALLOC_IN_PLACE_ONLY, info, 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->info = info;
brush->bits = bits; brush->bits = bits;
brush->usage = DIB_RGB_COLORS; brush->usage = DIB_RGB_COLORS;
@ -119,7 +119,7 @@ static BOOL copy_bitmap( BRUSHOBJ *brush, HBITMAP bitmap )
} }
info = HeapAlloc( GetProcessHeap(), 0, 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; if (!info) goto done;
info->bmiHeader = bmp->dib->dsBmih; info->bmiHeader = bmp->dib->dsBmih;
if (info->bmiHeader.biCompression == BI_BITFIELDS) 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) 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; *bits = brush->bits.ptr;
*usage = brush->usage; *usage = brush->usage;
ret = TRUE; ret = TRUE;
@ -224,7 +224,7 @@ HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush )
ptr->info = copy_packed_dib( (BITMAPINFO *)ptr->logbrush.lbHatch, ptr->usage ); ptr->info = copy_packed_dib( (BITMAPINFO *)ptr->logbrush.lbHatch, ptr->usage );
if (hmem) GlobalUnlock( hmem ); if (hmem) GlobalUnlock( hmem );
if (!ptr->info) goto error; 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.lbStyle = BS_DIBPATTERN;
ptr->logbrush.lbColor = 0; ptr->logbrush.lbColor = 0;
break; break;

View File

@ -168,6 +168,12 @@ static BOOL bitmapinfoheader_from_user_bitmapinfo( BITMAPINFOHEADER *dst, const
/******************************************************************************************* /*******************************************************************************************
* Fill out a true BITMAPINFO from a variable sized BITMAPINFO / BITMAPCOREINFO. * 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, static BOOL bitmapinfo_from_user_bitmapinfo( BITMAPINFO *dst, const BITMAPINFO *info,
UINT coloruse, BOOL allow_compression ) 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] )]; char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
BITMAPINFO *ret, *info = (BITMAPINFO *)buffer; 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; if (!bitmapinfo_from_user_bitmapinfo( info, src_info, usage, FALSE )) return NULL;
info_size = bitmap_info_size( info, usage ); info_size = get_dib_info_size( info, usage );
image_size = get_dib_image_size( info ); if ((ret = HeapAlloc( GetProcessHeap(), 0, info_size + info->bmiHeader.biSizeImage )))
if ((ret = HeapAlloc( GetProcessHeap(), 0, info_size + image_size )))
{ {
memcpy( ret, info, info_size ); 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; return ret;
} }

View File

@ -178,7 +178,7 @@ INT EMFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT hei
UINT bmi_size, emr_size; UINT bmi_size, emr_size;
/* calculate the size of the colour table */ /* 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_size = sizeof (EMRSTRETCHDIBITS) + bmi_size + info->bmiHeader.biSizeImage;
emr = HeapAlloc(GetProcessHeap(), 0, emr_size ); 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 ) LPCVOID bits, BITMAPINFO *info, UINT wUsage )
{ {
EMRSETDIBITSTODEVICE* pEMR; 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; DWORD size = sizeof(EMRSETDIBITSTODEVICE) + bmiSize + info->bmiHeader.biSizeImage;
pEMR = HeapAlloc(GetProcessHeap(), 0, size); pEMR = HeapAlloc(GetProcessHeap(), 0, size);

View File

@ -138,15 +138,15 @@ DWORD EMFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush )
EMRCREATEDIBPATTERNBRUSHPT *emr; EMRCREATEDIBPATTERNBRUSHPT *emr;
char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
BITMAPINFO *info = (BITMAPINFO *)buffer; BITMAPINFO *info = (BITMAPINFO *)buffer;
DWORD info_size, image_size; DWORD info_size;
void *bits; void *bits;
UINT usage; UINT usage;
if (!get_brush_bitmap_info( hBrush, info, &bits, &usage )) break; if (!get_brush_bitmap_info( hBrush, info, &bits, &usage )) break;
info_size = bitmap_info_size( info, usage ); info_size = get_dib_info_size( info, usage );
image_size = get_dib_image_size( info );
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(!emr) break;
if (logbrush.lbStyle == BS_PATTERN && info->bmiHeader.biBitCount == 1) 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->ihBrush = index = EMFDRV_AddHandle( dev, hBrush );
emr->iUsage = usage; emr->iUsage = usage;
emr->offBits = emr->offBmi + emr->cbBmi; 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->offBmi, info, emr->cbBmi );
memcpy( (BYTE *)emr + emr->offBits, bits, emr->cbBits ); memcpy( (BYTE *)emr + emr->offBits, bits, emr->cbBits );

View File

@ -469,11 +469,20 @@ static inline int get_dib_image_size( const BITMAPINFO *info )
* abs( info->bmiHeader.biHeight ); * 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 ) static inline void copy_bitmapinfo( BITMAPINFO *dst, const BITMAPINFO *src )
{ {
unsigned int size = FIELD_OFFSET( BITMAPINFO, bmiColors[src->bmiHeader.biClrUsed] ); memcpy( dst, src, get_dib_info_size( src, DIB_RGB_COLORS ));
if (src->bmiHeader.biCompression == BI_BITFIELDS) size += 3 * sizeof(DWORD);
memcpy( dst, src, size );
} }
static inline const struct gdi_dc_funcs *get_bitmap_funcs( const BITMAPOBJ *bitmap ) static inline const struct gdi_dc_funcs *get_bitmap_funcs( const BITMAPOBJ *bitmap )

View File

@ -90,8 +90,7 @@ BOOL MFDRV_StretchBlt( PHYSDEV devDst, struct bitblt_coords *dst,
len,rop,lpBMI->biYPelsPerMeter,GetDeviceCaps(devSrc->hdc, LOGPIXELSY)); len,rop,lpBMI->biYPelsPerMeter,GetDeviceCaps(devSrc->hdc, LOGPIXELSY));
if (GetDIBits(devSrc->hdc, hBitmap, 0, (UINT)lpBMI->biHeight, if (GetDIBits(devSrc->hdc, hBitmap, 0, (UINT)lpBMI->biHeight,
(LPSTR)lpBMI + bitmap_info_size( (BITMAPINFO *)lpBMI, (LPSTR)lpBMI + get_dib_info_size( (BITMAPINFO *)lpBMI, DIB_RGB_COLORS ),
DIB_RGB_COLORS ),
(LPBITMAPINFO)lpBMI, DIB_RGB_COLORS)) (LPBITMAPINFO)lpBMI, DIB_RGB_COLORS))
#else #else
len = sizeof(METARECORD) + 15 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight; 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, INT heightSrc, const void *bits,
BITMAPINFO *info, UINT wUsage, DWORD dwRop ) 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; DWORD len = sizeof(METARECORD) + 10 * sizeof(WORD) + infosize + info->bmiHeader.biSizeImage;
METARECORD *mr = HeapAlloc( GetProcessHeap(), 0, len ); METARECORD *mr = HeapAlloc( GetProcessHeap(), 0, len );
if(!mr) return 0; 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 ) 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; DWORD len = sizeof(METARECORD) + 8 * sizeof(WORD) + infosize + info->bmiHeader.biSizeImage;
METARECORD *mr = HeapAlloc( GetProcessHeap(), 0, len ); METARECORD *mr = HeapAlloc( GetProcessHeap(), 0, len );
if(!mr) return 0; if(!mr) return 0;

View File

@ -178,16 +178,15 @@ INT16 MFDRV_CreateBrushIndirect(PHYSDEV dev, HBRUSH hBrush )
{ {
char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
BITMAPINFO *dst_info, *src_info = (BITMAPINFO *)buffer; BITMAPINFO *dst_info, *src_info = (BITMAPINFO *)buffer;
DWORD info_size, image_size; DWORD info_size;
char *dst_ptr; char *dst_ptr;
void *bits; void *bits;
UINT usage; UINT usage;
if (!get_brush_bitmap_info( hBrush, src_info, &bits, &usage )) goto done; if (!get_brush_bitmap_info( hBrush, src_info, &bits, &usage )) goto done;
info_size = bitmap_info_size( src_info, usage ); info_size = get_dib_info_size( src_info, usage );
image_size = get_dib_image_size( src_info ); size = FIELD_OFFSET( METARECORD, rdParm[2] ) + info_size + src_info->bmiHeader.biSizeImage;
size = FIELD_OFFSET( METARECORD, rdParm[2] ) + info_size + image_size;
if (!(mr = HeapAlloc( GetProcessHeap(), 0, size ))) goto done; if (!(mr = HeapAlloc( GetProcessHeap(), 0, size ))) goto done;
mr->rdFunction = META_DIBCREATEPATTERNBRUSH; 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) for (i = 0; i < dst_info->bmiHeader.biHeight; i++, dst_ptr -= width_bytes)
memcpy( dst_ptr, (char *)bits + i * width_bytes, 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; break;
} }