Commit 0dd2910e authored by Michael Kaufmann's avatar Michael Kaufmann Committed by Alexandre Julliard

- Extended support for BITMAPCOREINFO / BITMAPCOREHEADER structures.

- Always calculate the location of the color table. - CreateCompatibleBitmap: Create a DIB section if necessary. - Added some tests.
parent 7ce76466
...@@ -171,32 +171,83 @@ HBITMAP WINAPI CreateCompatibleBitmap( HDC hdc, INT width, INT height) ...@@ -171,32 +171,83 @@ HBITMAP WINAPI CreateCompatibleBitmap( HDC hdc, INT width, INT height)
HBITMAP hbmpRet = 0; HBITMAP hbmpRet = 0;
DC *dc; DC *dc;
TRACE("(%p,%d,%d) = \n", hdc, width, height ); TRACE("(%p,%d,%d) = \n", hdc, width, height);
if (!(dc = DC_GetDCPtr( hdc ))) return 0;
if ((width >= 0x10000) || (height >= 0x10000)) { if ((width >= 0x10000) || (height >= 0x10000))
FIXME("got bad width %d or height %d, please look for reason\n", {
width, height ); FIXME("got bad width %d or height %d, please look for reason\n",
width, height);
} }
else else
{ {
INT planes, bpp; if (!(dc = DC_GetDCPtr(hdc))) return 0;
if (GDIMAGIC( dc->header.wMagic ) != MEMORY_DC_MAGIC) if (GDIMAGIC( dc->header.wMagic ) != MEMORY_DC_MAGIC)
{ {
planes = GetDeviceCaps( hdc, PLANES ); hbmpRet = CreateBitmap(width, height,
bpp = GetDeviceCaps( hdc, BITSPIXEL ); 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 ); BITMAPOBJ *bmp = GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC );
planes = bmp->bitmap.bmPlanes;
bpp = bmp->bitmap.bmBitsPixel; if (!bmp->dib)
GDI_ReleaseObj( dc->hBitmap ); {
/* 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); TRACE("\t\t%p\n", hbmpRet);
GDI_ReleaseObj(hdc);
return hbmpRet; return hbmpRet;
} }
...@@ -618,6 +669,8 @@ BOOL WINAPI GetBitmapDimensionEx( ...@@ -618,6 +669,8 @@ BOOL WINAPI GetBitmapDimensionEx(
* SetBitmapDimensionEx [GDI32.@] * SetBitmapDimensionEx [GDI32.@]
* *
* Assigns dimensions to a bitmap. * 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 * RETURNS
* Success: TRUE * Success: TRUE
......
...@@ -160,7 +160,11 @@ static void test_dibsections(void) ...@@ -160,7 +160,11 @@ static void test_dibsections(void)
HDC hdc, hdcmem, hdcmem2; HDC hdc, hdcmem, hdcmem2;
HBITMAP hdib, oldbm, hdib2, oldbm2; HBITMAP hdib, oldbm, hdib2, oldbm2;
char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)]; char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf; BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
HBITMAP hcoredib;
char coreBits[256];
BYTE *bits; BYTE *bits;
RGBQUAD rgb[256]; RGBQUAD rgb[256];
int ret; int ret;
...@@ -188,6 +192,37 @@ static void test_dibsections(void) ...@@ -188,6 +192,37 @@ static void test_dibsections(void)
hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0); hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
ok(hdib != NULL, "CreateDIBSection failed\n"); 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); hdcmem = CreateCompatibleDC(hdc);
oldbm = SelectObject(hdcmem, hdib); oldbm = SelectObject(hdcmem, hdib);
......
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