John Edmonds : gdi32: Fixed GetDIBits for top-down bitmaps.

Alexandre Julliard julliard at winehq.org
Wed Feb 23 13:01:54 CST 2011


Module: wine
Branch: master
Commit: 3c239fa0cd00a80cdccde9f7a19e9bbf862bac4f
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=3c239fa0cd00a80cdccde9f7a19e9bbf862bac4f

Author: John Edmonds <pocketcookies2 at gmail.com>
Date:   Sun Feb 20 22:31:26 2011 -0500

gdi32: Fixed GetDIBits for top-down bitmaps.

---

 dlls/gdi32/dib.c          |   23 ++++++++++++++---------
 dlls/gdi32/tests/bitmap.c |   10 +++++-----
 2 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c
index 5067e49..0619304 100644
--- a/dlls/gdi32/dib.c
+++ b/dlls/gdi32/dib.c
@@ -871,18 +871,23 @@ INT WINAPI GetDIBits(
         if(bmp->dib && bmp->dib->dsBm.bmBitsPixel >= 15 && bpp >= 15)
         {
             /*FIXME: Only RGB dibs supported for now */
-            unsigned int srcwidth = bmp->dib->dsBm.bmWidth, srcwidthb = bmp->dib->dsBm.bmWidthBytes;
+            unsigned int srcwidth = bmp->dib->dsBm.bmWidth;
+            int srcwidthb = bmp->dib->dsBm.bmWidthBytes;
             unsigned int dstwidth = width;
-            int dstwidthb = DIB_GetDIBWidthBytes( width, bpp );
+            unsigned int dstwidthb = DIB_GetDIBWidthBytes( width, bpp );
             LPBYTE dbits = bits, sbits = (LPBYTE) bmp->dib->dsBm.bmBits + (startscan * srcwidthb);
             unsigned int x, y, width, widthb;
 
-            if ((height < 0) ^ (bmp->dib->dsBmih.biHeight < 0))
+            /*
+             * If copying from a top-down source bitmap, move the source
+             * pointer to the end of the source bitmap and negate the width
+             * so that we copy the bits upside-down.
+             */
+            if (bmp->dib->dsBmih.biHeight < 0)
             {
-                dbits = (LPBYTE)bits + (dstwidthb * (lines-1));
-                dstwidthb = -dstwidthb;
+                sbits += (srcwidthb * (abs(bmp->dib->dsBmih.biHeight) - 2 * startscan - 1));
+                srcwidthb = -srcwidthb;
             }
-
             switch( bpp ) {
 
 	    case 15:
@@ -897,7 +902,7 @@ INT WINAPI GetDIBits(
 
                     case 16: /* 16 bpp srcDIB -> 16 bpp dstDIB */
                         {
-                            widthb = min(srcwidthb, abs(dstwidthb));
+                            widthb = min(abs(srcwidthb), dstwidthb);
                             /* FIXME: BI_BITFIELDS not supported yet */
                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
                                 memcpy(dbits, sbits, widthb);
@@ -975,7 +980,7 @@ INT WINAPI GetDIBits(
 
                     case 24: /* 24 bpp srcDIB -> 24 bpp dstDIB */
                         {
-                            widthb = min(srcwidthb, abs(dstwidthb));
+                            widthb = min(abs(srcwidthb), dstwidthb);
                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
                                 memcpy(dbits, sbits, widthb);
                         }
@@ -1051,7 +1056,7 @@ INT WINAPI GetDIBits(
 
                     case 32: /* 32 bpp srcDIB -> 32 bpp dstDIB */
                         {
-                            widthb = min(srcwidthb, abs(dstwidthb));
+                            widthb = min(abs(srcwidthb), 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 4b54302..1a743c7 100644
--- a/dlls/gdi32/tests/bitmap.c
+++ b/dlls/gdi32/tests/bitmap.c
@@ -3116,27 +3116,27 @@ static void test_GetDIBits_single_pixel_destination(int bpp)
     ok((char)pixelOut == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pixelOut);
     statusCode = GetDIBits(hdc, bmptb, 0, 1, &pixelOut, &bi, DIB_RGB_COLORS);
     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
-    todo_wine ok((char)pixelOut == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pixelOut);
+    ok((char)pixelOut == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pixelOut);
     /*Check second scanline.*/
     statusCode = GetDIBits(hdc, bmptb, 1, 1, &pixelOut, &bi, DIB_RGB_COLORS);
     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
-    todo_wine ok((char)pixelOut == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pixelOut);
+    ok((char)pixelOut == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pixelOut);
     statusCode = GetDIBits(hdc, bmpbt, 1, 1, &pixelOut, &bi, DIB_RGB_COLORS);
     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
     ok((char)pixelOut == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pixelOut);
 
-    /*Make destination bitmap top-down. Windows (and soon, Wine) will ignore this.*/
+    /*Make destination bitmap top-down.  This should be ignored by GetDIBits.*/
     bi.bmiHeader.biHeight = -2;
     statusCode = GetDIBits(hdc, bmpbt, 0, 1, &pixelOut, &bi, DIB_RGB_COLORS);
     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
     ok((char)pixelOut == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pixelOut);
     statusCode = GetDIBits(hdc, bmptb, 0, 1, &pixelOut, &bi, DIB_RGB_COLORS);
     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
-    todo_wine ok((char)pixelOut == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pixelOut);
+    ok((char)pixelOut == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pixelOut);
     /*Check second scanline.*/
     statusCode = GetDIBits(hdc, bmptb, 1, 1, &pixelOut, &bi, DIB_RGB_COLORS);
     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
-    todo_wine ok((char)pixelOut == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pixelOut);
+    ok((char)pixelOut == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pixelOut);
     statusCode = GetDIBits(hdc, bmpbt, 1, 1, &pixelOut, &bi, DIB_RGB_COLORS);
     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
     ok((char)pixelOut == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pixelOut);




More information about the wine-cvs mailing list