CreateDIBitmap fix
Huw D M Davies
h.davies1 at physics.ox.ac.uk
Mon Sep 13 06:12:39 CDT 2004
Michael Kaufmann <hallo at michael-kaufmann.ch>
Huw Davies <huw at codeweavers.com>
CreateDIBitmap should return bitmaps at the depth of the
supplied dc.
Add a test to exercise this behaviour.
--
Huw Davies
huw at codeweavers.com
Index: dlls/gdi/dib.c
===================================================================
RCS file: /home/wine/wine/dlls/gdi/dib.c,v
retrieving revision 1.3
diff -u -r1.3 dib.c
--- dlls/gdi/dib.c 12 Aug 2004 20:02:39 -0000 1.3
+++ dlls/gdi/dib.c 13 Sep 2004 11:05:17 -0000
@@ -773,13 +773,15 @@
/***********************************************************************
* CreateDIBitmap (GDI32.@)
+ *
+ * Creates a DDB (device dependent bitmap) from a DIB.
+ * The DDB will have the same color depth as the reference DC.
*/
HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header,
DWORD init, LPCVOID bits, const BITMAPINFO *data,
UINT coloruse )
{
HBITMAP handle;
- BOOL fColor;
DWORD width;
int height;
WORD bpp;
@@ -789,91 +791,26 @@
if (DIB_GetBitmapInfo( header, &width, &height, &bpp, &compr ) == -1) return 0;
if (height < 0) height = -height;
- /* Check if we should create a monochrome or color bitmap. */
- /* We create a monochrome bitmap only if it has exactly 2 */
- /* colors, which are black followed by white, nothing else. */
- /* In all other cases, we create a color bitmap. */
-
- if (bpp != 1) fColor = TRUE;
- else if ((coloruse != DIB_RGB_COLORS) || !data) fColor = FALSE;
+ if (hdc == NULL)
+ handle = CreateBitmap( width, height, 1, 1, NULL );
else
- {
- if (data->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
- {
- RGBQUAD *rgb = data->bmiColors;
- DWORD col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
-
- /* Check if the first color of the colormap is black */
- if ((col == RGB(0,0,0)))
- {
- rgb++;
- col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
- /* If the second color is white, create a monochrome bitmap */
- fColor = (col != RGB(0xff,0xff,0xff));
- }
- /* Note : If the first color of the colormap is white
- followed by black, we have to create a color bitmap.
- If we don't the white will be displayed in black later on!*/
- else fColor = TRUE;
- }
- else if (data->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
- {
- RGBTRIPLE *rgb = ((BITMAPCOREINFO *)data)->bmciColors;
- DWORD col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue );
- if ((col == RGB(0,0,0)))
- {
- rgb++;
- col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue );
- fColor = (col != RGB(0xff,0xff,0xff));
- }
- else fColor = TRUE;
- }
- else if (data->bmiHeader.biSize == sizeof(BITMAPV4HEADER))
- { /* FIXME: correct ? */
- RGBQUAD *rgb = data->bmiColors;
- DWORD col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
-
- /* Check if the first color of the colormap is black */
- if ((col == RGB(0,0,0)))
- {
- rgb++;
- col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
- /* If the second color is white, create a monochrome bitmap */
- fColor = (col != RGB(0xff,0xff,0xff));
- }
- /* Note : If the first color of the colormap is white
- followed by black, we have to create a color bitmap.
- If we don't the white will be displayed in black later on!*/
- else fColor = TRUE;
- }
- else
- {
- ERR("(%ld): wrong/unknown size for data\n",
- data->bmiHeader.biSize );
- return 0;
- }
- }
-
- /* Now create the bitmap */
-
- if (!(dc = DC_GetDCPtr( hdc ))) return 0;
-
- if (fColor)
- handle = CreateBitmap( width, height, GetDeviceCaps( hdc, PLANES ),
- GetDeviceCaps( hdc, BITSPIXEL ), NULL );
- else handle = CreateBitmap( width, height, 1, 1, NULL );
+ handle = CreateCompatibleBitmap( hdc, width, height );
if (handle)
{
if (init == CBM_INIT) SetDIBits( hdc, handle, 0, height, bits, data, coloruse );
- else if (!BITMAP_SetOwnerDC( handle, dc ))
+
+ else if (hdc && ((dc = DC_GetDCPtr( hdc )) != NULL) )
{
- DeleteObject( handle );
- handle = 0;
+ if (!BITMAP_SetOwnerDC( handle, dc ))
+ {
+ DeleteObject( handle );
+ handle = 0;
+ }
+ GDI_ReleaseObj( hdc );
}
}
- GDI_ReleaseObj( hdc );
return handle;
}
Index: dlls/gdi/enhmetafile.c
===================================================================
RCS file: /home/wine/wine/dlls/gdi/enhmetafile.c,v
retrieving revision 1.3
diff -u -r1.3 enhmetafile.c
--- dlls/gdi/enhmetafile.c 8 Sep 2004 01:37:24 -0000 1.3
+++ dlls/gdi/enhmetafile.c 13 Sep 2004 11:05:22 -0000
@@ -196,6 +196,55 @@
return NULL;
}
+/***********************************************************************
+ * is_dib_monochrome
+ *
+ * Returns whether a DIB can be converted to a monochrome DDB.
+ *
+ * A DIB can be converted if its color table contains only black and
+ * white. Black must be the first color in the color table.
+ *
+ * Note : If the first color in the color table is white followed by
+ * black, we can't convert it to a monochrome DDB with
+ * SetDIBits, because black and white would be inverted.
+ */
+static BOOL is_dib_monochrome( const BITMAPINFO* info )
+{
+ if (info->bmiHeader.biBitCount != 1) return FALSE;
+
+ if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+ {
+ RGBTRIPLE *rgb = ((BITMAPCOREINFO *) info)->bmciColors;
+
+ /* Check if the first color is black */
+ if ((rgb->rgbtRed == 0) && (rgb->rgbtGreen == 0) && (rgb->rgbtBlue == 0))
+ {
+ rgb++;
+
+ /* Check if the second color is white */
+ return ((rgb->rgbtRed == 0xff) && (rgb->rgbtGreen == 0xff)
+ && (rgb->rgbtBlue == 0xff));
+ }
+ else return FALSE;
+ }
+ else /* assume BITMAPINFOHEADER */
+ {
+ RGBQUAD *rgb = info->bmiColors;
+
+ /* Check if the first color is black */
+ if ((rgb->rgbRed == 0) && (rgb->rgbGreen == 0) &&
+ (rgb->rgbBlue == 0) && (rgb->rgbReserved == 0))
+ {
+ rgb++;
+
+ /* Check if the second color is white */
+ return ((rgb->rgbRed == 0xff) && (rgb->rgbGreen == 0xff)
+ && (rgb->rgbBlue == 0xff) && (rgb->rgbReserved == 0));
+ }
+ else return FALSE;
+ }
+}
+
/****************************************************************************
* EMF_Create_HENHMETAFILE
*/
@@ -1619,11 +1668,30 @@
case EMR_CREATEMONOBRUSH:
{
- PEMRCREATEMONOBRUSH pCreateMonoBrush = (PEMRCREATEMONOBRUSH)mr;
- BITMAPINFO *pbi = (BITMAPINFO *)((BYTE *)mr + pCreateMonoBrush->offBmi);
- HBITMAP hBmp = CreateDIBitmap(0, (BITMAPINFOHEADER *)pbi, CBM_INIT,
- (BYTE *)mr + pCreateMonoBrush->offBits, pbi, pCreateMonoBrush->iUsage);
+ PEMRCREATEMONOBRUSH pCreateMonoBrush = (PEMRCREATEMONOBRUSH)mr;
+ BITMAPINFO *pbi = (BITMAPINFO *)((BYTE *)mr + pCreateMonoBrush->offBmi);
+ HBITMAP hBmp;
+
+ /* Need to check if the bitmap is monochrome, and if the
+ two colors are really black and white */
+ if (is_dib_monochrome(pbi))
+ {
+ /* Top-down DIBs have a negative height */
+ LONG height = pbi->bmiHeader.biHeight;
+ if (height < 0) height = -height;
+
+ hBmp = CreateBitmap(pbi->bmiHeader.biWidth, height, 1, 1, NULL);
+ SetDIBits(hdc, hBmp, 0, pbi->bmiHeader.biHeight,
+ (BYTE *)mr + pCreateMonoBrush->offBits, pbi, pCreateMonoBrush->iUsage);
+ }
+ else
+ {
+ hBmp = CreateDIBitmap(hdc, (BITMAPINFOHEADER *)pbi, CBM_INIT,
+ (BYTE *)mr + pCreateMonoBrush->offBits, pbi, pCreateMonoBrush->iUsage);
+ }
+
(handletable->objectHandle)[pCreateMonoBrush->ihBrush] = CreatePatternBrush(hBmp);
+
/* CreatePatternBrush created a copy of the bitmap */
DeleteObject(hBmp);
break;
@@ -1652,7 +1720,7 @@
SelectObject(hdcSrc, hBrushOld);
DeleteObject(hBrush);
- hBmp = CreateDIBitmap(0, (BITMAPINFOHEADER *)pbi, CBM_INIT,
+ hBmp = CreateDIBitmap(hdc, (BITMAPINFOHEADER *)pbi, CBM_INIT,
(BYTE *)mr + pBitBlt->offBitsSrc, pbi, pBitBlt->iUsageSrc);
hBmpOld = SelectObject(hdcSrc, hBmp);
@@ -1694,7 +1762,7 @@
SelectObject(hdcSrc, hBrushOld);
DeleteObject(hBrush);
- hBmp = CreateDIBitmap(0, (BITMAPINFOHEADER *)pbi, CBM_INIT,
+ hBmp = CreateDIBitmap(hdc, (BITMAPINFOHEADER *)pbi, CBM_INIT,
(BYTE *)mr + pStretchBlt->offBitsSrc, pbi, pStretchBlt->iUsageSrc);
hBmpOld = SelectObject(hdcSrc, hBmp);
@@ -1728,11 +1796,13 @@
DeleteObject(hBrush);
pbi = (BITMAPINFO *)((BYTE *)mr + pMaskBlt->offBmiMask);
- hBmpMask = CreateDIBitmap(0, (BITMAPINFOHEADER *)pbi, CBM_INIT,
- (BYTE *)mr + pMaskBlt->offBitsMask, pbi, pMaskBlt->iUsageMask);
+ hBmpMask = CreateBitmap(pbi->bmiHeader.biWidth, pbi->bmiHeader.biHeight,
+ 1, 1, NULL);
+ SetDIBits(hdc, hBmpMask, 0, pbi->bmiHeader.biHeight,
+ (BYTE *)mr + pMaskBlt->offBitsMask, pbi, pMaskBlt->iUsageMask);
pbi = (BITMAPINFO *)((BYTE *)mr + pMaskBlt->offBmiSrc);
- hBmp = CreateDIBitmap(0, (BITMAPINFOHEADER *)pbi, CBM_INIT,
+ hBmp = CreateDIBitmap(hdc, (BITMAPINFOHEADER *)pbi, CBM_INIT,
(BYTE *)mr + pMaskBlt->offBitsSrc, pbi, pMaskBlt->iUsageSrc);
hBmpOld = SelectObject(hdcSrc, hBmp);
MaskBlt(hdc,
@@ -1778,11 +1848,13 @@
DeleteObject(hBrush);
pbi = (BITMAPINFO *)((BYTE *)mr + pPlgBlt->offBmiMask);
- hBmpMask = CreateDIBitmap(0, (BITMAPINFOHEADER *)pbi, CBM_INIT,
- (BYTE *)mr + pPlgBlt->offBitsMask, pbi, pPlgBlt->iUsageMask);
+ hBmpMask = CreateBitmap(pbi->bmiHeader.biWidth, pbi->bmiHeader.biHeight,
+ 1, 1, NULL);
+ SetDIBits(hdc, hBmpMask, 0, pbi->bmiHeader.biHeight,
+ (BYTE *)mr + pPlgBlt->offBitsMask, pbi, pPlgBlt->iUsageMask);
pbi = (BITMAPINFO *)((BYTE *)mr + pPlgBlt->offBmiSrc);
- hBmp = CreateDIBitmap(0, (BITMAPINFOHEADER *)pbi, CBM_INIT,
+ hBmp = CreateDIBitmap(hdc, (BITMAPINFOHEADER *)pbi, CBM_INIT,
(BYTE *)mr + pPlgBlt->offBitsSrc, pbi, pPlgBlt->iUsageSrc);
hBmpOld = SelectObject(hdcSrc, hBmp);
PlgBlt(hdc,
Index: dlls/gdi/tests/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/gdi/tests/Makefile.in,v
retrieving revision 1.3
diff -u -r1.3 Makefile.in
--- dlls/gdi/tests/Makefile.in 1 Sep 2004 17:29:28 -0000 1.3
+++ dlls/gdi/tests/Makefile.in 13 Sep 2004 11:05:22 -0000
@@ -6,6 +6,7 @@
IMPORTS = user32 gdi32
CTESTS = \
+ bitmap.c \
gdiobj.c \
generated.c \
metafile.c
Index: windows/cursoricon.c
===================================================================
RCS file: /home/wine/wine/windows/cursoricon.c,v
retrieving revision 1.72
diff -u -r1.72 cursoricon.c
--- windows/cursoricon.c 31 Aug 2004 00:02:02 -0000 1.72
+++ windows/cursoricon.c 13 Sep 2004 11:05:24 -0000
@@ -224,6 +224,56 @@
}
+/***********************************************************************
+ * is_dib_monochrome
+ *
+ * Returns whether a DIB can be converted to a monochrome DDB.
+ *
+ * A DIB can be converted if its color table contains only black and
+ * white. Black must be the first color in the color table.
+ *
+ * Note : If the first color in the color table is white followed by
+ * black, we can't convert it to a monochrome DDB with
+ * SetDIBits, because black and white would be inverted.
+ */
+static BOOL is_dib_monochrome( const BITMAPINFO* info )
+{
+ if (info->bmiHeader.biBitCount != 1) return FALSE;
+
+ if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+ {
+ RGBTRIPLE *rgb = ((BITMAPCOREINFO *) info)->bmciColors;
+
+ /* Check if the first color is black */
+ if ((rgb->rgbtRed == 0) && (rgb->rgbtGreen == 0) && (rgb->rgbtBlue == 0))
+ {
+ rgb++;
+
+ /* Check if the second color is white */
+ return ((rgb->rgbtRed == 0xff) && (rgb->rgbtGreen == 0xff)
+ && (rgb->rgbtBlue == 0xff));
+ }
+ else return FALSE;
+ }
+ else /* assume BITMAPINFOHEADER */
+ {
+ RGBQUAD *rgb = info->bmiColors;
+
+ /* Check if the first color is black */
+ if ((rgb->rgbRed == 0) && (rgb->rgbGreen == 0) &&
+ (rgb->rgbBlue == 0) && (rgb->rgbReserved == 0))
+ {
+ rgb++;
+
+ /* Check if the second color is white */
+ return ((rgb->rgbRed == 0xff) && (rgb->rgbGreen == 0xff)
+ && (rgb->rgbBlue == 0xff) && (rgb->rgbReserved == 0));
+ }
+ else return FALSE;
+ }
+}
+
+
/**********************************************************************
* CURSORICON_FindSharedIcon
*/
@@ -657,8 +707,17 @@
}
if (!res) { DeleteObject(hXorBits); hXorBits = 0; }
}
- } else hXorBits = CreateDIBitmap( screen_dc, &pInfo->bmiHeader,
- CBM_INIT, (char*)bmi + size, pInfo, DIB_RGB_COLORS );
+ } else {
+ if (is_dib_monochrome(bmi)) {
+ hXorBits = CreateBitmap(width, height, 1, 1, NULL);
+ SetDIBits(screen_dc, hXorBits, 0, height,
+ (char*)bmi + size, pInfo, DIB_RGB_COLORS);
+ }
+ else
+ hXorBits = CreateDIBitmap(screen_dc, &pInfo->bmiHeader,
+ CBM_INIT, (char*)bmi + size, pInfo, DIB_RGB_COLORS);
+ }
+
if( hXorBits )
{
char* xbits = (char *)bmi + size +
@@ -700,9 +759,13 @@
}
if (!res) { DeleteObject(hAndBits); hAndBits = 0; }
}
- } else hAndBits = CreateDIBitmap( screen_dc, &pInfo->bmiHeader,
- CBM_INIT, xbits, pInfo, DIB_RGB_COLORS );
+ } else {
+ hAndBits = CreateBitmap(width, height, 1, 1, NULL);
+
+ if (hAndBits) SetDIBits(screen_dc, hAndBits, 0, height,
+ xbits, pInfo, DIB_RGB_COLORS);
+ }
if( !hAndBits ) DeleteObject( hXorBits );
}
HeapFree( GetProcessHeap(), 0, pInfo );
@@ -1170,7 +1233,7 @@
iinfo.hbmColor = CreateDIBitmap( hdc, &bmi.bmiHeader,
CBM_INIT, lpXORbits,
&bmi, DIB_RGB_COLORS );
-
+
hIcon=CreateIconIndirect(&iinfo);
DeleteObject(iinfo.hbmMask);
DeleteObject(iinfo.hbmColor);
@@ -1957,7 +2020,7 @@
/**********************************************************************
* BITMAP_Load
*/
-static HBITMAP BITMAP_Load( HINSTANCE instance,LPCWSTR name, UINT loadflags )
+static HBITMAP BITMAP_Load( HINSTANCE instance, LPCWSTR name, UINT loadflags )
{
HBITMAP hbitmap = 0;
HRSRC hRsrc;
@@ -1975,6 +2038,7 @@
if (HIWORD(name)) return 0;
instance = user32_module;
}
+
if (!(hRsrc = FindResourceW( instance, name, (LPWSTR)RT_BITMAP ))) return 0;
if (!(handle = LoadResource( instance, hRsrc ))) return 0;
@@ -1985,8 +2049,10 @@
if (!(ptr = map_fileW( name ))) return 0;
info = (BITMAPINFO *)(ptr + sizeof(BITMAPFILEHEADER));
}
+
size = bitmap_info_size(info, DIB_RGB_COLORS);
if ((hFix = GlobalAlloc(0, size))) fix_info=GlobalLock(hFix);
+
if (fix_info) {
BYTE pix;
@@ -1994,9 +2060,11 @@
pix = *((LPBYTE)info + size);
DIB_FixColorsToLoadflags(fix_info, loadflags, pix);
if (!screen_dc) screen_dc = CreateDCA( "DISPLAY", NULL, NULL, NULL );
+
if (screen_dc)
{
char *bits = (char *)info + size;
+
if (loadflags & LR_CREATEDIBSECTION) {
DIBSECTION dib;
hbitmap = CreateDIBSection(screen_dc, fix_info, DIB_RGB_COLORS, NULL, 0, 0);
@@ -2005,14 +2073,28 @@
DIB_RGB_COLORS);
}
else {
- hbitmap = CreateDIBitmap( screen_dc, &fix_info->bmiHeader, CBM_INIT,
- bits, fix_info, DIB_RGB_COLORS );
+ /* If it's possible, create a monochrome bitmap */
+
+ LONG height = fix_info->bmiHeader.biHeight;
+ if (height < 0) height = -height;
+
+ if (is_dib_monochrome(fix_info))
+ hbitmap = CreateBitmap(fix_info->bmiHeader.biWidth, height, 1, 1, NULL);
+ else
+ hbitmap = CreateBitmap(fix_info->bmiHeader.biWidth, height,
+ GetDeviceCaps(screen_dc, PLANES),
+ GetDeviceCaps(screen_dc, BITSPIXEL), NULL);
+
+ SetDIBits(screen_dc, hbitmap, 0, height, bits, info, DIB_RGB_COLORS);
}
}
+
GlobalUnlock(hFix);
GlobalFree(hFix);
}
+
if (loadflags & LR_LOADFROMFILE) UnmapViewOfFile( ptr );
+
return hbitmap;
}
--- /dev/null 2003-01-30 10:24:37.000000000 +0000
+++ dlls/gdi/tests/bitmap.c 2004-09-10 17:11:20.000000000 +0100
@@ -0,0 +1,161 @@
+/*
+ * Unit test suite for bitmaps
+ *
+ * Copyright 2004 Huw Davies
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdarg.h>
+#include <assert.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+
+#include "wine/test.h"
+
+
+static void test_createdibitmap(void)
+{
+ HDC hdc, hdcmem;
+ BITMAPINFOHEADER bmih;
+ BITMAP bm;
+ HBITMAP hbm, hbm_colour, hbm_old;
+ INT screen_depth;
+
+ hdc = GetDC(0);
+ screen_depth = GetDeviceCaps(hdc, BITSPIXEL);
+ memset(&bmih, 0, sizeof(bmih));
+ bmih.biSize = sizeof(bmih);
+ bmih.biWidth = 10;
+ bmih.biHeight = 10;
+ bmih.biPlanes = 1;
+ bmih.biBitCount = 32;
+ bmih.biCompression = BI_RGB;
+
+ /* First create an un-initialised bitmap. The depth of the bitmap
+ should match that of the hdc and not that supplied in bmih.
+ */
+
+ /* First try 32 bits */
+ hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
+ ok(hbm != NULL, "CreateDIBitmap failed\n");
+ ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n");
+
+ ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth);
+ DeleteObject(hbm);
+
+ /* Then 16 */
+ bmih.biBitCount = 16;
+ hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
+ ok(hbm != NULL, "CreateDIBitmap failed\n");
+ ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n");
+
+ ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth);
+ DeleteObject(hbm);
+
+ /* Then 1 */
+ bmih.biBitCount = 1;
+ hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
+ ok(hbm != NULL, "CreateDIBitmap failed\n");
+ ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n");
+
+ ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth);
+ DeleteObject(hbm);
+
+ /* Now with a monochrome dc we expect a monochrome bitmap */
+ hdcmem = CreateCompatibleDC(hdc);
+
+ /* First try 32 bits */
+ bmih.biBitCount = 32;
+ hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
+ ok(hbm != NULL, "CreateDIBitmap failed\n");
+ ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n");
+
+ ok(bm.bmBitsPixel == 1, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, 1);
+ DeleteObject(hbm);
+
+ /* Then 16 */
+ bmih.biBitCount = 16;
+ hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
+ ok(hbm != NULL, "CreateDIBitmap failed\n");
+ ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n");
+
+ ok(bm.bmBitsPixel == 1, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, 1);
+ DeleteObject(hbm);
+
+ /* Then 1 */
+ bmih.biBitCount = 1;
+ hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
+ ok(hbm != NULL, "CreateDIBitmap failed\n");
+ ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n");
+
+ ok(bm.bmBitsPixel == 1, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, 1);
+ DeleteObject(hbm);
+
+ /* Now select a polychrome bitmap into the dc and we expect
+ screen_depth bitmaps again */
+ hbm_colour = CreateCompatibleBitmap(hdc, 1, 1);
+ hbm_old = SelectObject(hdcmem, hbm_colour);
+
+ /* First try 32 bits */
+ bmih.biBitCount = 32;
+ hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
+ ok(hbm != NULL, "CreateDIBitmap failed\n");
+ ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n");
+
+ ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth);
+ DeleteObject(hbm);
+
+ /* Then 16 */
+ bmih.biBitCount = 16;
+ hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
+ ok(hbm != NULL, "CreateDIBitmap failed\n");
+ ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n");
+
+ ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth);
+ DeleteObject(hbm);
+
+ /* Then 1 */
+ bmih.biBitCount = 1;
+ hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
+ ok(hbm != NULL, "CreateDIBitmap failed\n");
+ ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n");
+
+ ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth);
+ DeleteObject(hbm);
+
+ SelectObject(hdcmem, hbm_old);
+ DeleteObject(hbm_colour);
+ DeleteDC(hdcmem);
+
+ /* If hdc == 0 then we get a 1 bpp bitmap */
+ bmih.biBitCount = 32;
+ hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0);
+ ok(hbm != NULL, "CreateDIBitmap failed\n");
+ ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n");
+
+ ok(bm.bmBitsPixel == 1, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, 1);
+ DeleteObject(hbm);
+
+ ReleaseDC(0, hdc);
+}
+
+START_TEST(bitmap)
+{
+ test_createdibitmap();
+}
More information about the wine-patches
mailing list