gdi32: Create a sanitized BITMAPINFO in StretchDIBits and pass that to the drivers.
This commit is contained in:
parent
7deda05185
commit
d0d98046c6
|
@ -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 )))
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue