diff --git a/dlls/gdi32/brush.c b/dlls/gdi32/brush.c index c86421c3289..dc8eb904740 100644 --- a/dlls/gdi32/brush.c +++ b/dlls/gdi32/brush.c @@ -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; diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c index 23affb13340..a08e2554a7a 100644 --- a/dlls/gdi32/dib.c +++ b/dlls/gdi32/dib.c @@ -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; } diff --git a/dlls/gdi32/enhmfdrv/bitblt.c b/dlls/gdi32/enhmfdrv/bitblt.c index 77c89cb5101..d6d0fe7b333 100644 --- a/dlls/gdi32/enhmfdrv/bitblt.c +++ b/dlls/gdi32/enhmfdrv/bitblt.c @@ -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); diff --git a/dlls/gdi32/enhmfdrv/objects.c b/dlls/gdi32/enhmfdrv/objects.c index 027b6a3aab4..e2e4efb3228 100644 --- a/dlls/gdi32/enhmfdrv/objects.c +++ b/dlls/gdi32/enhmfdrv/objects.c @@ -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 ); diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 8589c4ff4c9..e2dbeff358a 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -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 ) diff --git a/dlls/gdi32/mfdrv/bitblt.c b/dlls/gdi32/mfdrv/bitblt.c index 11954f7c744..fd6c68fc115 100644 --- a/dlls/gdi32/mfdrv/bitblt.c +++ b/dlls/gdi32/mfdrv/bitblt.c @@ -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; diff --git a/dlls/gdi32/mfdrv/objects.c b/dlls/gdi32/mfdrv/objects.c index 3745ec76dd0..1489f4ed6a6 100644 --- a/dlls/gdi32/mfdrv/objects.c +++ b/dlls/gdi32/mfdrv/objects.c @@ -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; }