Commit f825f5db authored by Alexandre Julliard's avatar Alexandre Julliard

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

parent d0d98046
...@@ -646,13 +646,16 @@ done: ...@@ -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 ...@@ -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 ...@@ -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, ...@@ -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, ...@@ -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;
......
...@@ -240,42 +240,6 @@ void X11DRV_DIB_DestroyXImage( XImage *image ) ...@@ -240,42 +240,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
* *
* Computes the number of colors for the bitmap palette. * Computes the number of colors for the bitmap palette.
...@@ -283,41 +247,11 @@ static int DIB_GetBitmapInfoEx( const BITMAPINFOHEADER *header, LONG *width, ...@@ -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 (core_info)
{
colors = 1 << ((const BITMAPCOREINFO*)info)->bmciHeader.bcBitCount;
}
else
{
colors = info->bmiHeader.biClrUsed;
if (!colors) colors = 1 << info->bmiHeader.biBitCount; 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,15 +266,12 @@ static inline BOOL colour_is_brighter(RGBQUAD c1, RGBQUAD c2) ...@@ -332,15 +266,12 @@ 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; const RGBQUAD * rgb = colorPtr;
if (depth == 1) /* Monochrome */ if (depth == 1) /* Monochrome */
...@@ -363,31 +294,6 @@ static int *X11DRV_DIB_GenColorMap( X11DRV_PDEVICE *physDev, int *colorMapping, ...@@ -363,31 +294,6 @@ static int *X11DRV_DIB_GenColorMap( X11DRV_PDEVICE *physDev, int *colorMapping,
rgb->rgbGreen, rgb->rgbGreen,
rgb->rgbBlue)); rgb->rgbBlue));
} }
else
{
const RGBTRIPLE * rgb = colorPtr;
if (depth == 1) /* Monochrome */
{
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 */
{ {
const WORD * index = colorPtr; const WORD * index = colorPtr;
...@@ -408,7 +314,6 @@ static int *X11DRV_DIB_GenColorMap( X11DRV_PDEVICE *physDev, int *colorMapping, ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment