PATCH: handle NULL XImage in GetBitmapBits
Marcus Meissner
marcus at jet.franken.de
Tue Dec 13 02:43:15 CST 2005
On Mon, Dec 12, 2005 at 05:42:57PM +0100, Alexandre Julliard wrote:
> Marcus Meissner <marcus at jet.franken.de> writes:
>
> > Hi,
> >
> > This fixes bug 4034.
> > XGetImage() returns NULL since we can pass a 0 height value. (298 bytes
> > vs 320 byte wide image).
>
> This shouldn't happen, the height should have been checked in
> GetBitmapBits already. There's something wrong here...
Yes.
trace:bitmap:DIB_CreateDIBSection format (95,1), planes 1, bpp 32, size 0, RGB
trace:bitmap:CreateBitmapIndirect 95x1, 16777216 colors returning 0x3754
trace:bitmap:X11DRV_DIB_DoProtectDIBSection Changed protection from 4 to 4
trace:bitmap:GetBitmapBits (0x3754, 286, 0x5a22d750) 95(286 bytes)x1 16777216 colors fetched height: 1
trace:bitmap:GetBitmapBits Calling device specific BitmapBits
bmWidthBytes is 286.
trace:x11drv:X11DRV_GetBitmapBits (bmp=0x3754, buffer=0x5a22d750, count=0x11e)
trace:x11drv:X11DRV_GetBitmapBits (widthbytes=380, height=0, oldheight=1)
bmWidthBytes is 380.
This is the same bitmap...
In GDI it is got like this:
bitmap = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
In X11DRV like this:
GetObjectW( hbitmap, sizeof(bitmap), &bitmap ))
The later calls into gdi/bitmap.c to get the bitmap data, while
the first one does not.
The problem here is that the specific bitmap is actually a DIB,
and GDI GetBitmapBits() uses the "bitmap" part of the BITMAP object,
but should have used the "dib" part for the information.
I would suggest something along the lines of this patch:
Ciao, Marcus
Changelog:
In GetBitmapBits() handle the correct bitmap information
when a DIB is used.
Index: dlls/gdi/bitmap.c
===================================================================
RCS file: /home/wine/wine/dlls/gdi/bitmap.c,v
retrieving revision 1.9
diff -u -r1.9 bitmap.c
--- dlls/gdi/bitmap.c 29 Nov 2005 11:06:17 -0000 1.9
+++ dlls/gdi/bitmap.c 13 Dec 2005 08:37:19 -0000
@@ -303,14 +303,20 @@
LPVOID bits) /* [out] Pointer to buffer to receive bits */
{
BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
+ BITMAP bitmap;
LONG height, ret;
if (!bmp) return 0;
+ if (!GetObjectW(hbitmap, sizeof(bitmap), &bitmap)) {
+ GDI_ReleaseObj( hbitmap );
+ return 0;
+ }
+
/* If the bits vector is null, the function should return the read size */
if(bits == NULL)
{
- ret = bmp->bitmap.bmWidthBytes * bmp->bitmap.bmHeight;
+ ret = bitmap.bmWidthBytes * bitmap.bmHeight;
goto done;
}
@@ -320,9 +326,9 @@
}
/* Only get entire lines */
- height = count / bmp->bitmap.bmWidthBytes;
- if (height > bmp->bitmap.bmHeight) height = bmp->bitmap.bmHeight;
- count = height * bmp->bitmap.bmWidthBytes;
+ height = count / bitmap.bmWidthBytes;
+ if (height > bitmap.bmHeight) height = bitmap.bmHeight;
+ count = height * bitmap.bmWidthBytes;
if (count == 0)
{
WARN("Less than one entire line requested\n");
@@ -331,9 +337,9 @@
}
- TRACE("(%p, %ld, %p) %dx%d %d colors fetched height: %ld\n",
- hbitmap, count, bits, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
- 1 << bmp->bitmap.bmBitsPixel, height );
+ TRACE("(%p, %ld, %p) %d(%d bytes)x%d %d colors fetched height: %ld\n",
+ hbitmap, count, bits, bitmap.bmWidth, bitmap.bmWidthBytes,
+ bitmap.bmHeight, 1 << bitmap.bmBitsPixel, height );
if(bmp->funcs && bmp->funcs->pGetBitmapBits)
{
More information about the wine-patches
mailing list