gdi32: Create a sanitized BITMAPINFO in StretchDIBits and pass that to the drivers.

This commit is contained in:
Alexandre Julliard 2011-08-04 13:09:34 +02:00
parent 7deda05185
commit d0d98046c6
4 changed files with 21 additions and 59 deletions

View File

@ -389,9 +389,7 @@ INT nulldrv_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT he
{ {
DC *dc = get_nulldrv_dc( dev ); DC *dc = get_nulldrv_dc( dev );
INT ret; INT ret;
LONG width, height; LONG height;
WORD planes, bpp;
DWORD compr, size;
HBITMAP hBitmap; HBITMAP hBitmap;
HDC hdcMem; HDC hdcMem;
@ -399,10 +397,8 @@ INT nulldrv_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT he
if (GET_DC_PHYSDEV( dc, pStretchBlt ) == dev || GET_DC_PHYSDEV( dc, pPutImage ) == dev) if (GET_DC_PHYSDEV( dc, pStretchBlt ) == dev || GET_DC_PHYSDEV( dc, pPutImage ) == dev)
return 0; return 0;
if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, &planes, &bpp, &compr, &size ) == -1) if (info->bmiHeader.biWidth < 0) return 0;
return 0; height = info->bmiHeader.biHeight;
if (width < 0) return 0;
if (xSrc == 0 && ySrc == 0 && widthDst == widthSrc && heightDst == heightSrc && if (xSrc == 0 && ySrc == 0 && widthDst == widthSrc && heightDst == heightSrc &&
info->bmiHeader.biCompression == BI_RGB) info->bmiHeader.biCompression == BI_RGB)
@ -417,7 +413,7 @@ INT nulldrv_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT he
hBitmap = GetCurrentObject( dev->hdc, OBJ_BITMAP ); hBitmap = GetCurrentObject( dev->hdc, OBJ_BITMAP );
if (GetObjectW( hBitmap, sizeof(bm), &bm ) && if (GetObjectW( hBitmap, sizeof(bm), &bm ) &&
bm.bmWidth == widthSrc && bm.bmHeight == heightSrc && bm.bmWidth == widthSrc && bm.bmHeight == heightSrc &&
bm.bmBitsPixel == bpp && bm.bmPlanes == planes) bm.bmBitsPixel == info->bmiHeader.biBitCount && bm.bmPlanes == 1)
{ {
/* fast path */ /* fast path */
return SetDIBits( dev->hdc, hBitmap, 0, abs( height ), bits, info, coloruse ); return SetDIBits( dev->hdc, hBitmap, 0, abs( height ), bits, info, coloruse );
@ -426,7 +422,7 @@ INT nulldrv_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT he
} }
hdcMem = CreateCompatibleDC( dev->hdc ); hdcMem = CreateCompatibleDC( dev->hdc );
hBitmap = CreateCompatibleBitmap( dev->hdc, width, height ); hBitmap = CreateCompatibleBitmap( dev->hdc, info->bmiHeader.biWidth, height );
SelectObject( hdcMem, hBitmap ); SelectObject( hdcMem, hBitmap );
if (coloruse == DIB_PAL_COLORS) if (coloruse == DIB_PAL_COLORS)
SelectPalette( hdcMem, GetCurrentObject( dev->hdc, OBJ_PAL ), FALSE ); SelectPalette( hdcMem, GetCurrentObject( dev->hdc, OBJ_PAL ), FALSE );
@ -457,12 +453,15 @@ INT nulldrv_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT he
*/ */
INT WINAPI StretchDIBits(HDC hdc, INT xDst, INT yDst, INT widthDst, INT heightDst, INT WINAPI StretchDIBits(HDC hdc, INT xDst, INT yDst, INT widthDst, INT heightDst,
INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, const void *bits, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, const void *bits,
const BITMAPINFO *info, UINT coloruse, DWORD rop ) const BITMAPINFO *bmi, UINT coloruse, DWORD rop )
{ {
char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
BITMAPINFO *info = (BITMAPINFO *)buffer;
DC *dc; DC *dc;
INT ret = 0; INT ret = 0;
if (!bits || !info) return 0; if (!bits) return 0;
if (!bitmapinfo_from_user_bitmapinfo( info, bmi, coloruse )) return 0;
if ((dc = get_dc_ptr( hdc ))) if ((dc = get_dc_ptr( hdc )))
{ {

View File

@ -175,13 +175,12 @@ INT EMFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT hei
{ {
EMRSTRETCHDIBITS *emr; EMRSTRETCHDIBITS *emr;
BOOL ret; BOOL ret;
UINT bmi_size=0, emr_size; UINT bmi_size, emr_size;
UINT bits_size = get_dib_image_size(info);
/* calculate the size of the colour table */ /* calculate the size of the colour table */
bmi_size = bitmap_info_size(info, wUsage); bmi_size = bitmap_info_size(info, wUsage);
emr_size = sizeof (EMRSTRETCHDIBITS) + bmi_size + bits_size; emr_size = sizeof (EMRSTRETCHDIBITS) + bmi_size + info->bmiHeader.biSizeImage;
emr = HeapAlloc(GetProcessHeap(), 0, emr_size ); emr = HeapAlloc(GetProcessHeap(), 0, emr_size );
if (!emr) return 0; if (!emr) return 0;
@ -189,7 +188,7 @@ INT EMFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT hei
memcpy( &emr[1], info, bmi_size); memcpy( &emr[1], info, bmi_size);
/* write bitmap bits to the record */ /* write bitmap bits to the record */
memcpy ( ( (BYTE *) (&emr[1]) ) + bmi_size, bits, bits_size); memcpy ( ( (BYTE *) (&emr[1]) ) + bmi_size, bits, info->bmiHeader.biSizeImage);
/* fill in the EMR header at the front of our piece of memory */ /* fill in the EMR header at the front of our piece of memory */
emr->emr.iType = EMR_STRETCHDIBITS; emr->emr.iType = EMR_STRETCHDIBITS;
@ -207,7 +206,7 @@ INT EMFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT hei
emr->offBmiSrc = sizeof (EMRSTRETCHDIBITS); emr->offBmiSrc = sizeof (EMRSTRETCHDIBITS);
emr->cbBmiSrc = bmi_size; emr->cbBmiSrc = bmi_size;
emr->offBitsSrc = emr->offBmiSrc + bmi_size; emr->offBitsSrc = emr->offBmiSrc + bmi_size;
emr->cbBitsSrc = bits_size; emr->cbBitsSrc = info->bmiHeader.biSizeImage;
emr->cxSrc = widthSrc; emr->cxSrc = widthSrc;
emr->cySrc = heightSrc; emr->cySrc = heightSrc;

View File

@ -136,8 +136,7 @@ INT MFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst,
const BITMAPINFO *info, UINT wUsage, DWORD dwRop ) const BITMAPINFO *info, UINT wUsage, DWORD dwRop )
{ {
DWORD infosize = bitmap_info_size(info, wUsage); DWORD infosize = bitmap_info_size(info, wUsage);
DWORD imagesize = get_dib_image_size( info ); DWORD len = sizeof(METARECORD) + 10 * sizeof(WORD) + infosize + info->bmiHeader.biSizeImage;
DWORD len = sizeof(METARECORD) + 10 * sizeof(WORD) + infosize + imagesize;
METARECORD *mr = HeapAlloc( GetProcessHeap(), 0, len ); METARECORD *mr = HeapAlloc( GetProcessHeap(), 0, len );
if(!mr) return 0; if(!mr) return 0;
@ -155,7 +154,7 @@ INT MFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst,
mr->rdParm[9] = (INT16)yDst; mr->rdParm[9] = (INT16)yDst;
mr->rdParm[10] = (INT16)xDst; mr->rdParm[10] = (INT16)xDst;
memcpy(mr->rdParm + 11, info, infosize); memcpy(mr->rdParm + 11, info, infosize);
memcpy(mr->rdParm + 11 + infosize / 2, bits, imagesize); memcpy(mr->rdParm + 11 + infosize / 2, bits, info->bmiHeader.biSizeImage);
MFDRV_WriteRecord( dev, mr, mr->rdSize * 2 ); MFDRV_WriteRecord( dev, mr, mr->rdSize * 2 );
HeapFree( GetProcessHeap(), 0, mr ); HeapFree( GetProcessHeap(), 0, mr );
return heightSrc; return heightSrc;

View File

@ -49,37 +49,6 @@ static inline int get_dib_width_bytes( int width, int depth )
return 4 * words; return 4 * words;
} }
/* get the bitmap info from either an INFOHEADER or COREHEADER bitmap */
static BOOL get_bitmap_info( const void *ptr, LONG *width, LONG *height, WORD *bpp, WORD *compr )
{
const BITMAPINFOHEADER *header = ptr;
switch(header->biSize)
{
case sizeof(BITMAPCOREHEADER):
{
const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)header;
*width = core->bcWidth;
*height = core->bcHeight;
*bpp = core->bcBitCount;
*compr = 0;
}
return TRUE;
case sizeof(BITMAPINFOHEADER):
case sizeof(BITMAPV4HEADER):
case sizeof(BITMAPV5HEADER):
/* V4 and V5 structures are a superset of the INFOHEADER structure */
*width = header->biWidth;
*height = header->biHeight;
*bpp = header->biBitCount;
*compr = header->biCompression;
return TRUE;
default:
ERR("(%d): unknown/wrong size for header\n", header->biSize );
return FALSE;
}
}
/*************************************************************************** /***************************************************************************
* PSDRV_WriteImageHeader * PSDRV_WriteImageHeader
@ -336,9 +305,7 @@ INT PSDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst,
INT heightDst, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, const void *bits, INT heightDst, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, const void *bits,
const BITMAPINFO *info, UINT wUsage, DWORD dwRop ) const BITMAPINFO *info, UINT wUsage, DWORD dwRop )
{ {
LONG fullSrcWidth, fullSrcHeight;
INT stride; INT stride;
WORD bpp, compression;
INT line; INT line;
POINT pt[2]; POINT pt[2];
const BYTE *src_ptr; const BYTE *src_ptr;
@ -348,15 +315,13 @@ INT PSDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst,
TRACE("%p (%d,%d %dx%d) -> (%d,%d %dx%d)\n", dev->hdc, TRACE("%p (%d,%d %dx%d) -> (%d,%d %dx%d)\n", dev->hdc,
xSrc, ySrc, widthSrc, heightSrc, xDst, yDst, widthDst, heightDst); xSrc, ySrc, widthSrc, heightSrc, xDst, yDst, widthDst, heightDst);
if (!get_bitmap_info( info, &fullSrcWidth, &fullSrcHeight, &bpp, &compression )) return FALSE; stride = get_dib_width_bytes( info->bmiHeader.biWidth, info->bmiHeader.biBitCount );
stride = get_dib_width_bytes(fullSrcWidth, bpp); TRACE("full size=%dx%d bpp=%d compression=%d rop=%08x\n", info->bmiHeader.biWidth,
info->bmiHeader.biHeight, info->bmiHeader.biBitCount, info->bmiHeader.biCompression, dwRop);
TRACE("full size=%dx%d bpp=%d compression=%d rop=%08x\n", fullSrcWidth,
fullSrcHeight, bpp, compression, dwRop);
if(compression != BI_RGB) { if(info->bmiHeader.biCompression != BI_RGB) {
FIXME("Compression not supported\n"); FIXME("Compression not supported\n");
return FALSE; return FALSE;
} }
@ -371,7 +336,7 @@ INT PSDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst,
widthDst = pt[1].x - pt[0].x; widthDst = pt[1].x - pt[0].x;
heightDst = pt[1].y - pt[0].y; heightDst = pt[1].y - pt[0].y;
switch(bpp) { switch (info->bmiHeader.biBitCount) {
case 1: case 1:
src_ptr = bits; src_ptr = bits;