gdi32: Fixed GetDIBits for top-down bitmaps (try 2).

Jack Edmonds pocketcookies2 at gmail.com
Sat Feb 12 12:24:26 CST 2011


gdi32/dib.c:          Reversed source bitmap pointer instead of destination bitmap pointer.
                      Removed check for destination bitmap height when determining whether to copy the source bitmap upside down.
gdi32/tests/bitmap.c: Added a test for copying between top-down bitmaps.
---
 dlls/gdi32/dib.c          |   12 +++++++---
 dlls/gdi32/tests/bitmap.c |   52 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c
index 5067e49..9004b2c 100644
--- a/dlls/gdi32/dib.c
+++ b/dlls/gdi32/dib.c
@@ -876,11 +876,15 @@ INT WINAPI GetDIBits(
             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) - startscan - 1));
+                srcwidthb = -srcwidthb;
             }
 
             switch( bpp ) {
diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c
index d0d7a9c..ffdb2a4 100644
--- a/dlls/gdi32/tests/bitmap.c
+++ b/dlls/gdi32/tests/bitmap.c
@@ -3050,6 +3050,57 @@ static void test_32bit_bitmap_blt(void)
     DeleteDC(hdcScreen);
 }
 
+static void test_GetDIBits_single_pixel_destination(void)
+{
+    BITMAPINFO bi;
+    HBITMAP bmptb, bmpbt;
+    HDC hdc;
+    int pixelOut;
+    int *picture;
+    bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
+    bi.bmiHeader.biWidth=2;
+    bi.bmiHeader.biHeight=2;
+    bi.bmiHeader.biPlanes=1;
+    bi.bmiHeader.biBitCount=32;
+    bi.bmiHeader.biCompression=BI_RGB;
+
+    /*Get the device context for the screen.*/
+    hdc=GetDC(NULL);
+
+    /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
+    bmpbt=CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
+    /*Now that we have a pointer to the pixels, we write to them.*/
+    picture[0]=1;
+    picture[1]=2;
+    picture[2]=3;
+    picture[3]=4;
+    /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
+    bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
+    bmptb=CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
+    /*Write to this top to bottom bitmap.*/
+    picture[0]=1;
+    picture[1]=2;
+    picture[2]=3;
+    picture[3]=4;
+
+    bi.bmiHeader.biWidth=1;
+
+    bi.bmiHeader.biHeight=2;
+    GetDIBits(hdc, bmpbt, 0, 1, &pixelOut, &bi, DIB_RGB_COLORS);
+    ok(pixelOut==1, "Bottom-up -> bottom-up should have first scanline.\n");
+    GetDIBits(hdc, bmptb, 0, 1, &pixelOut, &bi, DIB_RGB_COLORS);
+    ok(pixelOut==3, "Top-down -> bottom-up should have last scanline.\n");
+    
+    bi.bmiHeader.biHeight=-2;
+    GetDIBits(hdc, bmpbt, 0, 1, &pixelOut, &bi, DIB_RGB_COLORS);
+    ok(pixelOut==1, "Bottom-up -> top-down should have first scanline.\n");
+    GetDIBits(hdc, bmptb, 0, 1, &pixelOut, &bi, DIB_RGB_COLORS);
+    ok(pixelOut==3, "Top-down -> top-down should have last scanline.\n");
+
+    DeleteObject(bmpbt);
+    DeleteObject(bmptb);
+}
+
 START_TEST(bitmap)
 {
     HMODULE hdll;
@@ -3080,4 +3131,5 @@ START_TEST(bitmap)
     test_bitmapinfoheadersize();
     test_get16dibits();
     test_clipping();
+    test_GetDIBits_single_pixel_destination();
 }
-- 
1.7.1





More information about the wine-patches mailing list