<p>Sorry about that. I added the newlines in my latest patch. Thanks for telling me.</p>
<div class="gmail_quote">On Feb 8, 2011 4:22 AM, &quot;Nicolas Le Cam&quot; &lt;<a href="mailto:niko.lecam@gmail.com">niko.lecam@gmail.com</a>&gt; wrote:<br type="attribution">&gt; 2011/2/8 Jack Edmonds &lt;jack@jack-desktop.&gt;<br>
&gt; <br>&gt;&gt; Fixes bug 25698 and addresses one of the test cases in bug 24278 (possibly<br>&gt;&gt; resolves bug 24278 but more testing is required to be sure).<br>&gt;&gt;<br>&gt;&gt; dib.c: Fills BITMAPINFOHEADER with correct width and height when bits ==<br>
&gt;&gt; NULL and copying from a top-to-bottom bitmap.<br>&gt;&gt; For top-to-bottom bitmaps, reverses the source pointer rather than the<br>&gt;&gt; destination pointer.<br>&gt;&gt; Ignoring the case when both source and destination are top-to-bottom<br>
&gt;&gt; bitmaps and treating this as if the destination is only a top-to-bottom<br>&gt;&gt; bitmap.<br>&gt;&gt; ---<br>&gt;&gt;  dlls/gdi32/dib.c          |  113<br>&gt;&gt; ++++++++++++++++++++++++---------------------<br>
&gt;&gt;  dlls/gdi32/tests/bitmap.c |  112<br>&gt;&gt; ++++++++++++++++++++++++++++++++++++++++++++<br>&gt;&gt;  2 files changed, 173 insertions(+), 52 deletions(-)<br>&gt;&gt;<br>&gt;&gt; diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c<br>
&gt;&gt; index 5067e49..bf7a525 100644<br>&gt;&gt; --- a/dlls/gdi32/dib.c<br>&gt;&gt; +++ b/dlls/gdi32/dib.c<br>&gt;&gt; @@ -636,54 +636,6 @@ INT WINAPI GetDIBits(<br>&gt;&gt;<br>&gt;&gt;     switch (bpp)<br>&gt;&gt;     {<br>
&gt;&gt; -    case 0:  /* query bitmap info only */<br>&gt;&gt; -        if (core_header)<br>&gt;&gt; -        {<br>&gt;&gt; -            BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) info;<br>&gt;&gt; -            coreheader-&gt;bcWidth = bmp-&gt;bitmap.bmWidth;<br>
&gt;&gt; -            coreheader-&gt;bcHeight = bmp-&gt;bitmap.bmHeight;<br>&gt;&gt; -            coreheader-&gt;bcPlanes = 1;<br>&gt;&gt; -            coreheader-&gt;bcBitCount = bmp-&gt;bitmap.bmBitsPixel;<br>&gt;&gt; -        }<br>
&gt;&gt; -        else<br>&gt;&gt; -        {<br>&gt;&gt; -            info-&gt;bmiHeader.biWidth = bmp-&gt;bitmap.bmWidth;<br>&gt;&gt; -            info-&gt;bmiHeader.biHeight = bmp-&gt;bitmap.bmHeight;<br>&gt;&gt; -            info-&gt;bmiHeader.biPlanes = 1;<br>
&gt;&gt; -            info-&gt;bmiHeader.biSizeImage =<br>&gt;&gt; -                DIB_GetDIBImageBytes( bmp-&gt;bitmap.bmWidth,<br>&gt;&gt; -                                      bmp-&gt;bitmap.bmHeight,<br>&gt;&gt; -                                      bmp-&gt;bitmap.bmBitsPixel );<br>
&gt;&gt; -            if (bmp-&gt;dib)<br>&gt;&gt; -            {<br>&gt;&gt; -                info-&gt;bmiHeader.biBitCount = bmp-&gt;dib-&gt;dsBm.bmBitsPixel;<br>&gt;&gt; -                switch (bmp-&gt;dib-&gt;dsBm.bmBitsPixel)<br>
&gt;&gt; -                {<br>&gt;&gt; -                case 16:<br>&gt;&gt; -                case 32:<br>&gt;&gt; -                    info-&gt;bmiHeader.biCompression = BI_BITFIELDS;<br>&gt;&gt; -                    break;<br>
&gt;&gt; -                default:<br>&gt;&gt; -                    info-&gt;bmiHeader.biCompression = BI_RGB;<br>&gt;&gt; -                    break;<br>&gt;&gt; -                }<br>&gt;&gt; -            }<br>&gt;&gt; -            else<br>
&gt;&gt; -            {<br>&gt;&gt; -                info-&gt;bmiHeader.biCompression = (bmp-&gt;bitmap.bmBitsPixel &gt;<br>&gt;&gt; 8) ? BI_BITFIELDS : BI_RGB;<br>&gt;&gt; -                info-&gt;bmiHeader.biBitCount = bmp-&gt;bitmap.bmBitsPixel;<br>
&gt;&gt; -            }<br>&gt;&gt; -            info-&gt;bmiHeader.biXPelsPerMeter = 0;<br>&gt;&gt; -            info-&gt;bmiHeader.biYPelsPerMeter = 0;<br>&gt;&gt; -            info-&gt;bmiHeader.biClrUsed = 0;<br>&gt;&gt; -            info-&gt;bmiHeader.biClrImportant = 0;<br>
&gt;&gt; -<br>&gt;&gt; -            /* Windows 2000 doesn&#39;t touch the additional struct members if<br>&gt;&gt; -               it&#39;s a BITMAPV4HEADER or a BITMAPV5HEADER */<br>&gt;&gt; -        }<br>&gt;&gt; -        lines = abs(bmp-&gt;bitmap.bmHeight);<br>
&gt;&gt; -        goto done;<br>&gt;&gt; -<br>&gt;&gt;     case 1:<br>&gt;&gt;     case 4:<br>&gt;&gt;     case 8:<br>&gt;&gt; @@ -877,10 +829,10 @@ INT WINAPI GetDIBits(<br>&gt;&gt;             LPBYTE dbits = bits, sbits = (LPBYTE) bmp-&gt;dib-&gt;dsBm.bmBits +<br>
&gt;&gt; (startscan * srcwidthb);<br>&gt;&gt;             unsigned int x, y, width, widthb;<br>&gt;&gt;<br>&gt;&gt; -            if ((height &lt; 0) ^ (bmp-&gt;dib-&gt;dsBmih.biHeight &lt; 0))<br>&gt;&gt; +            if (bmp-&gt;dib-&gt;dsBmih.biHeight &lt; 0)<br>
&gt;&gt;             {<br>&gt;&gt; -                dbits = (LPBYTE)bits + (dstwidthb * (lines-1));<br>&gt;&gt; -                dstwidthb = -dstwidthb;<br>&gt;&gt; +                sbits += (srcwidthb * (abs(bmp-&gt;dib-&gt;dsBmih.biHeight) -<br>
&gt;&gt; startscan - 1));<br>&gt;&gt; +                srcwidthb = -srcwidthb;<br>&gt;&gt;             }<br>&gt;&gt;<br>&gt;&gt;             switch( bpp ) {<br>&gt;&gt; @@ -1086,7 +1038,64 @@ INT WINAPI GetDIBits(<br>&gt;&gt;             }<br>
&gt;&gt;         }<br>&gt;&gt;     }<br>&gt;&gt; -    else lines = abs(height);<br>&gt;&gt; +    else /* query bitmap info only */<br>&gt;&gt; +    {<br>&gt;&gt; +        if (core_header)<br>&gt;&gt; +        {<br>&gt;&gt; +            BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) info;<br>
&gt;&gt; +            if (bmp-&gt;dib)<br>&gt;&gt; +            {<br>&gt;&gt; +                coreheader-&gt;bcWidth = bmp-&gt;dib-&gt;dsBmih.biWidth;<br>&gt;&gt; +                coreheader-&gt;bcHeight = bmp-&gt;dib-&gt;dsBmih.biHeight;<br>
&gt;&gt; +            }<br>&gt;&gt; +            else<br>&gt;&gt; +            {<br>&gt;&gt; +                coreheader-&gt;bcWidth = bmp-&gt;bitmap.bmWidth;<br>&gt;&gt; +                coreheader-&gt;bcHeight = bmp-&gt;bitmap.bmHeight;<br>
&gt;&gt; +            }<br>&gt;&gt; +            coreheader-&gt;bcPlanes = 1;<br>&gt;&gt; +            coreheader-&gt;bcBitCount = bmp-&gt;bitmap.bmBitsPixel;<br>&gt;&gt; +        }<br>&gt;&gt; +        else<br>&gt;&gt; +        {<br>
&gt;&gt; +            if (bmp-&gt;dib)<br>&gt;&gt; +            {<br>&gt;&gt; +                info-&gt;bmiHeader.biHeight = bmp-&gt;dib-&gt;dsBmih.biHeight;<br>&gt;&gt; +                info-&gt;bmiHeader.biWidth = bmp-&gt;dib-&gt;dsBmih.biWidth;<br>
&gt;&gt; +                info-&gt;bmiHeader.biBitCount = bmp-&gt;dib-&gt;dsBm.bmBitsPixel;<br>&gt;&gt; +                switch (bmp-&gt;dib-&gt;dsBm.bmBitsPixel)<br>&gt;&gt; +                {<br>&gt;&gt; +                case 16:<br>
&gt;&gt; +                case 32:<br>&gt;&gt; +                    info-&gt;bmiHeader.biCompression = BI_BITFIELDS;<br>&gt;&gt; +                    break;<br>&gt;&gt; +                default:<br>&gt;&gt; +                    info-&gt;bmiHeader.biCompression = BI_RGB;<br>
&gt;&gt; +                    break;<br>&gt;&gt; +                }<br>&gt;&gt; +            }<br>&gt;&gt; +            else<br>&gt;&gt; +            {<br>&gt;&gt; +                info-&gt;bmiHeader.biWidth = bmp-&gt;bitmap.bmWidth;<br>
&gt;&gt; +                info-&gt;bmiHeader.biHeight = bmp-&gt;bitmap.bmHeight;<br>&gt;&gt; +                info-&gt;bmiHeader.biCompression = (bmp-&gt;bitmap.bmBitsPixel &gt;<br>&gt;&gt; 8) ? BI_BITFIELDS : BI_RGB;<br>
&gt;&gt; +                info-&gt;bmiHeader.biBitCount = bmp-&gt;bitmap.bmBitsPixel;<br>&gt;&gt; +            }<br>&gt;&gt; +            info-&gt;bmiHeader.biPlanes = 1;<br>&gt;&gt; +            info-&gt;bmiHeader.biSizeImage =<br>
&gt;&gt; +                DIB_GetDIBImageBytes( bmp-&gt;bitmap.bmWidth,<br>&gt;&gt; +                                      bmp-&gt;bitmap.bmHeight,<br>&gt;&gt; +                                      bmp-&gt;bitmap.bmBitsPixel );<br>
&gt;&gt; +            info-&gt;bmiHeader.biXPelsPerMeter = 0;<br>&gt;&gt; +            info-&gt;bmiHeader.biYPelsPerMeter = 0;<br>&gt;&gt; +            info-&gt;bmiHeader.biClrUsed = 0;<br>&gt;&gt; +            info-&gt;bmiHeader.biClrImportant = 0;<br>
&gt;&gt; +<br>&gt;&gt; +            /* Windows 2000 doesn&#39;t touch the additional struct members if<br>&gt;&gt; +               it&#39;s a BITMAPV4HEADER or a BITMAPV5HEADER */<br>&gt;&gt; +        }<br>&gt;&gt; +        lines = abs(bmp-&gt;bitmap.bmHeight);<br>
&gt;&gt; +    }<br>&gt;&gt;<br>&gt;&gt;     /* The knowledge base article Q81498 (&quot;DIBs and Their Uses&quot;) states<br>&gt;&gt; that<br>&gt;&gt;        if bits == NULL and bpp != 0, only biSizeImage and the color table<br>
&gt;&gt; are<br>&gt;&gt; diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c<br>&gt;&gt; index d0d7a9c..a76d437 100644<br>&gt;&gt; --- a/dlls/gdi32/tests/bitmap.c<br>&gt;&gt; +++ b/dlls/gdi32/tests/bitmap.c<br>
&gt;&gt; @@ -3050,6 +3050,116 @@ static void test_32bit_bitmap_blt(void)<br>&gt;&gt;     DeleteDC(hdcScreen);<br>&gt;&gt;  }<br>&gt;&gt;<br>&gt;&gt; +static void test_GetDIBits_info_query(void)<br>&gt;&gt; +{<br>&gt;&gt; +    BITMAPINFO bi;<br>
&gt;&gt; +    HBITMAP bmp;<br>&gt;&gt; +    HDC hdc;<br>&gt;&gt; +    int *picture;<br>&gt;&gt; +<br>&gt;&gt; +    hdc = GetDC(NULL);<br>&gt;&gt; +<br>&gt;&gt; +    bi.bmiHeader.biSize=sizeof(bi.bmiHeader);<br>&gt;&gt; +    bi.bmiHeader.biWidth=2;<br>
&gt;&gt; +    bi.bmiHeader.biHeight=2;<br>&gt;&gt; +    bi.bmiHeader.biPlanes=1;<br>&gt;&gt; +    bi.bmiHeader.biBitCount=32;<br>&gt;&gt; +    bi.bmiHeader.biCompression=BI_RGB;<br>&gt;&gt; +    bmp = CreateDIBSection(hdc, &amp;bi, DIB_RGB_COLORS, (void**)&amp;picture,<br>
&gt;&gt; NULL, 0);<br>&gt;&gt; +    /*Clear the structure to make sure that we really are testing that the<br>&gt;&gt; structure is being written to.*/<br>&gt;&gt; +    memset(&amp;bi, 0, sizeof(bi));<br>&gt;&gt; +    /*Test with a BITMAPINFOHEADER.*/<br>
&gt;&gt; +    bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);<br>&gt;&gt; +    GetDIBits(hdc, bmp, 0, 0, NULL, &amp;bi, DIB_RGB_COLORS);<br>&gt;&gt; +    ok(bi.bmiHeader.biHeight == 2, &quot;Height should be 2.&quot;);<br>
&gt;&gt; +    ok(bi.bmiHeader.biWidth == 2, &quot;Width should be 2.&quot;);<br>&gt;&gt; +    /*Clear the structure to make sure that we really are testing that the<br>&gt;&gt; structure is being written to.*/<br>&gt;&gt; +    memset(&amp;bi, 0, sizeof(bi));<br>
&gt;&gt; +    /*Now test with a BITMAPCOREHEADER.*/<br>&gt;&gt; +    bi.bmiHeader.biSize=sizeof(BITMAPCOREHEADER);<br>&gt;&gt; +    GetDIBits(hdc, bmp, 0, 0, NULL, &amp;bi, DIB_RGB_COLORS);<br>&gt;&gt; +    ok(((BITMAPCOREHEADER*)&amp;bi)-&gt;bcHeight == 2, &quot;Height should be 2.&quot;);<br>
&gt;&gt; +    ok(((BITMAPCOREHEADER*)&amp;bi)-&gt;bcWidth == 2, &quot;Width should be 2.&quot;);<br>&gt;&gt; +    /*Clean up.*/<br>&gt;&gt; +    DeleteObject(bmp);<br>&gt;&gt; +<br>&gt;&gt; +    /*Test top to bottom bitmap.*/<br>
&gt;&gt; +    bi.bmiHeader.biSize=sizeof(bi.bmiHeader);<br>&gt;&gt; +    bi.bmiHeader.biWidth=2;<br>&gt;&gt; +    bi.bmiHeader.biHeight=-2;<br>&gt;&gt; +    bi.bmiHeader.biPlanes=1;<br>&gt;&gt; +    bi.bmiHeader.biBitCount=32;<br>
&gt;&gt; +    bi.bmiHeader.biCompression=BI_RGB;<br>&gt;&gt; +    bmp = CreateDIBSection(hdc, &amp;bi, DIB_RGB_COLORS, (void**)&amp;picture,<br>&gt;&gt; NULL, 0);<br>&gt;&gt; +    /*Clear the structure to make sure that we really are testing that the<br>
&gt;&gt; structure is being written to.*/<br>&gt;&gt; +    memset(&amp;bi, 0, sizeof(bi));<br>&gt;&gt; +    /*Test with a BITMAPINFOHEADER.*/<br>&gt;&gt; +    bi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);<br>&gt;&gt; +    GetDIBits(hdc, bmp, 0, 0, NULL, &amp;bi, DIB_RGB_COLORS);<br>
&gt;&gt; +    ok(bi.bmiHeader.biHeight == -2, &quot;Height should be -2.&quot;);<br>&gt;&gt; +    ok(bi.bmiHeader.biWidth == 2, &quot;Width should be 2.&quot;);<br>&gt;&gt; +    /*Clear the structure to make sure that we really are testing that the<br>
&gt;&gt; structure is being written to.*/<br>&gt;&gt; +    memset(&amp;bi, 0, sizeof(bi));<br>&gt;&gt; +    /*Now test with a BITMAPCOREHEADER.*/<br>&gt;&gt; +    bi.bmiHeader.biSize=sizeof(BITMAPCOREHEADER);<br>&gt;&gt; +    GetDIBits(hdc, bmp, 0, 0, NULL, &amp;bi, DIB_RGB_COLORS);<br>
&gt;&gt; +    ok(((BITMAPCOREHEADER*)&amp;bi)-&gt;bcHeight == (WORD)-2, &quot;Height should be<br>&gt;&gt; -2.&quot;);<br>&gt;&gt; +    ok(((BITMAPCOREHEADER*)&amp;bi)-&gt;bcWidth == (WORD)2, &quot;Width should be<br>&gt;&gt; 2.&quot;);<br>
&gt;&gt; +    /*Clean up.*/<br>&gt;&gt; +    DeleteObject(bmp);<br>&gt;&gt; +}<br>&gt;&gt; +<br>&gt;&gt; +static void test_GetDIBits_single_pixel_destination(void)<br>&gt;&gt; +{<br>&gt;&gt; +    BITMAPINFO bi;<br>&gt;&gt; +    HBITMAP bmptb, bmpbt;<br>
&gt;&gt; +    HDC hdc;<br>&gt;&gt; +    int pixelOut;<br>&gt;&gt; +    int *picture;<br>&gt;&gt; +    bi.bmiHeader.biSize=sizeof(bi.bmiHeader);<br>&gt;&gt; +    bi.bmiHeader.biWidth=2;<br>&gt;&gt; +    bi.bmiHeader.biHeight=2;<br>
&gt;&gt; +    bi.bmiHeader.biPlanes=1;<br>&gt;&gt; +    bi.bmiHeader.biBitCount=32;<br>&gt;&gt; +    bi.bmiHeader.biCompression=BI_RGB;<br>&gt;&gt; +<br>&gt;&gt; +    /*Get the device context for the screen.*/<br>&gt;&gt; +    hdc=GetDC(NULL);<br>
&gt;&gt; +<br>&gt;&gt; +    /*Create the bottom to top image (image&#39;s bottom scan line is at the<br>&gt;&gt; top in memory).*/<br>&gt;&gt; +    bmpbt=CreateDIBSection(hdc, &amp;bi, DIB_RGB_COLORS, (void**)&amp;picture,<br>
&gt;&gt; NULL, 0);<br>&gt;&gt; +    /*Now that we have a pointer to the pixels, we write to them.*/<br>&gt;&gt; +    picture[0]=1;<br>&gt;&gt; +    picture[1]=2;<br>&gt;&gt; +    picture[2]=3;<br>&gt;&gt; +    picture[3]=4;<br>
&gt;&gt; +    /*Create the top to bottom image (images&#39; bottom scan line is at the<br>&gt;&gt; bottom in memory).*/<br>&gt;&gt; +    bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom<br>&gt;&gt; image by specifying a negative height.*/<br>
&gt;&gt; +    bmptb=CreateDIBSection(hdc, &amp;bi, DIB_RGB_COLORS, (void**)&amp;picture,<br>&gt;&gt; NULL, 0);<br>&gt;&gt; +    /*Write to this top to bottom bitmap.*/<br>&gt;&gt; +    picture[0]=1;<br>&gt;&gt; +    picture[1]=2;<br>
&gt;&gt; +    picture[2]=3;<br>&gt;&gt; +       picture[3]=4;<br>&gt;&gt; +<br>&gt;&gt; +    bi.bmiHeader.biWidth=1;<br>&gt;&gt; +<br>&gt;&gt; +    bi.bmiHeader.biHeight=2;<br>&gt;&gt; +    GetDIBits(hdc, bmpbt, 0, 1, &amp;pixelOut, &amp;bi, DIB_RGB_COLORS);<br>
&gt;&gt; +    ok(pixelOut==1, &quot;Bottom-up -&gt; bottom-up should have first scanline.&quot;);<br>&gt;&gt; +    GetDIBits(hdc, bmptb, 0, 1, &amp;pixelOut, &amp;bi, DIB_RGB_COLORS);<br>&gt;&gt; +    ok(pixelOut==3, &quot;Top-down -&gt; bottom-up should have last scanline.&quot;);<br>
&gt;&gt; +<br>&gt;&gt; +    bi.bmiHeader.biHeight=-2;<br>&gt;&gt; +    GetDIBits(hdc, bmpbt, 0, 1, &amp;pixelOut, &amp;bi, DIB_RGB_COLORS);<br>&gt;&gt; +    ok(pixelOut==1, &quot;Bottom-up -&gt; top-down should have first scanline.&quot;);<br>
&gt;&gt; +    GetDIBits(hdc, bmptb, 0, 1, &amp;pixelOut, &amp;bi, DIB_RGB_COLORS);<br>&gt;&gt; +    ok(pixelOut==3, &quot;Top-down -&gt; top-down should have last scanline.&quot;);<br>&gt;&gt; +<br>&gt;&gt; +    DeleteObject(bmpbt);<br>
&gt;&gt; +    DeleteObject(bmptb);<br>&gt;&gt; +}<br>&gt;&gt; +<br>&gt;&gt;  START_TEST(bitmap)<br>&gt;&gt;  {<br>&gt;&gt;     HMODULE hdll;<br>&gt;&gt; @@ -3080,4 +3190,6 @@ START_TEST(bitmap)<br>&gt;&gt;     test_bitmapinfoheadersize();<br>
&gt;&gt;     test_get16dibits();<br>&gt;&gt;     test_clipping();<br>&gt;&gt; +    test_GetDIBits_single_pixel_destination();<br>&gt;&gt; +    test_GetDIBits_info_query();<br>&gt;&gt;  }<br>&gt;&gt; --<br>&gt;&gt; 1.7.1<br>
&gt;&gt;<br>&gt;&gt;<br>&gt;&gt;<br>&gt;&gt;<br>&gt; Hi Jack,<br>&gt; <br>&gt; You forgot trailing \n in the ok() calls.<br>&gt; <br>&gt; -- <br>&gt; Nicolas Le Cam<br></div>