[PATCH] winex11.drv: in GetDIBits() with DIBSections, always use dibpitch from the target

Wolfram Sang wolfram at the-dreams.de
Wed Dec 1 11:10:49 CST 2010


The target object should decide the number of bytes to copy, not the
source.

Signed-off-by: Wolfram Sang <wolfram at the-dreams.de>
---

The source object is already converted, so its bmWidthBytes is obsolete
meanwhile and causes the wrong number of bytes to be copied (if you look
closely at the background picture in Blobby Volley, you can see that it starts
drawing from the button, but just copying 1/4th of the needed bytes. So, we
have the first four scanlines from the source in the one lowest scanline in the
destination, because the source object is an 8-bit DIBSection, while the target
is 24/32 bit). This patch fixes at least Blobby Volley (Bug #4432) and
AlphaControls (Bug #12808) but I suspect that it affects a few more
bug-entries.

 dlls/gdi32/tests/bitmap.c |   15 +++++++++++++--
 dlls/winex11.drv/dib.c    |    3 +--
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c
index aa723bd..d0d7a9c 100644
--- a/dlls/gdi32/tests/bitmap.c
+++ b/dlls/gdi32/tests/bitmap.c
@@ -1218,7 +1218,8 @@ static void test_GetDIBits_selected_DIB(UINT bpp)
     BITMAPINFO * info2;
     void * bits;
     void * bits2;
-    UINT dib_size;
+    UINT dib_size, dib32_size;
+    DWORD pixel;
     HDC dib_dc, dc;
     HBITMAP old_bmp;
     BOOL equalContents;
@@ -1254,6 +1255,7 @@ static void test_GetDIBits_selected_DIB(UINT bpp)
     dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
     assert(dib);
     dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
+    dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
 
     /* Set the bits of the DIB section */
     for (i=0; i < dib_size; i++)
@@ -1265,7 +1267,7 @@ static void test_GetDIBits_selected_DIB(UINT bpp)
     dib_dc = CreateCompatibleDC(NULL);
     old_bmp = SelectObject(dib_dc, dib);
     dc = CreateCompatibleDC(NULL);
-    bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib_size);
+    bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
     assert(bits2);
 
     /* Copy the DIB attributes but not the color table */
@@ -1300,6 +1302,15 @@ static void test_GetDIBits_selected_DIB(UINT bpp)
     }
     ok(equalContents, "GetDIBits with %d bpp DIB selected in DC: Invalid DIB bits\n",bpp);
 
+    /* Map into a 32bit-DIB */
+    info2->bmiHeader.biBitCount = 32;
+    res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
+    ok(res, "GetDIBits failed\n");
+
+    /* Check if last pixel was set */
+    pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
+    ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
+
     HeapFree(GetProcessHeap(), 0, bits2);
     DeleteDC(dc);
 
diff --git a/dlls/winex11.drv/dib.c b/dlls/winex11.drv/dib.c
index 11157f1..05bd30c 100644
--- a/dlls/winex11.drv/dib.c
+++ b/dlls/winex11.drv/dib.c
@@ -4210,8 +4210,7 @@ INT CDECL X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT start
      descr.ySrc = startscan;
   }
   descr.shm_mode = physBitmap->shm_mode;
-  descr.dibpitch = (obj_size == sizeof(DIBSECTION)) ? dib.dsBm.bmWidthBytes
-		       : (((descr.infoWidth * descr.infoBpp + 31) &~31) / 8);
+  descr.dibpitch = (((descr.infoWidth * descr.infoBpp + 31) &~31) / 8);
 
   X11DRV_DIB_Lock( physBitmap, DIB_Status_GdiMod );
   X11DRV_DIB_GetImageBits( &descr );
-- 
1.7.2.3




More information about the wine-patches mailing list