/* Transfer color info */
- if (bpp <= 8 && bpp > 0)
+ switch (bpp)
{
+ case 0: /* query bitmap info only */
+ if (core_header)
+ {
+ BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) info;
+ coreheader->bcWidth = bmp->bitmap.bmWidth;
+ coreheader->bcHeight = bmp->bitmap.bmHeight;
+ coreheader->bcPlanes = 1;
+ coreheader->bcBitCount = bmp->bitmap.bmBitsPixel;
+ }
+ else
+ {
+ info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
+ info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
+ info->bmiHeader.biPlanes = 1;
+ info->bmiHeader.biSizeImage =
+ DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
+ bmp->bitmap.bmHeight,
+ bmp->bitmap.bmBitsPixel );
+ switch(bmp->bitmap.bmBitsPixel)
+ {
+ case 15:
+ info->bmiHeader.biBitCount = 16;
+ info->bmiHeader.biCompression = BI_RGB;
+ break;
+ case 16:
+ info->bmiHeader.biBitCount = 16;
+ info->bmiHeader.biCompression = BI_BITFIELDS;
+ break;
+ default:
+ info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
+ info->bmiHeader.biCompression = BI_RGB;
+ break;
+ }
+ info->bmiHeader.biXPelsPerMeter = 0;
+ info->bmiHeader.biYPelsPerMeter = 0;
+ info->bmiHeader.biClrUsed = 0;
+ info->bmiHeader.biClrImportant = 0;
+
+ /* Windows 2000 doesn't touch the additional struct members if
+ it's a BITMAPV4HEADER or a BITMAPV5HEADER */
+ }
+ lines = abs(bmp->bitmap.bmHeight);
+ goto done;
+
+ case 1:
+ case 4:
+ case 8:
if (!core_header) info->bmiHeader.biClrUsed = 0;
/* If the bitmap object already has a dib section at the
}
}
}
+ break;
+
+ case 15:
+ if (info->bmiHeader.biCompression == BI_BITFIELDS)
+ {
+ ((PDWORD)info->bmiColors)[0] = 0x7c00;
+ ((PDWORD)info->bmiColors)[1] = 0x03e0;
+ ((PDWORD)info->bmiColors)[2] = 0x001f;
+ }
+ break;
+
+ case 16:
+ if (info->bmiHeader.biCompression == BI_BITFIELDS)
+ {
+ ((PDWORD)info->bmiColors)[0] = 0xf800;
+ ((PDWORD)info->bmiColors)[1] = 0x07e0;
+ ((PDWORD)info->bmiColors)[2] = 0x001f;
+ }
+ break;
}
if (bits && lines)
}
}
}
- else
- {
- /* fill in struct members */
-
- if (bpp == 0)
- {
- if (core_header)
- {
- BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) info;
- coreheader->bcWidth = bmp->bitmap.bmWidth;
- coreheader->bcHeight = bmp->bitmap.bmHeight;
- coreheader->bcPlanes = 1;
- coreheader->bcBitCount = bmp->bitmap.bmBitsPixel;
- }
- else
- {
- info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
- info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
- info->bmiHeader.biPlanes = 1;
- info->bmiHeader.biSizeImage =
- DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
- bmp->bitmap.bmHeight,
- bmp->bitmap.bmBitsPixel );
- switch(bmp->bitmap.bmBitsPixel)
- {
- case 15:
- info->bmiHeader.biBitCount = 16;
- info->bmiHeader.biCompression = BI_RGB;
- break;
-
- case 16:
- if (bits)
- {
- /* Add color only when bits is given, as per MSDN */
- ((PDWORD)info->bmiColors)[0] = 0xf800;
- ((PDWORD)info->bmiColors)[1] = 0x07e0;
- ((PDWORD)info->bmiColors)[2] = 0x001f;
- }
- info->bmiHeader.biBitCount = 16;
- info->bmiHeader.biCompression = BI_BITFIELDS;
- break;
-
- default:
- info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
- info->bmiHeader.biCompression = BI_RGB;
- break;
- }
- info->bmiHeader.biXPelsPerMeter = 0;
- info->bmiHeader.biYPelsPerMeter = 0;
- info->bmiHeader.biClrUsed = 0;
- info->bmiHeader.biClrImportant = 0;
-
- /* Windows 2000 doesn't touch the additional struct members if
- it's a BITMAPV4HEADER or a BITMAPV5HEADER */
- }
- lines = abs(bmp->bitmap.bmHeight);
- }
- else
- {
- /* The knowledge base article Q81498 ("DIBs and Their Uses") states that
- if bits == NULL and bpp != 0, only biSizeImage and the color table are
- filled in. */
- if (!core_header)
- {
- /* FIXME: biSizeImage should be calculated according to the selected
- compression algorithm if biCompression != BI_RGB */
- info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes( width, height, bpp );
- }
- lines = abs(height);
- }
- }
+ else lines = abs(height);
+ /* The knowledge base article Q81498 ("DIBs and Their Uses") states that
+ if bits == NULL and bpp != 0, only biSizeImage and the color table are
+ filled in. */
if (!core_header)
{
+ /* FIXME: biSizeImage should be calculated according to the selected
+ compression algorithm if biCompression != BI_RGB */
+ info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes( width, height, bpp );
TRACE("biSizeImage = %d, ", info->bmiHeader.biSizeImage);
}
TRACE("biWidth = %d, biHeight = %d\n", width, height);
+done:
release_dc_ptr( dc );
GDI_ReleaseObj( hbitmap );
return lines;
* for the three primary colors in non-paletted 16 bit mode.
*/
char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
+ DWORD bits[32];
LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
HDC hdc;
HBITMAP hbm;
/* Call GetDIBits to fill in bmiHeader. */
ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
ok(ret == 1, "GetDIBits failed\n");
- if (dibinfo->bmiHeader.biBitCount == 16
- && dibinfo->bmiHeader.biCompression == BI_BITFIELDS) {
- /* In the BITMAPINFOHEADER doc, this little struct is implicit.
- * Making explicit for clarity.
- */
- struct bi_bitfields_s {
- DWORD red;
- DWORD blue;
- DWORD green;
- } *bitmasks;
-
- /* Retrieve the BI_BITFIELDS info (requires second call, honest). */
- ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
- ok(ret == 1, "GetDIBits failed\n");
-
- bitmasks = (struct bi_bitfields_s *) dibinfo->bmiColors;
- todo_wine {
- ok(bitmasks->red != 0, "expected space for red pixels\n");
- ok(bitmasks->blue != 0, "expected space for blue pixels\n");
- ok(bitmasks->green != 0, "expected space for green pixels\n");
- }
- } else {
- skip("not in 16 bpp BI_BITFIELDS mode, skipping that test\n");
+ if (dibinfo->bmiHeader.biBitCount == 16 &&
+ dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
+ {
+ DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
+
+ ok( !bitmasks[0], "red mask is set\n" );
+ ok( !bitmasks[1], "green mask is set\n" );
+ ok( !bitmasks[2], "blue mask is set\n" );
+
+ /* test with NULL bits pointer and correct bpp */
+ dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
+ ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
+ ok(ret == 1, "GetDIBits failed\n");
+
+ ok( bitmasks[0] != 0, "red mask is not set\n" );
+ ok( bitmasks[1] != 0, "green mask is not set\n" );
+ ok( bitmasks[2] != 0, "blue mask is not set\n" );
+ ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
+
+ /* test with valid bits pointer */
+ memset(dibinfo, 0, sizeof(dibinfo_buf));
+ dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
+ ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
+ dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
+ ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
+ ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
+
+ ok( bitmasks[0] != 0, "red mask is not set\n" );
+ ok( bitmasks[1] != 0, "green mask is not set\n" );
+ ok( bitmasks[2] != 0, "blue mask is not set\n" );
+ ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
+
+ /* now with bits and 0 lines */
+ memset(dibinfo, 0, sizeof(dibinfo_buf));
+ dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
+ ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
+
+ ok( !bitmasks[0], "red mask is set\n" );
+ ok( !bitmasks[1], "green mask is set\n" );
+ ok( !bitmasks[2], "blue mask is set\n" );
+ ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
+
+ memset(bitmasks, 0, 3*sizeof(DWORD));
+ dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
+ ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
+ ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
+
+ ok( bitmasks[0] != 0, "red mask is not set\n" );
+ ok( bitmasks[1] != 0, "green mask is not set\n" );
+ ok( bitmasks[2] != 0, "blue mask is not set\n" );
+ ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
}
+ else skip("not in 16 bpp BI_BITFIELDS mode, skipping that test\n");
DeleteObject(hbm);
ReleaseDC(NULL, hdc);