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