- Extended support for BITMAPCOREINFO / BITMAPCOREHEADER structures.

- Always calculate the location of the color table.
- CreateCompatibleBitmap: Create a DIB section if necessary.
- Added some tests.
This commit is contained in:
Michael Kaufmann 2004-11-02 05:23:49 +00:00 committed by Alexandre Julliard
parent 7ce764669e
commit 0dd2910eba
4 changed files with 603 additions and 188 deletions

View File

@ -171,32 +171,83 @@ HBITMAP WINAPI CreateCompatibleBitmap( HDC hdc, INT width, INT height)
HBITMAP hbmpRet = 0;
DC *dc;
TRACE("(%p,%d,%d) = \n", hdc, width, height );
if (!(dc = DC_GetDCPtr( hdc ))) return 0;
if ((width >= 0x10000) || (height >= 0x10000)) {
FIXME("got bad width %d or height %d, please look for reason\n",
width, height );
TRACE("(%p,%d,%d) = \n", hdc, width, height);
if ((width >= 0x10000) || (height >= 0x10000))
{
FIXME("got bad width %d or height %d, please look for reason\n",
width, height);
}
else
{
INT planes, bpp;
if (!(dc = DC_GetDCPtr(hdc))) return 0;
if (GDIMAGIC( dc->header.wMagic ) != MEMORY_DC_MAGIC)
{
planes = GetDeviceCaps( hdc, PLANES );
bpp = GetDeviceCaps( hdc, BITSPIXEL );
hbmpRet = CreateBitmap(width, height,
GetDeviceCaps(hdc, PLANES),
GetDeviceCaps(hdc, BITSPIXEL),
NULL);
}
else /* memory DC, get the depth of the bitmap */
else /* Memory DC */
{
BITMAPOBJ *bmp = GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC );
planes = bmp->bitmap.bmPlanes;
bpp = bmp->bitmap.bmBitsPixel;
GDI_ReleaseObj( dc->hBitmap );
if (!bmp->dib)
{
/* A device-dependent bitmap is selected in the DC */
hbmpRet = CreateBitmap(width, height,
bmp->bitmap.bmPlanes,
bmp->bitmap.bmBitsPixel,
NULL);
}
else
{
/* A DIB section is selected in the DC */
BITMAPINFO *bi;
void *bits;
/* Allocate memory for a BITMAPINFOHEADER structure and a
color table. The maximum number of colors in a color table
is 256 which corresponds to a bitmap with depth 8.
Bitmaps with higher depths don't have color tables. */
bi = HeapAlloc(GetProcessHeap(), 0, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
if (bi)
{
bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
bi->bmiHeader.biWidth = width;
bi->bmiHeader.biHeight = height;
bi->bmiHeader.biPlanes = bmp->dib->dsBmih.biPlanes;
bi->bmiHeader.biBitCount = bmp->dib->dsBmih.biBitCount;
bi->bmiHeader.biCompression = bmp->dib->dsBmih.biCompression;
bi->bmiHeader.biSizeImage = 0;
bi->bmiHeader.biXPelsPerMeter = bmp->dib->dsBmih.biXPelsPerMeter;
bi->bmiHeader.biYPelsPerMeter = bmp->dib->dsBmih.biYPelsPerMeter;
bi->bmiHeader.biClrUsed = bmp->dib->dsBmih.biClrUsed;
bi->bmiHeader.biClrImportant = bmp->dib->dsBmih.biClrImportant;
if (bi->bmiHeader.biCompression == BI_BITFIELDS)
{
/* Copy the color masks */
CopyMemory(bi->bmiColors, bmp->dib->dsBitfields, 3 * sizeof(DWORD));
}
else if (bi->bmiHeader.biBitCount <= 8)
{
/* Copy the color table */
GetDIBColorTable(hdc, 0, 256, bi->bmiColors);
}
hbmpRet = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
HeapFree(GetProcessHeap(), 0, bi);
}
}
GDI_ReleaseObj(dc->hBitmap);
}
hbmpRet = CreateBitmap( width, height, planes, bpp, NULL );
GDI_ReleaseObj(hdc);
}
TRACE("\t\t%p\n", hbmpRet);
GDI_ReleaseObj(hdc);
return hbmpRet;
}
@ -618,6 +669,8 @@ BOOL WINAPI GetBitmapDimensionEx(
* SetBitmapDimensionEx [GDI32.@]
*
* Assigns dimensions to a bitmap.
* MSDN says that this function will fail if hbitmap is a handle created by
* CreateDIBSection, but that's not true on Windows 2000.
*
* RETURNS
* Success: TRUE

View File

@ -18,6 +18,44 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
Important information:
* Current Windows versions support two different DIB structures:
- BITMAPCOREINFO / BITMAPCOREHEADER (legacy structures; used in OS/2)
- BITMAPINFO / BITMAPINFOHEADER
Most Windows API functions taking a BITMAPINFO* / BITMAPINFOHEADER* also
accept the old "core" structures, and so must WINE.
You can distinguish them by looking at the first member (bcSize/biSize),
or use the internal function DIB_GetBitmapInfo.
* The palettes are stored in different formats:
- BITMAPCOREINFO: Array of RGBTRIPLE
- BITMAPINFO: Array of RGBQUAD
* There are even more DIB headers, but they all extend BITMAPINFOHEADER:
- BITMAPV4HEADER: Introduced in Windows 95 / NT 4.0
- BITMAPV5HEADER: Introduced in Windows 98 / 2000
* You should never access the color table using the bmiColors member,
because the passed structure may have one of the extended headers
mentioned above. Use this to calculate the location:
BITMAPINFO* info;
void* colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
* More information:
Search for "Bitmap Structures" in MSDN
*/
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
@ -31,6 +69,12 @@
WINE_DEFAULT_DEBUG_CHANNEL(bitmap);
/*
Some of the following helper functions are duplicated in
dlls/x11drv/dib.c
*/
/***********************************************************************
* DIB_GetDIBWidthBytes
*
@ -174,12 +218,27 @@ INT WINAPI StretchDIBits(HDC hdc, INT xDst, INT yDst, INT widthDst,
{
HBITMAP hBitmap, hOldBitmap;
HPALETTE hpal = NULL;
HDC hdcMem;
HDC hdcMem;
LONG height;
LONG width;
WORD bpp;
DWORD compr;
if (DIB_GetBitmapInfo( (BITMAPINFOHEADER*) info, &width, &height, &bpp, &compr ) == -1)
{
ERR("Invalid bitmap\n");
return 0;
}
if (width < 0)
{
ERR("Bitmap has a negative width\n");
return 0;
}
GDI_ReleaseObj( hdc );
hdcMem = CreateCompatibleDC( hdc );
hBitmap = CreateCompatibleBitmap(hdc, info->bmiHeader.biWidth,
info->bmiHeader.biHeight);
hBitmap = CreateCompatibleBitmap(hdc, width, height);
hOldBitmap = SelectObject( hdcMem, hBitmap );
if(wUsage == DIB_PAL_COLORS)
{
@ -206,18 +265,17 @@ INT WINAPI StretchDIBits(HDC hdc, INT xDst, INT yDst, INT widthDst,
*/
/* copy existing bitmap from destination dc */
StretchBlt( hdcMem, xSrc, abs(info->bmiHeader.biHeight) - heightSrc - ySrc,
StretchBlt( hdcMem, xSrc, abs(height) - heightSrc - ySrc,
widthSrc, heightSrc, hdc, xDst, yDst, widthDst, heightDst,
dwRop );
}
SetDIBits(hdcMem, hBitmap, 0, info->bmiHeader.biHeight, bits,
info, wUsage);
SetDIBits(hdcMem, hBitmap, 0, height, bits, info, wUsage);
/* Origin for DIBitmap may be bottom left (positive biHeight) or top
left (negative biHeight) */
StretchBlt( hdc, xDst, yDst, widthDst, heightDst,
hdcMem, xSrc, abs(info->bmiHeader.biHeight) - heightSrc - ySrc,
hdcMem, xSrc, abs(height) - heightSrc - ySrc,
widthSrc, heightSrc, dwRop );
if(hpal)
SelectPalette(hdcMem, hpal, FALSE);
@ -346,8 +404,8 @@ UINT WINAPI GetDIBColorTable( HDC hdc, UINT startpos, UINT entries, RGBQUAD *col
NB. RGBQUAD and PALETTEENTRY have different orderings of red, green
and blue - sigh */
static RGBQUAD EGAColors[16] = {
/* rgbBlue, rgbGreen, rgbRed, rgbReserverd */
static RGBQUAD EGAColorsQuads[16] = {
/* rgbBlue, rgbGreen, rgbRed, rgbReserved */
{ 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x80, 0x00 },
{ 0x00, 0x80, 0x00, 0x00 },
@ -366,9 +424,28 @@ static RGBQUAD EGAColors[16] = {
{ 0xff, 0xff, 0xff, 0x00 }
};
static RGBTRIPLE EGAColorsTriples[16] = {
/* rgbBlue, rgbGreen, rgbRed */
{ 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x80 },
{ 0x00, 0x80, 0x00 },
{ 0x00, 0x80, 0x80 },
{ 0x80, 0x00, 0x00 },
{ 0x80, 0x00, 0x80 },
{ 0x80, 0x80, 0x00 },
{ 0x80, 0x80, 0x80 },
{ 0xc0, 0xc0, 0xc0 },
{ 0x00, 0x00, 0xff },
{ 0x00, 0xff, 0x00 },
{ 0x00, 0xff, 0xff },
{ 0xff, 0x00, 0x00 } ,
{ 0xff, 0x00, 0xff },
{ 0xff, 0xff, 0x00 },
{ 0xff, 0xff, 0xff }
};
static RGBQUAD DefLogPalette[20] = { /* Copy of Default Logical Palette */
/* rgbBlue, rgbGreen, rgbRed, rgbReserverd */
static RGBQUAD DefLogPaletteQuads[20] = { /* Copy of Default Logical Palette */
/* rgbBlue, rgbGreen, rgbRed, rgbReserved */
{ 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x80, 0x00 },
{ 0x00, 0x80, 0x00, 0x00 },
@ -391,6 +468,30 @@ static RGBQUAD DefLogPalette[20] = { /* Copy of Default Logical Palette */
{ 0xff, 0xff, 0xff, 0x00 }
};
static RGBTRIPLE DefLogPaletteTriples[20] = { /* Copy of Default Logical Palette */
/* rgbBlue, rgbGreen, rgbRed */
{ 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x80 },
{ 0x00, 0x80, 0x00 },
{ 0x00, 0x80, 0x80 },
{ 0x80, 0x00, 0x00 },
{ 0x80, 0x00, 0x80 },
{ 0x80, 0x80, 0x00 },
{ 0xc0, 0xc0, 0xc0 },
{ 0xc0, 0xdc, 0xc0 },
{ 0xf0, 0xca, 0xa6 },
{ 0xf0, 0xfb, 0xff },
{ 0xa4, 0xa0, 0xa0 },
{ 0x80, 0x80, 0x80 },
{ 0x00, 0x00, 0xf0 },
{ 0x00, 0xff, 0x00 },
{ 0x00, 0xff, 0xff },
{ 0xff, 0x00, 0x00 },
{ 0xff, 0x00, 0xff },
{ 0xff, 0xff, 0x00 },
{ 0xff, 0xff, 0xff}
};
/******************************************************************************
* GetDIBits [GDI32.@]
@ -416,8 +517,25 @@ INT WINAPI GetDIBits(
BITMAPOBJ * bmp;
int i;
HDC memdc;
int bitmap_type;
BOOL core_header;
LONG width;
LONG height;
WORD bpp;
DWORD compr;
void* colorPtr;
RGBTRIPLE* rgbTriples;
RGBQUAD* rgbQuads;
if (!info) return 0;
bitmap_type = DIB_GetBitmapInfo( (BITMAPINFOHEADER*) info, &width, &height, &bpp, &compr);
if (bitmap_type == -1)
{
ERR("Invalid bitmap format\n");
return 0;
}
core_header = (bitmap_type == 0);
memdc = CreateCompatibleDC(hdc);
if (!(dc = DC_GetDCUpdate( hdc )))
{
@ -431,30 +549,57 @@ INT WINAPI GetDIBits(
return 0;
}
colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
rgbTriples = (RGBTRIPLE *) colorPtr;
rgbQuads = (RGBQUAD *) colorPtr;
/* Transfer color info */
if (info->bmiHeader.biBitCount <= 8 && info->bmiHeader.biBitCount > 0 ) {
info->bmiHeader.biClrUsed = 0;
if (bpp <= 8 && bpp > 0)
{
if (!core_header) info->bmiHeader.biClrUsed = 0;
/* If the bitmap object already has a dib section at the
same color depth then get the color map from it */
if (bmp->dib && bmp->dib->dsBm.bmBitsPixel == info->bmiHeader.biBitCount) {
if (bmp->dib && bmp->dib->dsBm.bmBitsPixel == bpp) {
if(coloruse == DIB_RGB_COLORS) {
HBITMAP oldbm;
oldbm = SelectObject(memdc, hbitmap);
GetDIBColorTable(memdc, 0, 1 << info->bmiHeader.biBitCount, info->bmiColors);
HBITMAP oldbm = SelectObject(memdc, hbitmap);
unsigned int colors = 1 << bpp;
if (core_header)
{
/* Convert the color table (RGBQUAD to RGBTRIPLE) */
RGBQUAD* buffer = HeapAlloc(GetProcessHeap(), 0, colors * sizeof(RGBQUAD));
if (buffer)
{
RGBTRIPLE* index = rgbTriples;
GetDIBColorTable(memdc, 0, colors, buffer);
for (i=0; i < colors; i++, index++)
{
index->rgbtRed = buffer[i].rgbRed;
index->rgbtGreen = buffer[i].rgbGreen;
index->rgbtBlue = buffer[i].rgbBlue;
}
HeapFree(GetProcessHeap(), 0, buffer);
}
}
else
{
GetDIBColorTable(memdc, 0, colors, colorPtr);
}
SelectObject(memdc, oldbm);
}
else {
WORD *index = (WORD*)info->bmiColors;
int i;
WORD *index = colorPtr;
for(i = 0; i < 1 << info->bmiHeader.biBitCount; i++, index++)
*index = i;
}
}
}
else {
if(info->bmiHeader.biBitCount >= bmp->bitmap.bmBitsPixel) {
if(bpp >= bmp->bitmap.bmBitsPixel) {
/* Generate the color map from the selected palette */
PALETTEENTRY * palEntry;
PALETTEOBJ * palette;
@ -467,48 +612,93 @@ INT WINAPI GetDIBits(
palEntry = palette->logpalette.palPalEntry;
for (i = 0; i < (1 << bmp->bitmap.bmBitsPixel); i++, palEntry++) {
if (coloruse == DIB_RGB_COLORS) {
info->bmiColors[i].rgbRed = palEntry->peRed;
info->bmiColors[i].rgbGreen = palEntry->peGreen;
info->bmiColors[i].rgbBlue = palEntry->peBlue;
info->bmiColors[i].rgbReserved = 0;
if (core_header)
{
rgbTriples[i].rgbtRed = palEntry->peRed;
rgbTriples[i].rgbtGreen = palEntry->peGreen;
rgbTriples[i].rgbtBlue = palEntry->peBlue;
}
else
{
rgbQuads[i].rgbRed = palEntry->peRed;
rgbQuads[i].rgbGreen = palEntry->peGreen;
rgbQuads[i].rgbBlue = palEntry->peBlue;
rgbQuads[i].rgbReserved = 0;
}
}
else ((WORD *)info->bmiColors)[i] = (WORD)i;
else ((WORD *)colorPtr)[i] = (WORD)i;
}
GDI_ReleaseObj( dc->hPalette );
} else {
switch (info->bmiHeader.biBitCount) {
switch (bpp) {
case 1:
info->bmiColors[0].rgbRed = info->bmiColors[0].rgbGreen =
info->bmiColors[0].rgbBlue = 0;
info->bmiColors[0].rgbReserved = 0;
info->bmiColors[1].rgbRed = info->bmiColors[1].rgbGreen =
info->bmiColors[1].rgbBlue = 0xff;
info->bmiColors[1].rgbReserved = 0;
if (core_header)
{
rgbTriples[0].rgbtRed = rgbTriples[0].rgbtGreen =
rgbTriples[0].rgbtBlue = 0;
rgbTriples[1].rgbtRed = rgbTriples[1].rgbtGreen =
rgbTriples[1].rgbtBlue = 0xff;
}
else
{
rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen =
rgbQuads[0].rgbBlue = 0;
rgbQuads[0].rgbReserved = 0;
rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen =
rgbQuads[1].rgbBlue = 0xff;
rgbQuads[1].rgbReserved = 0;
}
break;
case 4:
memcpy(info->bmiColors, EGAColors, sizeof(EGAColors));
if (core_header)
memcpy(colorPtr, EGAColorsTriples, sizeof(EGAColorsTriples));
else
memcpy(colorPtr, EGAColorsQuads, sizeof(EGAColorsQuads));
break;
case 8:
{
INT r, g, b;
RGBQUAD *color;
if (core_header)
{
INT r, g, b;
RGBTRIPLE *color;
memcpy(info->bmiColors, DefLogPalette,
10 * sizeof(RGBQUAD));
memcpy(info->bmiColors + 246, DefLogPalette + 10,
10 * sizeof(RGBQUAD));
color = info->bmiColors + 10;
for(r = 0; r <= 5; r++) /* FIXME */
for(g = 0; g <= 5; g++)
for(b = 0; b <= 5; b++) {
color->rgbRed = (r * 0xff) / 5;
color->rgbGreen = (g * 0xff) / 5;
color->rgbBlue = (b * 0xff) / 5;
color->rgbReserved = 0;
color++;
}
memcpy(rgbTriples, DefLogPaletteTriples,
10 * sizeof(RGBTRIPLE));
memcpy(rgbTriples + 246, DefLogPaletteTriples + 10,
10 * sizeof(RGBTRIPLE));
color = rgbTriples + 10;
for(r = 0; r <= 5; r++) /* FIXME */
for(g = 0; g <= 5; g++)
for(b = 0; b <= 5; b++) {
color->rgbtRed = (r * 0xff) / 5;
color->rgbtGreen = (g * 0xff) / 5;
color->rgbtBlue = (b * 0xff) / 5;
color++;
}
}
else
{
INT r, g, b;
RGBQUAD *color;
memcpy(rgbQuads, DefLogPaletteQuads,
10 * sizeof(RGBQUAD));
memcpy(rgbQuads + 246, DefLogPaletteQuads + 10,
10 * sizeof(RGBQUAD));
color = rgbQuads + 10;
for(r = 0; r <= 5; r++) /* FIXME */
for(g = 0; g <= 5; g++)
for(b = 0; b <= 5; b++) {
color->rgbRed = (r * 0xff) / 5;
color->rgbGreen = (g * 0xff) / 5;
color->rgbBlue = (b * 0xff) / 5;
color->rgbReserved = 0;
color++;
}
}
}
}
}
@ -518,22 +708,22 @@ INT WINAPI GetDIBits(
if (bits && lines)
{
/* If the bitmap object already have a dib section that contains image data, get the bits from it */
if(bmp->dib && bmp->dib->dsBm.bmBitsPixel >= 15 && info->bmiHeader.biBitCount >= 15)
if(bmp->dib && bmp->dib->dsBm.bmBitsPixel >= 15 && bpp >= 15)
{
/*FIXME: Only RGB dibs supported for now */
unsigned int srcwidth = bmp->dib->dsBm.bmWidth, srcwidthb = bmp->dib->dsBm.bmWidthBytes;
unsigned int dstwidth = info->bmiHeader.biWidth;
int dstwidthb = DIB_GetDIBWidthBytes( info->bmiHeader.biWidth, info->bmiHeader.biBitCount );
unsigned int dstwidth = width;
int dstwidthb = DIB_GetDIBWidthBytes( width, bpp );
LPBYTE dbits = bits, sbits = (LPBYTE) bmp->dib->dsBm.bmBits + (startscan * srcwidthb);
unsigned int x, y, width, widthb;
if ((info->bmiHeader.biHeight < 0) ^ (bmp->dib->dsBmih.biHeight < 0))
if ((height < 0) ^ (bmp->dib->dsBmih.biHeight < 0))
{
dbits = (LPBYTE)bits + (dstwidthb * (lines-1));
dstwidthb = -dstwidthb;
}
switch( info->bmiHeader.biBitCount ) {
switch( bpp ) {
case 15:
case 16: /* 16 bpp dstDIB */
@ -734,35 +924,41 @@ INT WINAPI GetDIBits(
}
}
}
else if( info->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) )
else
{
/* fill in struct members */
if( info->bmiHeader.biBitCount == 0)
{
info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
info->bmiHeader.biPlanes = 1;
info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
info->bmiHeader.biSizeImage =
DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
bmp->bitmap.bmHeight,
bmp->bitmap.bmBitsPixel );
info->bmiHeader.biCompression = 0;
}
else
{
info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(
info->bmiHeader.biWidth,
info->bmiHeader.biHeight,
info->bmiHeader.biBitCount );
}
lines = info->bmiHeader.biHeight;
if (bpp == 0)
{
if (core_header)
{
BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) info;
coreheader->bcWidth = bmp->bitmap.bmWidth;
coreheader->bcHeight = bmp->bitmap.bmHeight;
coreheader->bcPlanes = 1;
coreheader->bcBitCount = bmp->bitmap.bmBitsPixel;
}
else
{
info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
info->bmiHeader.biPlanes = 1;
info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
info->bmiHeader.biSizeImage =
DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
bmp->bitmap.bmHeight,
bmp->bitmap.bmBitsPixel );
info->bmiHeader.biCompression = 0;
}
lines = abs(bmp->bitmap.bmHeight);
}
}
TRACE("biSizeImage = %ld, biWidth = %ld, biHeight = %ld\n",
info->bmiHeader.biSizeImage, info->bmiHeader.biWidth,
info->bmiHeader.biHeight);
if (!core_header)
{
TRACE("biSizeImage = %ld, ", info->bmiHeader.biSizeImage);
}
TRACE("biWidth = %ld, biHeight = %ld\n", width, height);
GDI_ReleaseObj( hdc );
GDI_ReleaseObj( hbitmap );
@ -841,15 +1037,33 @@ HBITMAP16 WINAPI CreateDIBSection16 (HDC16 hdc, const BITMAPINFO *bmi, UINT16 us
if (bmp && bmp->dib && bits32)
{
const BITMAPINFOHEADER *bi = &bmi->bmiHeader;
INT height = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
INT width_bytes = DIB_GetDIBWidthBytes(bi->biWidth, bi->biBitCount);
INT size = (bi->biSizeImage && bi->biCompression != BI_RGB) ?
bi->biSizeImage : width_bytes * height;
LONG width, height;
WORD bpp;
DWORD compr;
BOOL core_header;
INT width_bytes;
INT size;
WORD count, sel;
int i;
core_header = (DIB_GetBitmapInfo(bi, &width, &height, &bpp, &compr) == 0);
height = height >= 0 ? height : -height;
width_bytes = DIB_GetDIBWidthBytes(width, bpp);
if (core_header)
{
size = width_bytes * height;
}
else
{
size = (bi->biSizeImage && compr != BI_RGB) ?
bi->biSizeImage : width_bytes * height;
}
/* calculate number of sel's needed for size with 64K steps */
WORD count = (size + 0xffff) / 0x10000;
WORD sel = AllocSelectorArray16(count);
int i;
count = (size + 0xffff) / 0x10000;
sel = AllocSelectorArray16(count);
for (i = 0; i < count; i++)
{

View File

@ -160,7 +160,11 @@ static void test_dibsections(void)
HDC hdc, hdcmem, hdcmem2;
HBITMAP hdib, oldbm, hdib2, oldbm2;
char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
HBITMAP hcoredib;
char coreBits[256];
BYTE *bits;
RGBQUAD rgb[256];
int ret;
@ -188,6 +192,37 @@ static void test_dibsections(void)
hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
ok(hdib != NULL, "CreateDIBSection failed\n");
/* Test if the old BITMAPCOREINFO structure is supported */
pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
pbci->bmciHeader.bcBitCount = 0;
ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
&& (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
"GetDIBits did't fill in the BITMAPCOREHEADER structure properly\n");
ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
(pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
(pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
"The color table has not been translated to the old BITMAPCOREINFO format\n");
hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
(pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
(pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
"The color table has not been translated to the old BITMAPCOREINFO format\n");
DeleteObject(hcoredib);
hdcmem = CreateCompatibleDC(hdc);
oldbm = SelectObject(hdcmem, hdib);

View File

@ -83,6 +83,12 @@ enum Rle_EscapeCodes
RLE_DELTA = 2 /* Delta */
};
/*
Some of the following helper functions are duplicated in
dlls/gdi/dib.c
*/
/***********************************************************************
* X11DRV_DIB_GetXImageWidthBytes
*
@ -139,6 +145,17 @@ static int X11DRV_DIB_GetDIBWidthBytes( int width, int depth )
}
/***********************************************************************
* X11DRV_DIB_GetDIBImageBytes
*
* Return the number of bytes used to hold the image in a DIB bitmap.
*/
static int X11DRV_DIB_GetDIBImageBytes( int width, int height, int depth )
{
return X11DRV_DIB_GetDIBWidthBytes( width, depth ) * abs( height );
}
/***********************************************************************
* X11DRV_DIB_BitmapInfoSize
*
@ -146,7 +163,7 @@ static int X11DRV_DIB_GetDIBWidthBytes( int width, int depth )
*/
int X11DRV_DIB_BitmapInfoSize( const BITMAPINFO * info, WORD coloruse )
{
int colors;
unsigned int colors;
if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
{
@ -187,29 +204,34 @@ XImage *X11DRV_DIB_CreateXImage( int width, int height, int depth )
/***********************************************************************
* DIB_GetBitmapInfo
* DIB_GetBitmapInfoEx
*
* Get the info from a bitmap header.
* Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
*/
static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width,
int *height, WORD *bpp, WORD *compr )
static int DIB_GetBitmapInfoEx( const BITMAPINFOHEADER *header, LONG *width,
LONG *height, WORD *planes, WORD *bpp,
WORD *compr, DWORD *size )
{
if (header->biSize == sizeof(BITMAPCOREHEADER))
{
BITMAPCOREHEADER *core = (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("(%ld): unknown/wrong size for header\n", header->biSize );
@ -217,6 +239,22 @@ static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width,
}
/***********************************************************************
* 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);
}
/***********************************************************************
* X11DRV_DIB_GenColorMap
*
@ -285,24 +323,25 @@ int *X11DRV_DIB_GenColorMap( X11DRV_PDEVICE *physDev, int *colorMapping,
int *X11DRV_DIB_BuildColorMap( X11DRV_PDEVICE *physDev, WORD coloruse, WORD depth,
const BITMAPINFO *info, int *nColors )
{
int colors;
unsigned int colors;
BOOL isInfo;
const void *colorPtr;
int *colorMapping;
if ((isInfo = (info->bmiHeader.biSize != sizeof(BITMAPCOREHEADER))))
isInfo = info->bmiHeader.biSize != sizeof(BITMAPCOREHEADER);
if (isInfo)
{
/* assume BITMAPINFOHEADER */
colors = info->bmiHeader.biClrUsed;
if (!colors) colors = 1 << info->bmiHeader.biBitCount;
colorPtr = info->bmiColors;
}
else /* BITMAPCOREHEADER */
else
{
colors = 1 << ((BITMAPCOREHEADER *)info)->bcBitCount;
colorPtr = (WORD *)((BITMAPCOREINFO *)info)->bmciColors;
}
colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
if (colors > 256)
{
ERR("called with >256 colors!\n");
@ -333,10 +372,19 @@ static RGBQUAD *X11DRV_DIB_BuildColorTable( X11DRV_PDEVICE *physDev, WORD coloru
const BITMAPINFO *info )
{
RGBQUAD *colorTable;
int colors, i;
unsigned int colors;
int i;
BOOL core_info = info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER);
colors = info->bmiHeader.biClrUsed;
if (!colors) colors = 1 << info->bmiHeader.biBitCount;
if (core_info)
{
colors = 1 << ((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");
@ -347,14 +395,33 @@ static RGBQUAD *X11DRV_DIB_BuildColorTable( X11DRV_PDEVICE *physDev, WORD coloru
return NULL;
if(coloruse == DIB_RGB_COLORS)
memcpy(colorTable, info->bmiColors, colors * sizeof(RGBQUAD));
else {
{
if (core_info)
{
/* Convert RGBTRIPLEs to RGBQUADs */
for (i=0; i < colors; i++)
{
colorTable[i].rgbRed = ((BITMAPCOREINFO*) info)->bmciColors[i].rgbtRed;
colorTable[i].rgbGreen = ((BITMAPCOREINFO*) info)->bmciColors[i].rgbtGreen;
colorTable[i].rgbBlue = ((BITMAPCOREINFO*) info)->bmciColors[i].rgbtBlue;
colorTable[i].rgbReserved = 0;
}
}
else
{
memcpy(colorTable, (LPBYTE) info + (WORD) info->bmiHeader.biSize, colors * sizeof(RGBQUAD));
}
}
else
{
HPALETTE hpal = GetCurrentObject(physDev->hdc, OBJ_PAL);
PALETTEENTRY pal_ents[256];
WORD *index;
WORD *index = (WORD*) ((LPBYTE) info + (WORD) info->bmiHeader.biSize);
GetPaletteEntries(hpal, 0, 256, pal_ents);
for(i = 0, index = (WORD*)info->bmiColors; i < colors; i++, index++) {
for(i = 0; i < colors; i++, index++)
{
colorTable[i].rgbRed = pal_ents[*index].peRed;
colorTable[i].rgbGreen = pal_ents[*index].peGreen;
colorTable[i].rgbBlue = pal_ents[*index].peBlue;
@ -370,7 +437,7 @@ static RGBQUAD *X11DRV_DIB_BuildColorTable( X11DRV_PDEVICE *physDev, WORD coloru
*/
int X11DRV_DIB_MapColor( int *physMap, int nPhysMap, int phys, int oldcol )
{
int color;
unsigned int color;
if ((oldcol < nPhysMap) && (physMap[oldcol] == phys))
return oldcol;
@ -3626,15 +3693,16 @@ INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest, INT yDest, DWO
const BITMAPINFO *info, UINT coloruse )
{
X11DRV_DIB_IMAGEBITS_DESCR descr;
DWORD width;
INT result;
int height;
LONG width, height;
BOOL top_down;
POINT pt;
void* colorPtr;
if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height,
&descr.infoBpp, &descr.compression ) == -1)
return 0;
top_down = (height < 0);
if (top_down) height = -height;
@ -3685,6 +3753,8 @@ INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest, INT yDest, DWO
XSetFunction(gdi_display, physDev->gc, X11DRV_XROPfunction[GetROP2(physDev->hdc) - 1]);
wine_tsx11_unlock();
colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
switch (descr.infoBpp)
{
case 1:
@ -3698,17 +3768,17 @@ INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest, INT yDest, DWO
break;
case 15:
case 16:
descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *) colorPtr : 0x7c00;
descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 1) : 0x03e0;
descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 2) : 0x001f;
descr.colorMap = 0;
break;
case 24:
case 32:
descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *) colorPtr : 0xff0000;
descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 1) : 0x00ff00;
descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 2) : 0x0000ff;
descr.colorMap = 0;
break;
}
@ -3750,8 +3820,9 @@ INT X11DRV_SetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
{
X11DRV_DIB_IMAGEBITS_DESCR descr;
BITMAPOBJ *bmp;
int height, tmpheight;
LONG height, tmpheight;
INT result;
void* colorPtr;
descr.physDev = physDev;
@ -3768,6 +3839,8 @@ INT X11DRV_SetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
if (startscan + lines > height) lines = height - startscan;
colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
switch (descr.infoBpp)
{
case 1:
@ -3786,17 +3859,17 @@ INT X11DRV_SetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
break;
case 15:
case 16:
descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *) colorPtr : 0x7c00;
descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 1) : 0x03e0;
descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 2) : 0x001f;
descr.colorMap = 0;
break;
case 24:
case 32:
descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *) colorPtr : 0xff0000;
descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 1) : 0x00ff00;
descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 2) : 0x0000ff;
descr.colorMap = 0;
break;
@ -3839,21 +3912,35 @@ INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
PALETTEENTRY palette[256];
BITMAPOBJ *bmp;
int height;
LONG tempHeight;
int bitmap_type;
BOOL core_header;
void* colorPtr;
GetPaletteEntries( GetCurrentObject( physDev->hdc, OBJ_PAL ), 0, 256, palette );
if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return 0;
dib = (X11DRV_DIBSECTION *) bmp->dib;
bitmap_type = DIB_GetBitmapInfo( (BITMAPINFOHEADER*) info, &descr.infoWidth, &tempHeight, &descr.infoBpp, &descr.compression);
descr.lines = tempHeight;
if (bitmap_type == -1)
{
ERR("Invalid bitmap\n");
lines = 0;
goto done;
}
core_header = (bitmap_type == 0);
colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
lines, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
(int)info->bmiHeader.biWidth, (int)info->bmiHeader.biHeight,
startscan );
(int)descr.infoWidth, descr.lines, startscan);
if( lines > bmp->bitmap.bmHeight ) lines = bmp->bitmap.bmHeight;
height = info->bmiHeader.biHeight;
height = descr.lines;
if (height < 0) height = -height;
if( lines > height ) lines = height;
/* Top-down images have a negative biHeight, the scanlines of theses images
@ -3862,7 +3949,7 @@ INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
* (the number of scan lines to copy).
* Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
*/
if( info->bmiHeader.biHeight < 0 && lines > 0) lines = -lines;
if( descr.lines < 0 && lines > 0) lines = -lines;
if( startscan >= bmp->bitmap.bmHeight )
{
@ -3870,13 +3957,6 @@ INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
goto done;
}
if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &descr.lines,
&descr.infoBpp, &descr.compression ) == -1)
{
lines = 0;
goto done;
}
descr.colorMap = NULL;
switch (descr.infoBpp)
@ -3886,12 +3966,12 @@ INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
case 8:
descr.rMask= descr.gMask = descr.bMask = 0;
if(coloruse == DIB_RGB_COLORS)
descr.colorMap = info->bmiColors;
descr.colorMap = colorPtr;
else {
int num_colors = 1 << descr.infoBpp, i;
RGBQUAD *rgb;
COLORREF colref;
WORD *index = (WORD*)info->bmiColors;
WORD *index = (WORD*)colorPtr;
descr.colorMap = rgb = HeapAlloc(GetProcessHeap(), 0, num_colors * sizeof(RGBQUAD));
for(i = 0; i < num_colors; i++, rgb++, index++) {
colref = X11DRV_PALETTE_ToLogical(X11DRV_PALETTE_ToPhysical(physDev, PALETTEINDEX(*index)));
@ -3904,15 +3984,15 @@ INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
break;
case 15:
case 16:
descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *) colorPtr : 0x7c00;
descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 1) : 0x03e0;
descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 2) : 0x001f;
break;
case 24:
case 32:
descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *) colorPtr : 0xff0000;
descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 1) : 0x00ff00;
descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 2) : 0x0000ff;
break;
}
@ -3929,7 +4009,7 @@ INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
descr.xDest = 0;
descr.yDest = 0;
descr.xSrc = 0;
descr.sizeImage = info->bmiHeader.biSizeImage;
descr.sizeImage = core_header ? 0 : info->bmiHeader.biSizeImage;
if (descr.lines > 0)
{
@ -3951,25 +4031,25 @@ INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
X11DRV_DIB_GetImageBits( &descr );
X11DRV_DIB_Unlock(bmp, TRUE);
if(info->bmiHeader.biSizeImage == 0) /* Fill in biSizeImage */
info->bmiHeader.biSizeImage = X11DRV_DIB_GetDIBWidthBytes( info->bmiHeader.biWidth,
info->bmiHeader.biBitCount )
* abs( info->bmiHeader.biHeight );
if(!core_header && info->bmiHeader.biSizeImage == 0) /* Fill in biSizeImage */
info->bmiHeader.biSizeImage = X11DRV_DIB_GetDIBImageBytes( descr.infoWidth,
descr.lines,
descr.infoBpp);
if (descr.compression == BI_BITFIELDS)
{
*(DWORD *)info->bmiColors = descr.rMask;
*((DWORD *)info->bmiColors+1) = descr.gMask;
*((DWORD *)info->bmiColors+2) = descr.bMask;
*(DWORD *) colorPtr = descr.rMask;
*((DWORD *)colorPtr + 1) = descr.gMask;
*((DWORD *)colorPtr + 2) = descr.bMask;
}
else
else if (!core_header)
{
/* if RLE or JPEG compression were supported,
* this line would be invalid. */
info->bmiHeader.biCompression = 0;
}
if(descr.colorMap && descr.colorMap != info->bmiColors)
if(descr.colorMap && descr.colorMap != colorPtr)
HeapFree(GetProcessHeap(), 0, descr.colorMap);
done:
GDI_ReleaseObj( hbitmap );
@ -4014,7 +4094,7 @@ static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ *bmp, BOOL toDIB,
X11DRV_DIB_IMAGEBITS_DESCR descr;
int identity[2] = {0,1};
if (DIB_GetBitmapInfo( &dib->dibSection.dsBmih, &descr.infoWidth, &descr.lines,
if (DIB_GetBitmapInfo( &dib->dibSection.dsBmih, &descr.infoWidth, (DWORD*) &descr.lines,
&descr.infoBpp, &descr.compression ) == -1)
return;
@ -4596,29 +4676,43 @@ HBITMAP X11DRV_DIB_CreateDIBSection(
int nColorMap;
RGBQUAD *colorTable = NULL;
/* Fill BITMAP32 structure with DIB data */
const BITMAPINFOHEADER *bi = &bmi->bmiHeader;
/* Fill BITMAP structure with DIB data */
INT effHeight, totalSize;
BITMAP bm;
LPVOID mapBits = NULL;
TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
int bitmap_type;
BOOL core_header;
LONG width, height;
WORD planes, bpp, compression;
DWORD sizeImage;
void* colorPtr;
effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
if (((bitmap_type = DIB_GetBitmapInfoEx((BITMAPINFOHEADER*) bmi,
&width, &height, &planes, &bpp, &compression, &sizeImage)) == -1))
{
ERR("Invalid bitmap\n");
return 0;
}
core_header = (bitmap_type == 0);
TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, %s\n",
width, height, planes, bpp,
sizeImage, usage == DIB_PAL_COLORS? "PAL" : "RGB");
effHeight = height >= 0 ? height : -height;
bm.bmType = 0;
bm.bmWidth = bi->biWidth;
bm.bmWidth = width;
bm.bmHeight = effHeight;
bm.bmWidthBytes = ovr_pitch ? ovr_pitch : X11DRV_DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
bm.bmPlanes = bi->biPlanes;
bm.bmBitsPixel = bi->biBitCount;
bm.bmWidthBytes = ovr_pitch ? ovr_pitch : X11DRV_DIB_GetDIBWidthBytes(bm.bmWidth, bpp);
bm.bmPlanes = planes;
bm.bmBitsPixel = bpp;
bm.bmBits = NULL;
/* Get storage location for DIB bits. Only use biSizeImage if it's valid and
/* Get storage location for DIB bits. Only use sizeImage if it's valid and
we're dealing with a compressed bitmap. Otherwise, use width * height. */
if (bi->biSizeImage && (bi->biCompression == BI_RLE4 || bi->biCompression == BI_RLE8))
totalSize = bi->biSizeImage;
if (sizeImage && (compression == BI_RLE4 || compression == BI_RLE8))
totalSize = sizeImage;
else
totalSize = bm.bmWidthBytes * effHeight;
@ -4658,28 +4752,47 @@ HBITMAP X11DRV_DIB_CreateDIBSection(
if (dib)
{
dib->dibSection.dsBm = bm;
dib->dibSection.dsBmih = *bi;
if (core_header)
{
/* Convert the BITMAPCOREHEADER to a BITMAPINFOHEADER.
The structure is already filled with zeros */
dib->dibSection.dsBmih.biSize = sizeof(BITMAPINFOHEADER);
dib->dibSection.dsBmih.biWidth = width;
dib->dibSection.dsBmih.biHeight = height;
dib->dibSection.dsBmih.biPlanes = planes;
dib->dibSection.dsBmih.biBitCount = bpp;
dib->dibSection.dsBmih.biCompression = compression;
}
else
{
/* Truncate extended bitmap headers (BITMAPV4HEADER etc.) */
dib->dibSection.dsBmih = *((BITMAPINFOHEADER*) bmi);
dib->dibSection.dsBmih.biSize = sizeof(BITMAPINFOHEADER);
}
dib->dibSection.dsBmih.biSizeImage = totalSize;
colorPtr = (LPBYTE) bmi + (WORD) bmi->bmiHeader.biSize;
/* Set dsBitfields values */
if ( usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
if ( usage == DIB_PAL_COLORS || bpp <= 8)
{
dib->dibSection.dsBitfields[0] = dib->dibSection.dsBitfields[1] = dib->dibSection.dsBitfields[2] = 0;
}
else switch( bi->biBitCount )
else switch( bpp )
{
case 15:
case 16:
dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0x7c00;
dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x03e0;
dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x001f;
dib->dibSection.dsBitfields[0] = (compression == BI_BITFIELDS) ? *(DWORD *) colorPtr : 0x7c00;
dib->dibSection.dsBitfields[1] = (compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 1) : 0x03e0;
dib->dibSection.dsBitfields[2] = (compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 2) : 0x001f;
break;
case 24:
case 32:
dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0xff0000;
dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x00ff00;
dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x0000ff;
dib->dibSection.dsBitfields[0] = (compression == BI_BITFIELDS) ? *(DWORD *) colorPtr : 0xff0000;
dib->dibSection.dsBitfields[1] = (compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 1) : 0x00ff00;
dib->dibSection.dsBitfields[2] = (compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 2) : 0x0000ff;
break;
}
dib->dibSection.dshSection = section;
@ -4694,8 +4807,8 @@ HBITMAP X11DRV_DIB_CreateDIBSection(
/* Create Device Dependent Bitmap and add DIB pointer */
if (dib)
{
int depth = (bi->biBitCount == 1) ? 1 : GetDeviceCaps(physDev->hdc, BITSPIXEL);
res = CreateBitmap(bi->biWidth, effHeight, 1, depth, NULL);
int depth = (bpp == 1) ? 1 : GetDeviceCaps(physDev->hdc, BITSPIXEL);
res = CreateBitmap(width, effHeight, 1, depth, NULL);
if (res)
{