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