<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, "Nicolas Le Cam" <<a href="mailto:niko.lecam@gmail.com">niko.lecam@gmail.com</a>> wrote:<br type="attribution">> 2011/2/8 Jack Edmonds <jack@jack-desktop.><br>
> <br>>> Fixes bug 25698 and addresses one of the test cases in bug 24278 (possibly<br>>> resolves bug 24278 but more testing is required to be sure).<br>>><br>>> dib.c: Fills BITMAPINFOHEADER with correct width and height when bits ==<br>
>> NULL and copying from a top-to-bottom bitmap.<br>>> For top-to-bottom bitmaps, reverses the source pointer rather than the<br>>> destination pointer.<br>>> Ignoring the case when both source and destination are top-to-bottom<br>
>> bitmaps and treating this as if the destination is only a top-to-bottom<br>>> bitmap.<br>>> ---<br>>> dlls/gdi32/dib.c | 113<br>>> ++++++++++++++++++++++++---------------------<br>
>> dlls/gdi32/tests/bitmap.c | 112<br>>> ++++++++++++++++++++++++++++++++++++++++++++<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->bcWidth = bmp->bitmap.bmWidth;<br>
>> - coreheader->bcHeight = bmp->bitmap.bmHeight;<br>>> - coreheader->bcPlanes = 1;<br>>> - coreheader->bcBitCount = bmp->bitmap.bmBitsPixel;<br>>> - }<br>
>> - else<br>>> - {<br>>> - info->bmiHeader.biWidth = bmp->bitmap.bmWidth;<br>>> - info->bmiHeader.biHeight = bmp->bitmap.bmHeight;<br>>> - info->bmiHeader.biPlanes = 1;<br>
>> - info->bmiHeader.biSizeImage =<br>>> - DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,<br>>> - bmp->bitmap.bmHeight,<br>>> - bmp->bitmap.bmBitsPixel );<br>
>> - if (bmp->dib)<br>>> - {<br>>> - info->bmiHeader.biBitCount = bmp->dib->dsBm.bmBitsPixel;<br>>> - switch (bmp->dib->dsBm.bmBitsPixel)<br>
>> - {<br>>> - case 16:<br>>> - case 32:<br>>> - info->bmiHeader.biCompression = BI_BITFIELDS;<br>>> - break;<br>
>> - default:<br>>> - info->bmiHeader.biCompression = BI_RGB;<br>>> - break;<br>>> - }<br>>> - }<br>>> - else<br>
>> - {<br>>> - info->bmiHeader.biCompression = (bmp->bitmap.bmBitsPixel ><br>>> 8) ? BI_BITFIELDS : BI_RGB;<br>>> - info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;<br>
>> - }<br>>> - info->bmiHeader.biXPelsPerMeter = 0;<br>>> - info->bmiHeader.biYPelsPerMeter = 0;<br>>> - info->bmiHeader.biClrUsed = 0;<br>>> - info->bmiHeader.biClrImportant = 0;<br>
>> -<br>>> - /* Windows 2000 doesn't touch the additional struct members if<br>>> - it's a BITMAPV4HEADER or a BITMAPV5HEADER */<br>>> - }<br>>> - lines = abs(bmp->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->dib->dsBm.bmBits +<br>
>> (startscan * srcwidthb);<br>>> unsigned int x, y, width, widthb;<br>>><br>>> - if ((height < 0) ^ (bmp->dib->dsBmih.biHeight < 0))<br>>> + if (bmp->dib->dsBmih.biHeight < 0)<br>
>> {<br>>> - dbits = (LPBYTE)bits + (dstwidthb * (lines-1));<br>>> - dstwidthb = -dstwidthb;<br>>> + sbits += (srcwidthb * (abs(bmp->dib->dsBmih.biHeight) -<br>
>> 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->dib)<br>>> + {<br>>> + coreheader->bcWidth = bmp->dib->dsBmih.biWidth;<br>>> + coreheader->bcHeight = bmp->dib->dsBmih.biHeight;<br>
>> + }<br>>> + else<br>>> + {<br>>> + coreheader->bcWidth = bmp->bitmap.bmWidth;<br>>> + coreheader->bcHeight = bmp->bitmap.bmHeight;<br>
>> + }<br>>> + coreheader->bcPlanes = 1;<br>>> + coreheader->bcBitCount = bmp->bitmap.bmBitsPixel;<br>>> + }<br>>> + else<br>>> + {<br>
>> + if (bmp->dib)<br>>> + {<br>>> + info->bmiHeader.biHeight = bmp->dib->dsBmih.biHeight;<br>>> + info->bmiHeader.biWidth = bmp->dib->dsBmih.biWidth;<br>
>> + info->bmiHeader.biBitCount = bmp->dib->dsBm.bmBitsPixel;<br>>> + switch (bmp->dib->dsBm.bmBitsPixel)<br>>> + {<br>>> + case 16:<br>
>> + case 32:<br>>> + info->bmiHeader.biCompression = BI_BITFIELDS;<br>>> + break;<br>>> + default:<br>>> + info->bmiHeader.biCompression = BI_RGB;<br>
>> + break;<br>>> + }<br>>> + }<br>>> + else<br>>> + {<br>>> + info->bmiHeader.biWidth = bmp->bitmap.bmWidth;<br>
>> + info->bmiHeader.biHeight = bmp->bitmap.bmHeight;<br>>> + info->bmiHeader.biCompression = (bmp->bitmap.bmBitsPixel ><br>>> 8) ? BI_BITFIELDS : BI_RGB;<br>
>> + info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;<br>>> + }<br>>> + info->bmiHeader.biPlanes = 1;<br>>> + info->bmiHeader.biSizeImage =<br>
>> + DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,<br>>> + bmp->bitmap.bmHeight,<br>>> + bmp->bitmap.bmBitsPixel );<br>
>> + info->bmiHeader.biXPelsPerMeter = 0;<br>>> + info->bmiHeader.biYPelsPerMeter = 0;<br>>> + info->bmiHeader.biClrUsed = 0;<br>>> + info->bmiHeader.biClrImportant = 0;<br>
>> +<br>>> + /* Windows 2000 doesn't touch the additional struct members if<br>>> + it's a BITMAPV4HEADER or a BITMAPV5HEADER */<br>>> + }<br>>> + lines = abs(bmp->bitmap.bmHeight);<br>
>> + }<br>>><br>>> /* The knowledge base article Q81498 ("DIBs and Their Uses") states<br>>> that<br>>> if bits == NULL and bpp != 0, only biSizeImage and the color table<br>
>> 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, &bi, DIB_RGB_COLORS, (void**)&picture,<br>
>> NULL, 0);<br>>> + /*Clear the structure to make sure that we really are testing that the<br>>> structure is being written to.*/<br>>> + memset(&bi, 0, sizeof(bi));<br>>> + /*Test with a BITMAPINFOHEADER.*/<br>
>> + bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);<br>>> + GetDIBits(hdc, bmp, 0, 0, NULL, &bi, DIB_RGB_COLORS);<br>>> + ok(bi.bmiHeader.biHeight == 2, "Height should be 2.");<br>
>> + ok(bi.bmiHeader.biWidth == 2, "Width should be 2.");<br>>> + /*Clear the structure to make sure that we really are testing that the<br>>> structure is being written to.*/<br>>> + memset(&bi, 0, sizeof(bi));<br>
>> + /*Now test with a BITMAPCOREHEADER.*/<br>>> + bi.bmiHeader.biSize=sizeof(BITMAPCOREHEADER);<br>>> + GetDIBits(hdc, bmp, 0, 0, NULL, &bi, DIB_RGB_COLORS);<br>>> + ok(((BITMAPCOREHEADER*)&bi)->bcHeight == 2, "Height should be 2.");<br>
>> + ok(((BITMAPCOREHEADER*)&bi)->bcWidth == 2, "Width should be 2.");<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, &bi, DIB_RGB_COLORS, (void**)&picture,<br>>> NULL, 0);<br>>> + /*Clear the structure to make sure that we really are testing that the<br>
>> structure is being written to.*/<br>>> + memset(&bi, 0, sizeof(bi));<br>>> + /*Test with a BITMAPINFOHEADER.*/<br>>> + bi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);<br>>> + GetDIBits(hdc, bmp, 0, 0, NULL, &bi, DIB_RGB_COLORS);<br>
>> + ok(bi.bmiHeader.biHeight == -2, "Height should be -2.");<br>>> + ok(bi.bmiHeader.biWidth == 2, "Width should be 2.");<br>>> + /*Clear the structure to make sure that we really are testing that the<br>
>> structure is being written to.*/<br>>> + memset(&bi, 0, sizeof(bi));<br>>> + /*Now test with a BITMAPCOREHEADER.*/<br>>> + bi.bmiHeader.biSize=sizeof(BITMAPCOREHEADER);<br>>> + GetDIBits(hdc, bmp, 0, 0, NULL, &bi, DIB_RGB_COLORS);<br>
>> + ok(((BITMAPCOREHEADER*)&bi)->bcHeight == (WORD)-2, "Height should be<br>>> -2.");<br>>> + ok(((BITMAPCOREHEADER*)&bi)->bcWidth == (WORD)2, "Width should be<br>>> 2.");<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's bottom scan line is at the<br>>> top in memory).*/<br>>> + bmpbt=CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture,<br>
>> 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' bottom scan line is at the<br>>> bottom in memory).*/<br>>> + bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom<br>>> image by specifying a negative height.*/<br>
>> + bmptb=CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture,<br>>> 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, &pixelOut, &bi, DIB_RGB_COLORS);<br>
>> + ok(pixelOut==1, "Bottom-up -> bottom-up should have first scanline.");<br>>> + GetDIBits(hdc, bmptb, 0, 1, &pixelOut, &bi, DIB_RGB_COLORS);<br>>> + ok(pixelOut==3, "Top-down -> bottom-up should have last scanline.");<br>
>> +<br>>> + bi.bmiHeader.biHeight=-2;<br>>> + GetDIBits(hdc, bmpbt, 0, 1, &pixelOut, &bi, DIB_RGB_COLORS);<br>>> + ok(pixelOut==1, "Bottom-up -> top-down should have first scanline.");<br>
>> + GetDIBits(hdc, bmptb, 0, 1, &pixelOut, &bi, DIB_RGB_COLORS);<br>>> + ok(pixelOut==3, "Top-down -> top-down should have last scanline.");<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>>> --<br>>> 1.7.1<br>
>><br>>><br>>><br>>><br>> Hi Jack,<br>> <br>> You forgot trailing \n in the ok() calls.<br>> <br>> -- <br>> Nicolas Le Cam<br></div>