<div class="gmail_quote">2011/2/8 Jack Edmonds <span dir="ltr">&lt;jack@jack-desktop.&gt;</span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">Fixes bug 25698 and addresses one of the test cases in bug 24278 (possibly resolves bug 24278 but more testing is required to be sure).<br>

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