[PATCH 2/2] gdi32: Fixes GetDIBits for top-down destination bitmaps.

John Edmonds pocketcookies2 at gmail.com
Tue Mar 1 21:29:51 CST 2011


Resolves Bug #26236.
---
 dlls/gdi32/dib.c          |   14 ++++++++++----
 dlls/gdi32/tests/bitmap.c |    8 ++++----
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c
index eae7f35..0abd833 100644
--- a/dlls/gdi32/dib.c
+++ b/dlls/gdi32/dib.c
@@ -874,7 +874,7 @@ INT WINAPI GetDIBits(
             unsigned int srcwidth = bmp->dib->dsBm.bmWidth;
             int srcwidthb = bmp->dib->dsBm.bmWidthBytes;
             unsigned int dstwidth = width;
-            unsigned int dstwidthb = DIB_GetDIBWidthBytes( width, bpp );
+            int dstwidthb = DIB_GetDIBWidthBytes( width, bpp );
             LPBYTE dbits = bits, sbits = (LPBYTE) bmp->dib->dsBm.bmBits + (startscan * srcwidthb);
             unsigned int x, y, width, widthb;
 
@@ -888,6 +888,12 @@ INT WINAPI GetDIBits(
                 sbits += (srcwidthb * (int)(abs(bmp->dib->dsBmih.biHeight) - 2 * startscan - 1));
                 srcwidthb = -srcwidthb;
             }
+            /*Same for the destination.*/
+            if (height < 0)
+            {
+                dbits = (LPBYTE)bits + (dstwidthb * (lines - 1));
+                dstwidthb = -dstwidthb;
+            }
             switch( bpp ) {
 
 	    case 15:
@@ -902,7 +908,7 @@ INT WINAPI GetDIBits(
 
                     case 16: /* 16 bpp srcDIB -> 16 bpp dstDIB */
                         {
-                            widthb = min(abs(srcwidthb), dstwidthb);
+                            widthb = min(abs(srcwidthb), abs(dstwidthb));
                             /* FIXME: BI_BITFIELDS not supported yet */
                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
                                 memcpy(dbits, sbits, widthb);
@@ -980,7 +986,7 @@ INT WINAPI GetDIBits(
 
                     case 24: /* 24 bpp srcDIB -> 24 bpp dstDIB */
                         {
-                            widthb = min(abs(srcwidthb), dstwidthb);
+                            widthb = min(abs(srcwidthb), abs(dstwidthb));
                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
                                 memcpy(dbits, sbits, widthb);
                         }
@@ -1056,7 +1062,7 @@ INT WINAPI GetDIBits(
 
                     case 32: /* 32 bpp srcDIB -> 32 bpp dstDIB */
                         {
-                            widthb = min(abs(srcwidthb), dstwidthb);
+                            widthb = min(abs(srcwidthb), abs(dstwidthb));
                             /* FIXME: BI_BITFIELDS not supported yet */
                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb) {
                                 memcpy(dbits, sbits, widthb);
diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c
index 01ac758..adef035 100644
--- a/dlls/gdi32/tests/bitmap.c
+++ b/dlls/gdi32/tests/bitmap.c
@@ -3057,12 +3057,12 @@ static void test_GetDIBits_top_down(int bpp)
     /*Check both scanlines.*/
     statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
-    todo_wine ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
-    todo_wine ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
+    ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
+    ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
     statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
-    todo_wine ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
-    todo_wine ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
+    ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
+    ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
 
     DeleteObject(bmpbt);
     DeleteObject(bmptb);
-- 
1.7.1





More information about the wine-patches mailing list