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