Huw Davies : gdi32: Add a helper to sanitize a BITMAPINFO structure.
Alexandre Julliard
julliard at winehq.org
Fri Jul 22 10:16:00 CDT 2011
Module: wine
Branch: master
Commit: 6ce6f890bef2257af50a78e7deee86bdce052189
URL: http://source.winehq.org/git/wine.git/?a=commit;h=6ce6f890bef2257af50a78e7deee86bdce052189
Author: Huw Davies <huw at codeweavers.com>
Date: Fri Jul 22 15:09:58 2011 +0100
gdi32: Add a helper to sanitize a BITMAPINFO structure.
---
dlls/gdi32/dib.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 81 insertions(+), 2 deletions(-)
diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c
index 7e5354b..85a8992 100644
--- a/dlls/gdi32/dib.c
+++ b/dlls/gdi32/dib.c
@@ -136,6 +136,79 @@ int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
return -1;
}
+/*******************************************************************************************
+ * Fill out a true BITMAPINFO from a variable sized BITMAPINFO / BITMAPCOREINFO.
+ */
+static BOOL bitmapinfo_from_user_bitmapinfo( BITMAPINFO *dst, const BITMAPINFO *info, UINT coloruse )
+{
+ LONG width, height;
+ WORD planes, bpp;
+ DWORD compr, size;
+ void *src_colors = (char *)info + info->bmiHeader.biSize;
+ unsigned int colors;
+ int bitmap_type = DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, &planes, &bpp, &compr, &size );
+
+ if (bitmap_type == -1) return FALSE;
+
+ colors = (bpp > 8) ? 0 : 1 << bpp;
+
+ if (bitmap_type == 1)
+ {
+ dst->bmiHeader = info->bmiHeader;
+ dst->bmiHeader.biSize = sizeof(dst->bmiHeader);
+
+ if (info->bmiHeader.biClrUsed) colors = info->bmiHeader.biClrUsed;
+
+ if (info->bmiHeader.biCompression == BI_BITFIELDS)
+ /* bitfields are always at bmiColors even in larger structures */
+ memcpy( dst->bmiColors, info->bmiColors, 3 * sizeof(DWORD) );
+ else if (colors)
+ {
+ unsigned int size;
+
+ if (coloruse == DIB_PAL_COLORS)
+ size = colors * sizeof(WORD);
+ else
+ size = colors * sizeof(RGBQUAD);
+ memcpy( dst->bmiColors, src_colors, size );
+ }
+ }
+ else
+ {
+ dst->bmiHeader.biSize = sizeof(dst->bmiHeader);
+ dst->bmiHeader.biWidth = width;
+ dst->bmiHeader.biHeight = height;
+ dst->bmiHeader.biPlanes = planes;
+ dst->bmiHeader.biBitCount = bpp;
+ dst->bmiHeader.biCompression = compr;
+ dst->bmiHeader.biSizeImage = size;
+ dst->bmiHeader.biXPelsPerMeter = 0;
+ dst->bmiHeader.biYPelsPerMeter = 0;
+ dst->bmiHeader.biClrUsed = 0;
+ dst->bmiHeader.biClrImportant = 0;
+
+ if (colors)
+ {
+ if (coloruse == DIB_PAL_COLORS)
+ memcpy( dst->bmiColors, src_colors, colors * sizeof(WORD) );
+ else
+ {
+ unsigned int i;
+ RGBTRIPLE *triple = (RGBTRIPLE *)src_colors;
+ for (i = 0; i < colors; i++)
+ {
+ dst->bmiColors[i].rgbRed = triple[i].rgbtRed;
+ dst->bmiColors[i].rgbGreen = triple[i].rgbtGreen;
+ dst->bmiColors[i].rgbBlue = triple[i].rgbtBlue;
+ dst->bmiColors[i].rgbReserved = 0;
+ }
+ }
+ }
+ }
+
+ return TRUE;
+}
+
/* nulldrv fallback implementation using SetDIBits/StretchBlt */
INT nulldrv_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT heightDst,
INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, const void *bits,
@@ -256,6 +329,8 @@ INT WINAPI SetDIBits( HDC hdc, HBITMAP hbitmap, UINT startscan,
BOOL delete_hdc = FALSE;
PHYSDEV physdev;
BITMAPOBJ *bitmap;
+ char src_bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
+ BITMAPINFO *src_info = (BITMAPINFO *)src_bmibuf;
INT result = 0;
if (coloruse == DIB_RGB_COLORS && !dc)
@@ -276,10 +351,14 @@ INT WINAPI SetDIBits( HDC hdc, HBITMAP hbitmap, UINT startscan,
return 0;
}
+ if (!bitmapinfo_from_user_bitmapinfo( src_info, info, coloruse )) goto done;
+
physdev = GET_DC_PHYSDEV( dc, pSetDIBits );
- if (BITMAP_SetOwnerDC( hbitmap, physdev ))
- result = physdev->funcs->pSetDIBits( physdev, hbitmap, startscan, lines, bits, info, coloruse );
+ if (!BITMAP_SetOwnerDC( hbitmap, physdev )) goto done;
+ result = physdev->funcs->pSetDIBits( physdev, hbitmap, startscan, lines, bits, src_info, coloruse );
+
+done:
GDI_ReleaseObj( hbitmap );
release_dc_ptr( dc );
if (delete_hdc) DeleteDC(hdc);
More information about the wine-cvs
mailing list