Patch for CreateDIBitmap: Don't create monochrome bitmaps (help wanted)

Michael Kaufmann hallo at michael-kaufmann.ch
Mon Aug 23 10:35:43 CDT 2004


Hi all,

I need some help in fixing a bug in CreateDIBitmap. I've attached a 
patch, but unfortunately it introduces new bugs.

The function CreateDIBitmap creates a monochrome device-dependent bitmap 
if it's possible. But that's very bad, because BitBlt and StretchBlt 
handle monochrome bitmaps in a different way than color bitmaps (copied 
from MSDN):

"If *StretchBlt* must convert a monochrome bitmap to a color bitmap, it 
sets white bits (1) to the background color and black bits (0) to the 
foreground color. The foreground and background colors of the device 
context with color are used."

So SetTextColor and SetBkColor can change the colors of the (formerly 
device independent) bitmap, and that's not what we want. The attached 
patch fixes this bug (don't create monochrome bitmaps anymore), but it 
seems that other code in WINE depends on the old behavior. The mouse 
cursor is now completely garbage. Can anybody help me finding the 
remaining bugs?


Test Program (DIB-Testcase.zip):
---------------------------------

I've created a test program that shows the problem. It also shows a bug 
in Windows! It displays two bitmaps, both should be black and white. 
WINE displays them red on green (I've set these colors with 
SetTextColor/SetBkColor).

The images differ only in a single byte. I've used the program bmpdump ( 
http://david.tribble.com/programs.html ) to analyze them. In the color 
table of the bitmaps, the rgbReserved member of a RGBQUAD structure is 
0x00 for the left bitmap and 0xFF for the right bitmap. This shouldn't 
make a difference. But Windows creates a monochrome bitmap for the left 
one, and a color bitmap for the right one! Does anyone understand this 
behavior?

Regards

Michael
-------------- next part --------------
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	23 Aug 2004 14:45:03 -0000
@@ -779,7 +779,6 @@
                             UINT coloruse )
 {
     HBITMAP handle;
-    BOOL fColor;
     DWORD width;
     int height;
     WORD bpp;
@@ -789,79 +788,10 @@
     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;
-    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 ),
+    handle = CreateBitmap( width, height, GetDeviceCaps( hdc, PLANES ),
                                GetDeviceCaps( hdc, BITSPIXEL ), NULL );
-    else handle = CreateBitmap( width, height, 1, 1, NULL );
 
     if (handle)
     {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: DIB-Testcase.zip
Type: application/zip
Size: 28098 bytes
Desc: not available
Url : http://www.winehq.org/pipermail/wine-devel/attachments/20040823/6dfe96ad/DIB-Testcase.zip


More information about the wine-devel mailing list