gdi32: Create a sanitized BITMAPINFO in SetDIBitsToDevice and pass that to the drivers.
This commit is contained in:
parent
d0d98046c6
commit
f825f5db8c
|
@ -646,13 +646,16 @@ done:
|
||||||
*/
|
*/
|
||||||
INT WINAPI SetDIBitsToDevice(HDC hdc, INT xDest, INT yDest, DWORD cx,
|
INT WINAPI SetDIBitsToDevice(HDC hdc, INT xDest, INT yDest, DWORD cx,
|
||||||
DWORD cy, INT xSrc, INT ySrc, UINT startscan,
|
DWORD cy, INT xSrc, INT ySrc, UINT startscan,
|
||||||
UINT lines, LPCVOID bits, const BITMAPINFO *info,
|
UINT lines, LPCVOID bits, const BITMAPINFO *bmi,
|
||||||
UINT coloruse )
|
UINT coloruse )
|
||||||
{
|
{
|
||||||
|
char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
|
||||||
|
BITMAPINFO *info = (BITMAPINFO *)buffer;
|
||||||
INT ret = 0;
|
INT ret = 0;
|
||||||
DC *dc;
|
DC *dc;
|
||||||
|
|
||||||
if (!bits) 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 )))
|
||||||
{
|
{
|
||||||
|
|
|
@ -232,8 +232,7 @@ INT EMFDRV_SetDIBitsToDevice( PHYSDEV dev, INT xDst, INT yDst, DWORD width, DWOR
|
||||||
{
|
{
|
||||||
EMRSETDIBITSTODEVICE* pEMR;
|
EMRSETDIBITSTODEVICE* pEMR;
|
||||||
DWORD bmiSize = bitmap_info_size(info, wUsage);
|
DWORD bmiSize = bitmap_info_size(info, wUsage);
|
||||||
DWORD bitsSize = get_dib_image_size( info );
|
DWORD size = sizeof(EMRSETDIBITSTODEVICE) + bmiSize + info->bmiHeader.biSizeImage;
|
||||||
DWORD size = sizeof(EMRSETDIBITSTODEVICE) + bmiSize + bitsSize;
|
|
||||||
|
|
||||||
pEMR = HeapAlloc(GetProcessHeap(), 0, size);
|
pEMR = HeapAlloc(GetProcessHeap(), 0, size);
|
||||||
if (!pEMR) return 0;
|
if (!pEMR) return 0;
|
||||||
|
@ -253,12 +252,12 @@ INT EMFDRV_SetDIBitsToDevice( PHYSDEV dev, INT xDst, INT yDst, DWORD width, DWOR
|
||||||
pEMR->offBmiSrc = sizeof(EMRSETDIBITSTODEVICE);
|
pEMR->offBmiSrc = sizeof(EMRSETDIBITSTODEVICE);
|
||||||
pEMR->cbBmiSrc = bmiSize;
|
pEMR->cbBmiSrc = bmiSize;
|
||||||
pEMR->offBitsSrc = sizeof(EMRSETDIBITSTODEVICE) + bmiSize;
|
pEMR->offBitsSrc = sizeof(EMRSETDIBITSTODEVICE) + bmiSize;
|
||||||
pEMR->cbBitsSrc = bitsSize;
|
pEMR->cbBitsSrc = info->bmiHeader.biSizeImage;
|
||||||
pEMR->iUsageSrc = wUsage;
|
pEMR->iUsageSrc = wUsage;
|
||||||
pEMR->iStartScan = startscan;
|
pEMR->iStartScan = startscan;
|
||||||
pEMR->cScans = lines;
|
pEMR->cScans = lines;
|
||||||
memcpy((BYTE*)pEMR + pEMR->offBmiSrc, info, bmiSize);
|
memcpy((BYTE*)pEMR + pEMR->offBmiSrc, info, bmiSize);
|
||||||
memcpy((BYTE*)pEMR + pEMR->offBitsSrc, bits, bitsSize);
|
memcpy((BYTE*)pEMR + pEMR->offBitsSrc, bits, info->bmiHeader.biSizeImage);
|
||||||
|
|
||||||
if (EMFDRV_WriteRecord(dev, (EMR*)pEMR))
|
if (EMFDRV_WriteRecord(dev, (EMR*)pEMR))
|
||||||
EMFDRV_UpdateBBox(dev, &(pEMR->rclBounds));
|
EMFDRV_UpdateBBox(dev, &(pEMR->rclBounds));
|
||||||
|
|
|
@ -171,8 +171,7 @@ INT MFDRV_SetDIBitsToDevice( PHYSDEV dev, INT xDst, INT yDst, DWORD cx,
|
||||||
|
|
||||||
{
|
{
|
||||||
DWORD infosize = bitmap_info_size(info, coloruse);
|
DWORD infosize = bitmap_info_size(info, coloruse);
|
||||||
DWORD imagesize = get_dib_image_size( info );
|
DWORD len = sizeof(METARECORD) + 8 * sizeof(WORD) + infosize + info->bmiHeader.biSizeImage;
|
||||||
DWORD len = sizeof(METARECORD) + 8 * sizeof(WORD) + infosize + imagesize;
|
|
||||||
METARECORD *mr = HeapAlloc( GetProcessHeap(), 0, len );
|
METARECORD *mr = HeapAlloc( GetProcessHeap(), 0, len );
|
||||||
if(!mr) return 0;
|
if(!mr) return 0;
|
||||||
|
|
||||||
|
@ -188,7 +187,7 @@ INT MFDRV_SetDIBitsToDevice( PHYSDEV dev, INT xDst, INT yDst, DWORD cx,
|
||||||
mr->rdParm[7] = (INT16)yDst;
|
mr->rdParm[7] = (INT16)yDst;
|
||||||
mr->rdParm[8] = (INT16)xDst;
|
mr->rdParm[8] = (INT16)xDst;
|
||||||
memcpy(mr->rdParm + 9, info, infosize);
|
memcpy(mr->rdParm + 9, info, infosize);
|
||||||
memcpy(mr->rdParm + 9 + infosize / 2, bits, imagesize);
|
memcpy(mr->rdParm + 9 + 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 lines;
|
return lines;
|
||||||
|
|
|
@ -239,42 +239,6 @@ void X11DRV_DIB_DestroyXImage( XImage *image )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* DIB_GetBitmapInfoEx
|
|
||||||
*
|
|
||||||
* Get the info from a bitmap header.
|
|
||||||
* Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
|
|
||||||
*/
|
|
||||||
static int DIB_GetBitmapInfoEx( const BITMAPINFOHEADER *header, LONG *width,
|
|
||||||
LONG *height, WORD *planes, WORD *bpp,
|
|
||||||
WORD *compr, DWORD *size )
|
|
||||||
{
|
|
||||||
if (header->biSize == sizeof(BITMAPCOREHEADER))
|
|
||||||
{
|
|
||||||
const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)header;
|
|
||||||
*width = core->bcWidth;
|
|
||||||
*height = core->bcHeight;
|
|
||||||
*planes = core->bcPlanes;
|
|
||||||
*bpp = core->bcBitCount;
|
|
||||||
*compr = 0;
|
|
||||||
*size = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (header->biSize >= sizeof(BITMAPINFOHEADER))
|
|
||||||
{
|
|
||||||
*width = header->biWidth;
|
|
||||||
*height = header->biHeight;
|
|
||||||
*planes = header->biPlanes;
|
|
||||||
*bpp = header->biBitCount;
|
|
||||||
*compr = header->biCompression;
|
|
||||||
*size = header->biSizeImage;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
ERR("(%d): unknown/wrong size for header\n", header->biSize );
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* X11DRV_DIB_GetColorCount
|
* X11DRV_DIB_GetColorCount
|
||||||
*
|
*
|
||||||
|
@ -283,41 +247,11 @@ static int DIB_GetBitmapInfoEx( const BITMAPINFOHEADER *header, LONG *width,
|
||||||
*/
|
*/
|
||||||
static unsigned int X11DRV_DIB_GetColorCount(const BITMAPINFO *info)
|
static unsigned int X11DRV_DIB_GetColorCount(const BITMAPINFO *info)
|
||||||
{
|
{
|
||||||
unsigned int colors;
|
unsigned int colors = min( info->bmiHeader.biClrUsed, 256 );
|
||||||
BOOL core_info = info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER);
|
if (!colors) colors = 1 << info->bmiHeader.biBitCount;
|
||||||
|
|
||||||
if (core_info)
|
|
||||||
{
|
|
||||||
colors = 1 << ((const BITMAPCOREINFO*)info)->bmciHeader.bcBitCount;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
colors = info->bmiHeader.biClrUsed;
|
|
||||||
if (!colors) colors = 1 << info->bmiHeader.biBitCount;
|
|
||||||
}
|
|
||||||
if (colors > 256)
|
|
||||||
{
|
|
||||||
ERR("called with >256 colors!\n");
|
|
||||||
colors = 0;
|
|
||||||
}
|
|
||||||
return colors;
|
return colors;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* DIB_GetBitmapInfo
|
|
||||||
*
|
|
||||||
* Get the info from a bitmap header.
|
|
||||||
* Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
|
|
||||||
*/
|
|
||||||
static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
|
|
||||||
LONG *height, WORD *bpp, WORD *compr )
|
|
||||||
{
|
|
||||||
WORD planes;
|
|
||||||
DWORD size;
|
|
||||||
|
|
||||||
return DIB_GetBitmapInfoEx( header, width, height, &planes, bpp, compr, &size);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline BOOL colour_is_brighter(RGBQUAD c1, RGBQUAD c2)
|
static inline BOOL colour_is_brighter(RGBQUAD c1, RGBQUAD c2)
|
||||||
{
|
{
|
||||||
|
@ -332,61 +266,33 @@ static inline BOOL colour_is_brighter(RGBQUAD c1, RGBQUAD c2)
|
||||||
* for a >8-bit deep bitmap.
|
* for a >8-bit deep bitmap.
|
||||||
*/
|
*/
|
||||||
static int *X11DRV_DIB_GenColorMap( X11DRV_PDEVICE *physDev, int *colorMapping,
|
static int *X11DRV_DIB_GenColorMap( X11DRV_PDEVICE *physDev, int *colorMapping,
|
||||||
WORD coloruse, WORD depth, BOOL quads,
|
WORD coloruse, WORD depth, const void *colorPtr, int start, int end )
|
||||||
const void *colorPtr, int start, int end )
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (coloruse == DIB_RGB_COLORS)
|
if (coloruse == DIB_RGB_COLORS)
|
||||||
{
|
{
|
||||||
if (quads)
|
const RGBQUAD * rgb = colorPtr;
|
||||||
|
|
||||||
|
if (depth == 1) /* Monochrome */
|
||||||
{
|
{
|
||||||
const RGBQUAD * rgb = colorPtr;
|
BOOL invert = FALSE;
|
||||||
|
RGBQUAD table[2];
|
||||||
|
|
||||||
if (depth == 1) /* Monochrome */
|
if (GetDIBColorTable( physDev->dev.hdc, 0, 2, table ) == 2)
|
||||||
{
|
invert = !colour_is_brighter(table[1], table[0]);
|
||||||
BOOL invert = FALSE;
|
|
||||||
RGBQUAD table[2];
|
|
||||||
|
|
||||||
if (GetDIBColorTable( physDev->dev.hdc, 0, 2, table ) == 2)
|
for (i = start; i < end; i++, rgb++)
|
||||||
invert = !colour_is_brighter(table[1], table[0]);
|
colorMapping[i] = ((rgb->rgbRed + rgb->rgbGreen +
|
||||||
|
rgb->rgbBlue > 255*3/2 && !invert) ||
|
||||||
for (i = start; i < end; i++, rgb++)
|
(rgb->rgbRed + rgb->rgbGreen +
|
||||||
colorMapping[i] = ((rgb->rgbRed + rgb->rgbGreen +
|
rgb->rgbBlue <= 255*3/2 && invert));
|
||||||
rgb->rgbBlue > 255*3/2 && !invert) ||
|
|
||||||
(rgb->rgbRed + rgb->rgbGreen +
|
|
||||||
rgb->rgbBlue <= 255*3/2 && invert));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
for (i = start; i < end; i++, rgb++)
|
|
||||||
colorMapping[i] = X11DRV_PALETTE_LookupPixel(physDev->color_shifts, RGB(rgb->rgbRed,
|
|
||||||
rgb->rgbGreen,
|
|
||||||
rgb->rgbBlue));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
for (i = start; i < end; i++, rgb++)
|
||||||
const RGBTRIPLE * rgb = colorPtr;
|
colorMapping[i] = X11DRV_PALETTE_LookupPixel(physDev->color_shifts, RGB(rgb->rgbRed,
|
||||||
|
rgb->rgbGreen,
|
||||||
if (depth == 1) /* Monochrome */
|
rgb->rgbBlue));
|
||||||
{
|
|
||||||
BOOL invert = FALSE;
|
|
||||||
RGBQUAD table[2];
|
|
||||||
|
|
||||||
if (GetDIBColorTable( physDev->dev.hdc, 0, 2, table ) == 2)
|
|
||||||
invert = !colour_is_brighter(table[1], table[0]);
|
|
||||||
|
|
||||||
for (i = start; i < end; i++, rgb++)
|
|
||||||
colorMapping[i] = ((rgb->rgbtRed + rgb->rgbtGreen +
|
|
||||||
rgb->rgbtBlue > 255*3/2 && !invert) ||
|
|
||||||
(rgb->rgbtRed + rgb->rgbtGreen +
|
|
||||||
rgb->rgbtBlue <= 255*3/2 && invert));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
for (i = start; i < end; i++, rgb++)
|
|
||||||
colorMapping[i] = X11DRV_PALETTE_LookupPixel(physDev->color_shifts, RGB(rgb->rgbtRed,
|
|
||||||
rgb->rgbtGreen,
|
|
||||||
rgb->rgbtBlue));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else /* DIB_PAL_COLORS */
|
else /* DIB_PAL_COLORS */
|
||||||
{
|
{
|
||||||
|
@ -408,7 +314,6 @@ static int *X11DRV_DIB_GenColorMap( X11DRV_PDEVICE *physDev, int *colorMapping,
|
||||||
static int *X11DRV_DIB_BuildColorMap( X11DRV_PDEVICE *physDev, WORD coloruse, WORD depth,
|
static int *X11DRV_DIB_BuildColorMap( X11DRV_PDEVICE *physDev, WORD coloruse, WORD depth,
|
||||||
const BITMAPINFO *info, int *nColors )
|
const BITMAPINFO *info, int *nColors )
|
||||||
{
|
{
|
||||||
BOOL isInfo;
|
|
||||||
const void *colorPtr;
|
const void *colorPtr;
|
||||||
int *colorMapping;
|
int *colorMapping;
|
||||||
|
|
||||||
|
@ -416,13 +321,12 @@ static int *X11DRV_DIB_BuildColorMap( X11DRV_PDEVICE *physDev, WORD coloruse, WO
|
||||||
*nColors = X11DRV_DIB_GetColorCount(info);
|
*nColors = X11DRV_DIB_GetColorCount(info);
|
||||||
if (!*nColors) return NULL;
|
if (!*nColors) return NULL;
|
||||||
|
|
||||||
isInfo = info->bmiHeader.biSize != sizeof(BITMAPCOREHEADER);
|
|
||||||
colorPtr = (const BYTE*)info + (WORD)info->bmiHeader.biSize;
|
colorPtr = (const BYTE*)info + (WORD)info->bmiHeader.biSize;
|
||||||
if (!(colorMapping = HeapAlloc(GetProcessHeap(), 0, *nColors * sizeof(int) )))
|
if (!(colorMapping = HeapAlloc(GetProcessHeap(), 0, *nColors * sizeof(int) )))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return X11DRV_DIB_GenColorMap( physDev, colorMapping, coloruse, depth,
|
return X11DRV_DIB_GenColorMap( physDev, colorMapping, coloruse, depth,
|
||||||
isInfo, colorPtr, 0, *nColors);
|
colorPtr, 0, *nColors);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -3836,17 +3740,15 @@ INT X11DRV_SetDIBitsToDevice( PHYSDEV dev, INT xDest, INT yDest, DWORD cx, DWORD
|
||||||
X11DRV_PDEVICE *physDev = get_x11drv_dev( dev );
|
X11DRV_PDEVICE *physDev = get_x11drv_dev( dev );
|
||||||
X11DRV_DIB_IMAGEBITS_DESCR descr;
|
X11DRV_DIB_IMAGEBITS_DESCR descr;
|
||||||
INT result;
|
INT result;
|
||||||
LONG width, height;
|
LONG height;
|
||||||
BOOL top_down;
|
BOOL top_down;
|
||||||
POINT pt;
|
POINT pt;
|
||||||
int rop = X11DRV_XROPfunction[GetROP2(dev->hdc) - 1];
|
int rop = X11DRV_XROPfunction[GetROP2(dev->hdc) - 1];
|
||||||
|
|
||||||
if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height,
|
top_down = (info->bmiHeader.biHeight < 0);
|
||||||
&descr.infoBpp, &descr.compression ) == -1)
|
height = abs( info->bmiHeader.biHeight );
|
||||||
return 0;
|
descr.infoBpp = info->bmiHeader.biBitCount;
|
||||||
|
descr.compression = info->bmiHeader.biCompression;
|
||||||
top_down = (height < 0);
|
|
||||||
if (top_down) height = -height;
|
|
||||||
|
|
||||||
pt.x = xDest;
|
pt.x = xDest;
|
||||||
pt.y = yDest;
|
pt.y = yDest;
|
||||||
|
@ -3883,8 +3785,8 @@ INT X11DRV_SetDIBitsToDevice( PHYSDEV dev, INT xDest, INT yDest, DWORD cx, DWORD
|
||||||
ySrc = 0;
|
ySrc = 0;
|
||||||
if (cy > lines) cy = lines;
|
if (cy > lines) cy = lines;
|
||||||
}
|
}
|
||||||
if (xSrc >= width) return lines;
|
if (xSrc >= info->bmiHeader.biWidth) return lines;
|
||||||
if (xSrc + cx >= width) cx = width - xSrc;
|
if (xSrc + cx >= info->bmiHeader.biWidth) cx = info->bmiHeader.biWidth - xSrc;
|
||||||
if (!cx || !cy) return lines;
|
if (!cx || !cy) return lines;
|
||||||
|
|
||||||
/* Update the pixmap from the DIB section */
|
/* Update the pixmap from the DIB section */
|
||||||
|
@ -3928,7 +3830,7 @@ INT X11DRV_SetDIBitsToDevice( PHYSDEV dev, INT xDest, INT yDest, DWORD cx, DWORD
|
||||||
descr.image = NULL;
|
descr.image = NULL;
|
||||||
descr.palentry = NULL;
|
descr.palentry = NULL;
|
||||||
descr.lines = top_down ? -lines : lines;
|
descr.lines = top_down ? -lines : lines;
|
||||||
descr.infoWidth = width;
|
descr.infoWidth = info->bmiHeader.biWidth;
|
||||||
descr.depth = physDev->depth;
|
descr.depth = physDev->depth;
|
||||||
descr.shifts = physDev->color_shifts;
|
descr.shifts = physDev->color_shifts;
|
||||||
descr.drawable = physDev->drawable;
|
descr.drawable = physDev->drawable;
|
||||||
|
@ -3940,7 +3842,7 @@ INT X11DRV_SetDIBitsToDevice( PHYSDEV dev, INT xDest, INT yDest, DWORD cx, DWORD
|
||||||
descr.width = cx;
|
descr.width = cx;
|
||||||
descr.height = cy;
|
descr.height = cy;
|
||||||
descr.shm_mode = X11DRV_SHM_NONE;
|
descr.shm_mode = X11DRV_SHM_NONE;
|
||||||
descr.dibpitch = ((width * descr.infoBpp + 31) &~31) / 8;
|
descr.dibpitch = X11DRV_DIB_GetDIBWidthBytes( info->bmiHeader.biWidth, info->bmiHeader.biBitCount );
|
||||||
descr.physBitmap = NULL;
|
descr.physBitmap = NULL;
|
||||||
|
|
||||||
result = X11DRV_DIB_SetImageBits( &descr );
|
result = X11DRV_DIB_SetImageBits( &descr );
|
||||||
|
@ -4655,8 +4557,7 @@ UINT X11DRV_SetDIBColorTable( PHYSDEV dev, UINT start, UINT count, const RGBQUAD
|
||||||
*/
|
*/
|
||||||
X11DRV_DIB_Lock( physBitmap, DIB_Status_AppMod );
|
X11DRV_DIB_Lock( physBitmap, DIB_Status_AppMod );
|
||||||
X11DRV_DIB_GenColorMap( physDev, physBitmap->colorMap, DIB_RGB_COLORS,
|
X11DRV_DIB_GenColorMap( physDev, physBitmap->colorMap, DIB_RGB_COLORS,
|
||||||
dib.dsBm.bmBitsPixel,
|
dib.dsBm.bmBitsPixel, colors, start, end );
|
||||||
TRUE, colors, start, end );
|
|
||||||
X11DRV_DIB_Unlock( physBitmap, TRUE );
|
X11DRV_DIB_Unlock( physBitmap, TRUE );
|
||||||
ret = end - start;
|
ret = end - start;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue