Fix for LoadBitmap (regression)

Michael Kaufmann hallo at michael-kaufmann.ch
Sun Sep 19 12:51:40 CDT 2004


Revised patch: Removed two W -> A calls in the same file

> This fixes a bug which was introduced by this patch: 
> http://www.winehq.org/hypermail/wine-cvs/2004/09/0182.html
>
> LoadBitmap was not able to handle BITMAPCOREHEADERs. This has broken 
> Solitaire, Freecell and perhaps also other applications.
>
> Changelog:
>  - Fix a regression caused by an earlier patch for CreateDIBitmap


-------------- next part --------------
Index: dlls/gdi/dib.c
===================================================================
RCS file: /home/wine/wine/dlls/gdi/dib.c,v
retrieving revision 1.4
diff -u -r1.4 dib.c
--- dlls/gdi/dib.c	13 Sep 2004 19:37:04 -0000	1.4
+++ dlls/gdi/dib.c	19 Sep 2004 17:19:32 -0000
@@ -104,8 +104,8 @@
  * Return 1 for INFOHEADER, 0 for COREHEADER,
  * 4 for V4HEADER, 5 for V5HEADER, -1 for error.
  */
-static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width,
-                              int *height, WORD *bpp, WORD *compr )
+static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
+                              LONG *height, WORD *bpp, DWORD *compr )
 {
     if (header->biSize == sizeof(BITMAPINFOHEADER))
     {
@@ -782,15 +782,26 @@
                             UINT coloruse )
 {
     HBITMAP handle;
-    DWORD width;
-    int height;
+    LONG width;
+    LONG height;
     WORD bpp;
-    WORD compr;
+    DWORD compr;
     DC *dc;
 
     if (DIB_GetBitmapInfo( header, &width, &height, &bpp, &compr ) == -1) return 0;
+    
+    if (width < 0)
+    {
+        TRACE("Bitmap has a negative width\n");
+        return 0;
+    }
+    
+    /* Top-down DIBs have a negative height */
     if (height < 0) height = -height;
 
+    TRACE("hdc=%p, header=%p, init=%lu, bits=%p, data=%p, coloruse=%u (bitmap: width=%ld, height=%ld, bpp=%u, compr=%lu)\n",
+           hdc, header, init, bits, data, coloruse, width, height, bpp, compr);
+    
     if (hdc == NULL)
         handle = CreateBitmap( width, height, 1, 1, NULL );
     else
Index: windows/cursoricon.c
===================================================================
RCS file: /home/wine/wine/windows/cursoricon.c,v
retrieving revision 1.74
diff -u -r1.74 cursoricon.c
--- windows/cursoricon.c	15 Sep 2004 18:04:07 -0000	1.74
+++ windows/cursoricon.c	19 Sep 2004 17:19:38 -0000
@@ -273,6 +273,54 @@
     }
 }
 
+/***********************************************************************
+ *           DIB_GetBitmapInfo
+ *
+ * Get the info from a bitmap header.
+ * Return 1 for INFOHEADER, 0 for COREHEADER,
+ * 4 for V4HEADER, 5 for V5HEADER, -1 for error.
+ */
+static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
+                              LONG *height, WORD *bpp, DWORD *compr )
+{
+    if (header->biSize == sizeof(BITMAPINFOHEADER))
+    {
+        *width  = header->biWidth;
+        *height = header->biHeight;
+        *bpp    = header->biBitCount;
+        *compr  = header->biCompression;
+        return 1;
+    }
+    if (header->biSize == sizeof(BITMAPCOREHEADER))
+    {
+        BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)header;
+        *width  = core->bcWidth;
+        *height = core->bcHeight;
+        *bpp    = core->bcBitCount;
+        *compr  = 0;
+        return 0;
+    }
+    if (header->biSize == sizeof(BITMAPV4HEADER))
+    {
+        BITMAPV4HEADER *v4hdr = (BITMAPV4HEADER *)header;
+        *width  = v4hdr->bV4Width;
+        *height = v4hdr->bV4Height;
+        *bpp    = v4hdr->bV4BitCount;
+        *compr  = v4hdr->bV4V4Compression;
+        return 4;
+    }
+    if (header->biSize == sizeof(BITMAPV5HEADER))
+    {
+        BITMAPV5HEADER *v5hdr = (BITMAPV5HEADER *)header;
+        *width  = v5hdr->bV5Width;
+        *height = v5hdr->bV5Height;
+        *bpp    = v5hdr->bV5BitCount;
+        *compr  = v5hdr->bV5Compression;
+        return 5;
+    }
+    ERR("(%ld): unknown/wrong size for header\n", header->biSize );
+    return -1;
+}
 
 /**********************************************************************
  *	    CURSORICON_FindSharedIcon
@@ -659,7 +707,7 @@
           return 0;
     }
 
-    if (!screen_dc) screen_dc = CreateDCA( "DISPLAY", NULL, NULL, NULL );
+    if (!screen_dc) screen_dc = CreateDCW( DISPLAYW, NULL, NULL, NULL );
     if (screen_dc)
     {
 	BITMAPINFO* pInfo;
@@ -2059,7 +2107,7 @@
       memcpy(fix_info, info, size);
       pix = *((LPBYTE)info + size);
       DIB_FixColorsToLoadflags(fix_info, loadflags, pix);
-      if (!screen_dc) screen_dc = CreateDCA( "DISPLAY", NULL, NULL, NULL );
+      if (!screen_dc) screen_dc = CreateDCW( DISPLAYW, NULL, NULL, NULL );
 
       if (screen_dc)
       {
@@ -2075,18 +2123,31 @@
         else {
             /* If it's possible, create a monochrome bitmap */
 
-            LONG height = fix_info->bmiHeader.biHeight;
-            if (height < 0) height = -height;
+            LONG width;
+            LONG height;
+            WORD bpp;
+            DWORD compr;
 
-            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);
+            if (DIB_GetBitmapInfo( &fix_info->bmiHeader, &width, &height, &bpp, &compr ) != -1)
+            {
+                if (width < 0)
+                    TRACE("Bitmap has a negative width\n");
+                else
+                {
+                    /* Top-down DIBs have a negative height */
+                    if (height < 0) height = -height;
 
-            SetDIBits(screen_dc, hbitmap, 0, height, bits, info, DIB_RGB_COLORS);
-	}
+                    TRACE("width=%ld, height=%ld, bpp=%u, compr=%lu\n", width, height, bpp, compr);
+
+                    if (is_dib_monochrome(fix_info))
+                        hbitmap = CreateBitmap(width, height, 1, 1, NULL);
+                    else
+                        hbitmap = CreateCompatibleBitmap(screen_dc, width, height);
+
+                    SetDIBits(screen_dc, hbitmap, 0, height, bits, info, DIB_RGB_COLORS);
+                }
+            }
+         }
       }
 
       GlobalUnlock(hFix);


More information about the wine-patches mailing list