2 * Unit test suite for bitmaps
4 * Copyright 2004 Huw Davies
5 * Copyright 2006 Dmitry Timoshkov
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
32 #include "wine/test.h"
36 static INT
BITMAP_GetWidthBytes( INT bmWidth
, INT bpp
)
41 return 2 * ((bmWidth
+15) >> 4);
44 bmWidth
*= 3; /* fall through */
46 return bmWidth
+ (bmWidth
& 1);
56 return 2 * ((bmWidth
+3) >> 2);
59 trace("Unknown depth %d, please report.\n", bpp
);
65 static void test_bitmap_info(HBITMAP hbm
, INT expected_depth
, const BITMAPINFOHEADER
*bmih
)
69 char buf
[512], buf_cmp
[512];
71 ret
= GetObject(hbm
, sizeof(bm
), &bm
);
72 ok(ret
== sizeof(bm
), "GetObject returned %d\n", ret
);
74 ok(bm
.bmType
== 0, "wrong bm.bmType %d\n", bm
.bmType
);
75 ok(bm
.bmWidth
== bmih
->biWidth
, "wrong bm.bmWidth %d\n", bm
.bmWidth
);
76 ok(bm
.bmHeight
== bmih
->biHeight
, "wrong bm.bmHeight %d\n", bm
.bmHeight
);
77 width_bytes
= BITMAP_GetWidthBytes(bm
.bmWidth
, bm
.bmBitsPixel
);
78 ok(bm
.bmWidthBytes
== width_bytes
, "wrong bm.bmWidthBytes %d != %d\n", bm
.bmWidthBytes
, width_bytes
);
79 ok(bm
.bmPlanes
== bmih
->biPlanes
, "wrong bm.bmPlanes %d\n", bm
.bmPlanes
);
80 ok(bm
.bmBitsPixel
== expected_depth
, "wrong bm.bmBitsPixel %d != %d\n", bm
.bmBitsPixel
, expected_depth
);
81 ok(bm
.bmBits
== NULL
, "wrong bm.bmBits %p\n", bm
.bmBits
);
83 assert(sizeof(buf
) >= bm
.bmWidthBytes
* bm
.bmHeight
);
84 assert(sizeof(buf
) == sizeof(buf_cmp
));
86 ret
= GetBitmapBits(hbm
, 0, NULL
);
87 ok(ret
== bm
.bmWidthBytes
* bm
.bmHeight
, "%d != %d\n", ret
, bm
.bmWidthBytes
* bm
.bmHeight
);
89 memset(buf_cmp
, 0xAA, sizeof(buf_cmp
));
90 memset(buf_cmp
, 0, bm
.bmWidthBytes
* bm
.bmHeight
);
92 memset(buf
, 0xAA, sizeof(buf
));
93 ret
= GetBitmapBits(hbm
, sizeof(buf
), buf
);
94 ok(ret
== bm
.bmWidthBytes
* bm
.bmHeight
, "%d != %d\n", ret
, bm
.bmWidthBytes
* bm
.bmHeight
);
95 ok(!memcmp(buf
, buf_cmp
, sizeof(buf
)), "buffers do not match\n");
97 /* test various buffer sizes for GetObject */
98 ret
= GetObject(hbm
, 0, NULL
);
99 ok(ret
== sizeof(bm
), "wrong size %d\n", ret
);
101 ret
= GetObject(hbm
, sizeof(bm
) * 2, &bm
);
102 ok(ret
== sizeof(bm
), "wrong size %d\n", ret
);
104 ret
= GetObject(hbm
, sizeof(bm
) / 2, &bm
);
105 ok(ret
== 0, "%d != 0\n", ret
);
107 ret
= GetObject(hbm
, 0, &bm
);
108 ok(ret
== 0, "%d != 0\n", ret
);
110 ret
= GetObject(hbm
, 1, &bm
);
111 ok(ret
== 0, "%d != 0\n", ret
);
114 static void test_createdibitmap(void)
117 BITMAPINFOHEADER bmih
;
118 HBITMAP hbm
, hbm_colour
, hbm_old
;
122 screen_depth
= GetDeviceCaps(hdc
, BITSPIXEL
);
123 memset(&bmih
, 0, sizeof(bmih
));
124 bmih
.biSize
= sizeof(bmih
);
128 bmih
.biBitCount
= 32;
129 bmih
.biCompression
= BI_RGB
;
131 /* First create an un-initialised bitmap. The depth of the bitmap
132 should match that of the hdc and not that supplied in bmih.
135 /* First try 32 bits */
136 hbm
= CreateDIBitmap(hdc
, &bmih
, 0, NULL
, NULL
, 0);
137 ok(hbm
!= NULL
, "CreateDIBitmap failed\n");
138 test_bitmap_info(hbm
, screen_depth
, &bmih
);
142 bmih
.biBitCount
= 16;
143 hbm
= CreateDIBitmap(hdc
, &bmih
, 0, NULL
, NULL
, 0);
144 ok(hbm
!= NULL
, "CreateDIBitmap failed\n");
145 test_bitmap_info(hbm
, screen_depth
, &bmih
);
150 hbm
= CreateDIBitmap(hdc
, &bmih
, 0, NULL
, NULL
, 0);
151 ok(hbm
!= NULL
, "CreateDIBitmap failed\n");
152 test_bitmap_info(hbm
, screen_depth
, &bmih
);
155 /* Now with a monochrome dc we expect a monochrome bitmap */
156 hdcmem
= CreateCompatibleDC(hdc
);
158 /* First try 32 bits */
159 bmih
.biBitCount
= 32;
160 hbm
= CreateDIBitmap(hdcmem
, &bmih
, 0, NULL
, NULL
, 0);
161 ok(hbm
!= NULL
, "CreateDIBitmap failed\n");
162 test_bitmap_info(hbm
, 1, &bmih
);
166 bmih
.biBitCount
= 16;
167 hbm
= CreateDIBitmap(hdcmem
, &bmih
, 0, NULL
, NULL
, 0);
168 ok(hbm
!= NULL
, "CreateDIBitmap failed\n");
169 test_bitmap_info(hbm
, 1, &bmih
);
174 hbm
= CreateDIBitmap(hdcmem
, &bmih
, 0, NULL
, NULL
, 0);
175 ok(hbm
!= NULL
, "CreateDIBitmap failed\n");
176 test_bitmap_info(hbm
, 1, &bmih
);
179 /* Now select a polychrome bitmap into the dc and we expect
180 screen_depth bitmaps again */
181 hbm_colour
= CreateCompatibleBitmap(hdc
, 1, 1);
182 hbm_old
= SelectObject(hdcmem
, hbm_colour
);
184 /* First try 32 bits */
185 bmih
.biBitCount
= 32;
186 hbm
= CreateDIBitmap(hdcmem
, &bmih
, 0, NULL
, NULL
, 0);
187 ok(hbm
!= NULL
, "CreateDIBitmap failed\n");
188 test_bitmap_info(hbm
, screen_depth
, &bmih
);
192 bmih
.biBitCount
= 16;
193 hbm
= CreateDIBitmap(hdcmem
, &bmih
, 0, NULL
, NULL
, 0);
194 ok(hbm
!= NULL
, "CreateDIBitmap failed\n");
195 test_bitmap_info(hbm
, screen_depth
, &bmih
);
200 hbm
= CreateDIBitmap(hdcmem
, &bmih
, 0, NULL
, NULL
, 0);
201 ok(hbm
!= NULL
, "CreateDIBitmap failed\n");
202 test_bitmap_info(hbm
, screen_depth
, &bmih
);
205 SelectObject(hdcmem
, hbm_old
);
206 DeleteObject(hbm_colour
);
209 /* If hdc == 0 then we get a 1 bpp bitmap */
211 bmih
.biBitCount
= 32;
212 hbm
= CreateDIBitmap(0, &bmih
, 0, NULL
, NULL
, 0);
213 ok(hbm
!= NULL
, "CreateDIBitmap failed\n");
214 test_bitmap_info(hbm
, 1, &bmih
);
221 static INT
DIB_GetWidthBytes( int width
, int bpp
)
227 case 1: words
= (width
+ 31) / 32; break;
228 case 4: words
= (width
+ 7) / 8; break;
229 case 8: words
= (width
+ 3) / 4; break;
231 case 16: words
= (width
+ 1) / 2; break;
232 case 24: words
= (width
* 3 + 3)/4; break;
233 case 32: words
= width
; break;
237 trace("Unknown depth %d, please report.\n", bpp
);
244 static void test_dib_info(HBITMAP hbm
, const void *bits
, const BITMAPINFOHEADER
*bmih
)
248 INT ret
, width_bytes
;
251 ret
= GetObject(hbm
, sizeof(bm
), &bm
);
252 ok(ret
== sizeof(bm
), "GetObject returned %d\n", ret
);
254 ok(bm
.bmType
== 0, "wrong bm.bmType %d\n", bm
.bmType
);
255 ok(bm
.bmWidth
== bmih
->biWidth
, "wrong bm.bmWidth %d\n", bm
.bmWidth
);
256 ok(bm
.bmHeight
== bmih
->biHeight
, "wrong bm.bmHeight %d\n", bm
.bmHeight
);
257 width_bytes
= DIB_GetWidthBytes(bm
.bmWidth
, bm
.bmBitsPixel
);
258 ok(bm
.bmWidthBytes
== width_bytes
, "wrong bm.bmWidthBytes %d != %d\n", bm
.bmWidthBytes
, width_bytes
);
259 ok(bm
.bmPlanes
== bmih
->biPlanes
, "wrong bm.bmPlanes %d\n", bm
.bmPlanes
);
260 ok(bm
.bmBitsPixel
== bmih
->biBitCount
, "bm.bmBitsPixel %d != %d\n", bm
.bmBitsPixel
, bmih
->biBitCount
);
261 ok(bm
.bmBits
== bits
, "wrong bm.bmBits %p != %p\n", bm
.bmBits
, bits
);
263 buf
= HeapAlloc(GetProcessHeap(), 0, bm
.bmWidthBytes
* bm
.bmHeight
+ 4096);
265 width_bytes
= BITMAP_GetWidthBytes(bm
.bmWidth
, bm
.bmBitsPixel
);
267 /* GetBitmapBits returns not 32-bit aligned data */
268 ret
= GetBitmapBits(hbm
, 0, NULL
);
269 ok(ret
== width_bytes
* bm
.bmHeight
, "%d != %d\n", ret
, width_bytes
* bm
.bmHeight
);
271 memset(buf
, 0xAA, bm
.bmWidthBytes
* bm
.bmHeight
+ 4096);
272 ret
= GetBitmapBits(hbm
, bm
.bmWidthBytes
* bm
.bmHeight
+ 4096, buf
);
273 ok(ret
== width_bytes
* bm
.bmHeight
, "%d != %d\n", ret
, width_bytes
* bm
.bmHeight
);
275 HeapFree(GetProcessHeap(), 0, buf
);
277 /* test various buffer sizes for GetObject */
278 memset(&ds
, 0xAA, sizeof(ds
));
279 ret
= GetObject(hbm
, sizeof(bm
) * 2, &bm
);
280 ok(ret
== sizeof(bm
), "wrong size %d\n", ret
);
281 ok(bm
.bmWidth
== bmih
->biWidth
, "wrong bm.bmWidth %d\n", bm
.bmWidth
);
282 ok(bm
.bmHeight
== bmih
->biHeight
, "wrong bm.bmHeight %d\n", bm
.bmHeight
);
283 ok(bm
.bmBits
== bits
, "wrong bm.bmBits %p != %p\n", bm
.bmBits
, bits
);
285 ret
= GetObject(hbm
, sizeof(bm
) / 2, &bm
);
286 ok(ret
== 0, "%d != 0\n", ret
);
288 ret
= GetObject(hbm
, 0, &bm
);
289 ok(ret
== 0, "%d != 0\n", ret
);
291 ret
= GetObject(hbm
, 1, &bm
);
292 ok(ret
== 0, "%d != 0\n", ret
);
294 /* test various buffer sizes for GetObject */
295 ret
= GetObject(hbm
, 0, NULL
);
296 ok(ret
== sizeof(bm
), "wrong size %d\n", ret
);
298 memset(&ds
, 0xAA, sizeof(ds
));
299 ret
= GetObject(hbm
, sizeof(ds
) * 2, &ds
);
300 ok(ret
== sizeof(ds
), "wrong size %d\n", ret
);
302 ok(ds
.dsBm
.bmBits
== bits
, "wrong bm.bmBits %p != %p\n", ds
.dsBm
.bmBits
, bits
);
303 ok(ds
.dsBmih
.biSizeImage
== ds
.dsBm
.bmWidthBytes
* ds
.dsBm
.bmHeight
, "%lu != %u\n",
304 ds
.dsBmih
.biSizeImage
, ds
.dsBm
.bmWidthBytes
* ds
.dsBm
.bmHeight
);
305 ok(bmih
->biSizeImage
== 0, "%lu != 0\n", bmih
->biSizeImage
);
306 ds
.dsBmih
.biSizeImage
= 0;
308 ok(ds
.dsBmih
.biSize
== bmih
->biSize
, "%lu != %lu\n", ds
.dsBmih
.biSize
, bmih
->biSize
);
309 ok(ds
.dsBmih
.biWidth
== bmih
->biWidth
, "%lu != %lu\n", ds
.dsBmih
.biWidth
, bmih
->biWidth
);
310 ok(ds
.dsBmih
.biHeight
== bmih
->biHeight
, "%lu != %lu\n", ds
.dsBmih
.biHeight
, bmih
->biHeight
);
311 ok(ds
.dsBmih
.biPlanes
== bmih
->biPlanes
, "%u != %u\n", ds
.dsBmih
.biPlanes
, bmih
->biPlanes
);
312 ok(ds
.dsBmih
.biBitCount
== bmih
->biBitCount
, "%u != %u\n", ds
.dsBmih
.biBitCount
, bmih
->biBitCount
);
313 ok(ds
.dsBmih
.biCompression
== bmih
->biCompression
, "%lu != %lu\n", ds
.dsBmih
.biCompression
, bmih
->biCompression
);
314 ok(ds
.dsBmih
.biSizeImage
== bmih
->biSizeImage
, "%lu != %lu\n", ds
.dsBmih
.biSizeImage
, bmih
->biSizeImage
);
315 ok(ds
.dsBmih
.biXPelsPerMeter
== bmih
->biXPelsPerMeter
, "%lu != %lu\n", ds
.dsBmih
.biXPelsPerMeter
, bmih
->biXPelsPerMeter
);
316 ok(ds
.dsBmih
.biYPelsPerMeter
== bmih
->biYPelsPerMeter
, "%lu != %lu\n", ds
.dsBmih
.biYPelsPerMeter
, bmih
->biYPelsPerMeter
);
318 memset(&ds
, 0xAA, sizeof(ds
));
319 ret
= GetObject(hbm
, sizeof(ds
) - 4, &ds
);
320 ok(ret
== sizeof(ds
.dsBm
), "wrong size %d\n", ret
);
321 ok(ds
.dsBm
.bmWidth
== bmih
->biWidth
, "%lu != %lu\n", ds
.dsBmih
.biWidth
, bmih
->biWidth
);
322 ok(ds
.dsBm
.bmHeight
== bmih
->biHeight
, "%lu != %lu\n", ds
.dsBmih
.biHeight
, bmih
->biHeight
);
323 ok(ds
.dsBm
.bmBits
== bits
, "%p != %p\n", ds
.dsBm
.bmBits
, bits
);
325 ret
= GetObject(hbm
, 0, &ds
);
326 ok(ret
== 0, "%d != 0\n", ret
);
328 ret
= GetObject(hbm
, 1, &ds
);
329 ok(ret
== 0, "%d != 0\n", ret
);
332 #define test_color_todo(got, exp, txt, todo) \
333 if (!todo && got != exp && screen_depth < 24) { \
334 todo_wine ok(0, #txt " failed at %d-bit screen depth: got 0x%06x expected 0x%06x - skipping DIB tests\n", \
335 screen_depth, (UINT)got, (UINT)exp); \
337 } else if (todo) todo_wine { ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp); } \
338 else ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp) \
340 #define test_color(hdc, color, exp, todo_setp, todo_getp) \
343 c = SetPixel(hdc, 0, 0, color); \
344 if (!is_win9x) { test_color_todo(c, exp, SetPixel, todo_setp); } \
345 c = GetPixel(hdc, 0, 0); \
346 test_color_todo(c, exp, GetPixel, todo_getp); \
349 static void test_dibsections(void)
351 HDC hdc
, hdcmem
, hdcmem2
;
352 HBITMAP hdib
, oldbm
, hdib2
, oldbm2
;
353 char bmibuf
[sizeof(BITMAPINFO
) + 256 * sizeof(RGBQUAD
)];
354 char bcibuf
[sizeof(BITMAPCOREINFO
) + 256 * sizeof(RGBTRIPLE
)];
355 BITMAPINFO
*pbmi
= (BITMAPINFO
*)bmibuf
;
356 BITMAPCOREINFO
*pbci
= (BITMAPCOREINFO
*)bcibuf
;
362 char logpalbuf
[sizeof(LOGPALETTE
) + 256 * sizeof(PALETTEENTRY
)];
363 LOGPALETTE
*plogpal
= (LOGPALETTE
*)logpalbuf
;
366 HPALETTE hpal
, oldpal
;
371 MEMORY_BASIC_INFORMATION info
;
374 screen_depth
= GetDeviceCaps(hdc
, BITSPIXEL
) * GetDeviceCaps(hdc
, PLANES
);
376 memset(pbmi
, 0, sizeof(bmibuf
));
377 pbmi
->bmiHeader
.biSize
= sizeof(pbmi
->bmiHeader
);
378 pbmi
->bmiHeader
.biHeight
= 100;
379 pbmi
->bmiHeader
.biWidth
= 512;
380 pbmi
->bmiHeader
.biBitCount
= 24;
381 pbmi
->bmiHeader
.biPlanes
= 1;
382 pbmi
->bmiHeader
.biCompression
= BI_RGB
;
384 SetLastError(0xdeadbeef);
385 hdib
= CreateDIBSection(hdc
, pbmi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
386 ok(hdib
!= NULL
, "CreateDIBSection error %ld\n", GetLastError());
387 ok(GetObject(hdib
, sizeof(DIBSECTION
), &dibsec
) != 0, "GetObject failed for DIBSection\n");
388 ok(dibsec
.dsBm
.bmBits
== bits
, "dibsec.dsBits %p != bits %p\n", dibsec
.dsBm
.bmBits
, bits
);
390 /* test the DIB memory */
391 ok(VirtualQuery(bits
, &info
, sizeof(info
)) == sizeof(info
),
392 "VirtualQuery failed\n");
393 ok(info
.BaseAddress
== bits
, "%p != %p\n", info
.BaseAddress
, bits
);
394 ok(info
.AllocationBase
== bits
, "%p != %p\n", info
.AllocationBase
, bits
);
395 ok(info
.AllocationProtect
== PAGE_READWRITE
, "%lx != PAGE_READWRITE\n", info
.AllocationProtect
);
396 ok(info
.RegionSize
== 0x26000, "0x%lx != 0x26000\n", info
.RegionSize
);
397 ok(info
.State
== MEM_COMMIT
, "%lx != MEM_COMMIT\n", info
.State
);
398 ok(info
.Protect
== PAGE_READWRITE
, "%lx != PAGE_READWRITE\n", info
.Protect
);
399 ok(info
.Type
== MEM_PRIVATE
, "%lx != MEM_PRIVATE\n", info
.Type
);
401 test_dib_info(hdib
, bits
, &pbmi
->bmiHeader
);
404 pbmi
->bmiHeader
.biBitCount
= 8;
405 pbmi
->bmiHeader
.biCompression
= BI_RLE8
;
406 SetLastError(0xdeadbeef);
407 hdib
= CreateDIBSection(hdc
, pbmi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
408 ok(hdib
== NULL
, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
409 ok(GetLastError() == 0xdeadbeef, "wrong error %ld\n", GetLastError());
411 pbmi
->bmiHeader
.biBitCount
= 16;
412 pbmi
->bmiHeader
.biCompression
= BI_BITFIELDS
;
413 ((PDWORD
)pbmi
->bmiColors
)[0] = 0xf800;
414 ((PDWORD
)pbmi
->bmiColors
)[1] = 0x07e0;
415 ((PDWORD
)pbmi
->bmiColors
)[2] = 0x001f;
416 SetLastError(0xdeadbeef);
417 hdib
= CreateDIBSection(hdc
, pbmi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
418 ok(hdib
!= NULL
, "CreateDIBSection error %ld\n", GetLastError());
420 /* test the DIB memory */
421 ok(VirtualQuery(bits
, &info
, sizeof(info
)) == sizeof(info
),
422 "VirtualQuery failed\n");
423 ok(info
.BaseAddress
== bits
, "%p != %p\n", info
.BaseAddress
, bits
);
424 ok(info
.AllocationBase
== bits
, "%p != %p\n", info
.AllocationBase
, bits
);
425 ok(info
.AllocationProtect
== PAGE_READWRITE
, "%lx != PAGE_READWRITE\n", info
.AllocationProtect
);
426 ok(info
.RegionSize
== 0x19000, "0x%lx != 0x19000\n", info
.RegionSize
);
427 ok(info
.State
== MEM_COMMIT
, "%lx != MEM_COMMIT\n", info
.State
);
428 ok(info
.Protect
== PAGE_READWRITE
, "%lx != PAGE_READWRITE\n", info
.Protect
);
429 ok(info
.Type
== MEM_PRIVATE
, "%lx != MEM_PRIVATE\n", info
.Type
);
431 test_dib_info(hdib
, bits
, &pbmi
->bmiHeader
);
434 memset(pbmi
, 0, sizeof(bmibuf
));
435 pbmi
->bmiHeader
.biSize
= sizeof(pbmi
->bmiHeader
);
436 pbmi
->bmiHeader
.biHeight
= 16;
437 pbmi
->bmiHeader
.biWidth
= 16;
438 pbmi
->bmiHeader
.biBitCount
= 1;
439 pbmi
->bmiHeader
.biPlanes
= 1;
440 pbmi
->bmiHeader
.biCompression
= BI_RGB
;
441 pbmi
->bmiColors
[0].rgbRed
= 0xff;
442 pbmi
->bmiColors
[0].rgbGreen
= 0;
443 pbmi
->bmiColors
[0].rgbBlue
= 0;
444 pbmi
->bmiColors
[1].rgbRed
= 0;
445 pbmi
->bmiColors
[1].rgbGreen
= 0;
446 pbmi
->bmiColors
[1].rgbBlue
= 0xff;
448 hdib
= CreateDIBSection(hdc
, pbmi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
449 ok(hdib
!= NULL
, "CreateDIBSection failed\n");
450 ok(GetObject(hdib
, sizeof(DIBSECTION
), &dibsec
) != 0, "GetObject failed for DIBSection\n");
451 ok(dibsec
.dsBmih
.biClrUsed
== 2,
452 "created DIBSection: wrong biClrUsed field: %lu, should be: %u\n", dibsec
.dsBmih
.biClrUsed
, 2);
454 /* Test if the old BITMAPCOREINFO structure is supported */
456 pbci
->bmciHeader
.bcSize
= sizeof(BITMAPCOREHEADER
);
457 pbci
->bmciHeader
.bcBitCount
= 0;
460 ret
= GetDIBits(hdc
, hdib
, 0, 16, NULL
, (BITMAPINFO
*) pbci
, DIB_RGB_COLORS
);
461 ok(ret
, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
462 ok((pbci
->bmciHeader
.bcWidth
== 16) && (pbci
->bmciHeader
.bcHeight
== 16)
463 && (pbci
->bmciHeader
.bcBitCount
== 1) && (pbci
->bmciHeader
.bcPlanes
== 1),
464 "GetDIBits did't fill in the BITMAPCOREHEADER structure properly\n");
466 ret
= GetDIBits(hdc
, hdib
, 0, 16, &coreBits
, (BITMAPINFO
*) pbci
, DIB_RGB_COLORS
);
467 ok(ret
, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
468 ok((pbci
->bmciColors
[0].rgbtRed
== 0xff) && (pbci
->bmciColors
[0].rgbtGreen
== 0) &&
469 (pbci
->bmciColors
[0].rgbtBlue
== 0) && (pbci
->bmciColors
[1].rgbtRed
== 0) &&
470 (pbci
->bmciColors
[1].rgbtGreen
== 0) && (pbci
->bmciColors
[1].rgbtBlue
== 0xff),
471 "The color table has not been translated to the old BITMAPCOREINFO format\n");
473 hcoredib
= CreateDIBSection(hdc
, (BITMAPINFO
*) pbci
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
474 ok(hcoredib
!= NULL
, "CreateDIBSection failed with a BITMAPCOREINFO\n");
476 ZeroMemory(pbci
->bmciColors
, 256 * sizeof(RGBTRIPLE
));
477 ret
= GetDIBits(hdc
, hcoredib
, 0, 16, &coreBits
, (BITMAPINFO
*) pbci
, DIB_RGB_COLORS
);
478 ok(ret
, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
479 ok((pbci
->bmciColors
[0].rgbtRed
== 0xff) && (pbci
->bmciColors
[0].rgbtGreen
== 0) &&
480 (pbci
->bmciColors
[0].rgbtBlue
== 0) && (pbci
->bmciColors
[1].rgbtRed
== 0) &&
481 (pbci
->bmciColors
[1].rgbtGreen
== 0) && (pbci
->bmciColors
[1].rgbtBlue
== 0xff),
482 "The color table has not been translated to the old BITMAPCOREINFO format\n");
484 DeleteObject(hcoredib
);
487 hdcmem
= CreateCompatibleDC(hdc
);
488 oldbm
= SelectObject(hdcmem
, hdib
);
490 ret
= GetDIBColorTable(hdcmem
, 0, 2, rgb
);
491 ok(ret
== 2, "GetDIBColorTable returned %d\n", ret
);
492 ok(!memcmp(rgb
, pbmi
->bmiColors
, 2 * sizeof(RGBQUAD
)),
493 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
494 rgb
[0].rgbRed
, rgb
[0].rgbGreen
, rgb
[0].rgbBlue
, rgb
[0].rgbReserved
,
495 rgb
[1].rgbRed
, rgb
[1].rgbGreen
, rgb
[1].rgbBlue
, rgb
[1].rgbReserved
);
497 c0
= RGB(pbmi
->bmiColors
[0].rgbRed
, pbmi
->bmiColors
[0].rgbGreen
, pbmi
->bmiColors
[0].rgbBlue
);
498 c1
= RGB(pbmi
->bmiColors
[1].rgbRed
, pbmi
->bmiColors
[1].rgbGreen
, pbmi
->bmiColors
[1].rgbBlue
);
500 test_color(hdcmem
, DIBINDEX(0), c0
, 0, 1);
501 test_color(hdcmem
, DIBINDEX(1), c1
, 0, 1);
502 test_color(hdcmem
, DIBINDEX(2), c0
, 1, 1);
503 test_color(hdcmem
, PALETTEINDEX(0), c0
, 1, 1);
504 test_color(hdcmem
, PALETTEINDEX(1), c0
, 1, 1);
505 test_color(hdcmem
, PALETTEINDEX(2), c0
, 1, 1);
506 test_color(hdcmem
, PALETTERGB(pbmi
->bmiColors
[0].rgbRed
, pbmi
->bmiColors
[0].rgbGreen
,
507 pbmi
->bmiColors
[0].rgbBlue
), c0
, 1, 1);
508 test_color(hdcmem
, PALETTERGB(pbmi
->bmiColors
[1].rgbRed
, pbmi
->bmiColors
[1].rgbGreen
,
509 pbmi
->bmiColors
[1].rgbBlue
), c1
, 1, 1);
510 test_color(hdcmem
, PALETTERGB(0, 0, 0), c0
, 1, 1);
511 test_color(hdcmem
, PALETTERGB(0xff, 0xff, 0xff), c0
, 1, 1);
512 test_color(hdcmem
, PALETTERGB(0, 0, 0xfe), c1
, 1, 1);
514 SelectObject(hdcmem
, oldbm
);
517 pbmi
->bmiColors
[0].rgbRed
= 0xff;
518 pbmi
->bmiColors
[0].rgbGreen
= 0xff;
519 pbmi
->bmiColors
[0].rgbBlue
= 0xff;
520 pbmi
->bmiColors
[1].rgbRed
= 0;
521 pbmi
->bmiColors
[1].rgbGreen
= 0;
522 pbmi
->bmiColors
[1].rgbBlue
= 0;
524 hdib
= CreateDIBSection(hdc
, pbmi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
525 ok(hdib
!= NULL
, "CreateDIBSection failed\n");
527 test_dib_info(hdib
, bits
, &pbmi
->bmiHeader
);
529 oldbm
= SelectObject(hdcmem
, hdib
);
531 ret
= GetDIBColorTable(hdcmem
, 0, 2, rgb
);
532 ok(ret
== 2, "GetDIBColorTable returned %d\n", ret
);
533 ok(!memcmp(rgb
, pbmi
->bmiColors
, 2 * sizeof(RGBQUAD
)),
534 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
535 rgb
[0].rgbRed
, rgb
[0].rgbGreen
, rgb
[0].rgbBlue
, rgb
[0].rgbReserved
,
536 rgb
[1].rgbRed
, rgb
[1].rgbGreen
, rgb
[1].rgbBlue
, rgb
[1].rgbReserved
);
538 SelectObject(hdcmem
, oldbm
);
539 test_dib_info(hdib
, bits
, &pbmi
->bmiHeader
);
542 pbmi
->bmiHeader
.biBitCount
= 4;
543 for (i
= 0; i
< 16; i
++) {
544 pbmi
->bmiColors
[i
].rgbRed
= i
;
545 pbmi
->bmiColors
[i
].rgbGreen
= 16-i
;
546 pbmi
->bmiColors
[i
].rgbBlue
= 0;
548 hdib
= CreateDIBSection(hdcmem
, pbmi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
549 ok(hdib
!= NULL
, "CreateDIBSection failed\n");
550 ok(GetObject(hdib
, sizeof(DIBSECTION
), &dibsec
) != 0, "GetObject failed for DIB Section\n");
551 ok(dibsec
.dsBmih
.biClrUsed
== 16,
552 "created DIBSection: wrong biClrUsed field: %lu, should be: %u\n", dibsec
.dsBmih
.biClrUsed
, 16);
553 test_dib_info(hdib
, bits
, &pbmi
->bmiHeader
);
556 pbmi
->bmiHeader
.biBitCount
= 8;
558 for (i
= 0; i
< 128; i
++) {
559 pbmi
->bmiColors
[i
].rgbRed
= 255 - i
* 2;
560 pbmi
->bmiColors
[i
].rgbGreen
= i
* 2;
561 pbmi
->bmiColors
[i
].rgbBlue
= 0;
562 pbmi
->bmiColors
[255 - i
].rgbRed
= 0;
563 pbmi
->bmiColors
[255 - i
].rgbGreen
= i
* 2;
564 pbmi
->bmiColors
[255 - i
].rgbBlue
= 255 - i
* 2;
566 hdib
= CreateDIBSection(hdcmem
, pbmi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
567 ok(hdib
!= NULL
, "CreateDIBSection failed\n");
568 ok(GetObject(hdib
, sizeof(DIBSECTION
), &dibsec
) != 0, "GetObject failed for DIB Section\n");
569 ok(dibsec
.dsBmih
.biClrUsed
== 256,
570 "created DIBSection: wrong biClrUsed field: %lu, should be: %u\n", dibsec
.dsBmih
.biClrUsed
, 256);
572 oldbm
= SelectObject(hdcmem
, hdib
);
574 for (i
= 0; i
< 256; i
++) {
575 test_color(hdcmem
, DIBINDEX(i
),
576 RGB(pbmi
->bmiColors
[i
].rgbRed
, pbmi
->bmiColors
[i
].rgbGreen
, pbmi
->bmiColors
[i
].rgbBlue
), 0, 0);
577 test_color(hdcmem
, PALETTERGB(pbmi
->bmiColors
[i
].rgbRed
, pbmi
->bmiColors
[i
].rgbGreen
, pbmi
->bmiColors
[i
].rgbBlue
),
578 RGB(pbmi
->bmiColors
[i
].rgbRed
, pbmi
->bmiColors
[i
].rgbGreen
, pbmi
->bmiColors
[i
].rgbBlue
), 0, 0);
581 SelectObject(hdcmem
, oldbm
);
582 test_dib_info(hdib
, bits
, &pbmi
->bmiHeader
);
585 pbmi
->bmiHeader
.biBitCount
= 1;
587 /* Now create a palette and a palette indexed dib section */
588 memset(plogpal
, 0, sizeof(logpalbuf
));
589 plogpal
->palVersion
= 0x300;
590 plogpal
->palNumEntries
= 2;
591 plogpal
->palPalEntry
[0].peRed
= 0xff;
592 plogpal
->palPalEntry
[0].peBlue
= 0xff;
593 plogpal
->palPalEntry
[1].peGreen
= 0xff;
595 index
= (WORD
*)pbmi
->bmiColors
;
598 hpal
= CreatePalette(plogpal
);
599 ok(hpal
!= NULL
, "CreatePalette failed\n");
600 oldpal
= SelectPalette(hdc
, hpal
, TRUE
);
601 hdib
= CreateDIBSection(hdc
, pbmi
, DIB_PAL_COLORS
, (void**)&bits
, NULL
, 0);
602 ok(hdib
!= NULL
, "CreateDIBSection failed\n");
603 ok(GetObject(hdib
, sizeof(DIBSECTION
), &dibsec
) != 0, "GetObject failed for DIB Section\n");
604 ok(dibsec
.dsBmih
.biClrUsed
== 2,
605 "created DIBSection: wrong biClrUsed field: %lu, should be: %u\n", dibsec
.dsBmih
.biClrUsed
, 2);
607 /* The colour table has already been grabbed from the dc, so we select back the
610 SelectPalette(hdc
, oldpal
, TRUE
);
611 oldbm
= SelectObject(hdcmem
, hdib
);
612 oldpal
= SelectPalette(hdcmem
, hpal
, TRUE
);
614 ret
= GetDIBColorTable(hdcmem
, 0, 2, rgb
);
615 ok(ret
== 2, "GetDIBColorTable returned %d\n", ret
);
616 ok(rgb
[0].rgbRed
== 0xff && rgb
[0].rgbBlue
== 0xff && rgb
[0].rgbGreen
== 0 &&
617 rgb
[1].rgbRed
== 0 && rgb
[1].rgbBlue
== 0 && rgb
[1].rgbGreen
== 0xff,
618 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
619 rgb
[0].rgbRed
, rgb
[0].rgbGreen
, rgb
[0].rgbBlue
, rgb
[0].rgbReserved
,
620 rgb
[1].rgbRed
, rgb
[1].rgbGreen
, rgb
[1].rgbBlue
, rgb
[1].rgbReserved
);
622 c0
= RGB(plogpal
->palPalEntry
[0].peRed
, plogpal
->palPalEntry
[0].peGreen
, plogpal
->palPalEntry
[0].peBlue
);
623 c1
= RGB(plogpal
->palPalEntry
[1].peRed
, plogpal
->palPalEntry
[1].peGreen
, plogpal
->palPalEntry
[1].peBlue
);
625 test_color(hdcmem
, DIBINDEX(0), c0
, 0, 1);
626 test_color(hdcmem
, DIBINDEX(1), c1
, 0, 1);
627 test_color(hdcmem
, DIBINDEX(2), c0
, 1, 1);
628 test_color(hdcmem
, PALETTEINDEX(0), c0
, 0, 1);
629 test_color(hdcmem
, PALETTEINDEX(1), c1
, 0, 1);
630 test_color(hdcmem
, PALETTEINDEX(2), c0
, 1, 1);
631 test_color(hdcmem
, PALETTERGB(plogpal
->palPalEntry
[0].peRed
, plogpal
->palPalEntry
[0].peGreen
,
632 plogpal
->palPalEntry
[0].peBlue
), c0
, 1, 1);
633 test_color(hdcmem
, PALETTERGB(plogpal
->palPalEntry
[1].peRed
, plogpal
->palPalEntry
[1].peGreen
,
634 plogpal
->palPalEntry
[1].peBlue
), c1
, 1, 1);
635 test_color(hdcmem
, PALETTERGB(0, 0, 0), c1
, 1, 1);
636 test_color(hdcmem
, PALETTERGB(0xff, 0xff, 0xff), c0
, 1, 1);
637 test_color(hdcmem
, PALETTERGB(0, 0, 0xfe), c0
, 1, 1);
638 test_color(hdcmem
, PALETTERGB(0, 1, 0), c1
, 1, 1);
639 test_color(hdcmem
, PALETTERGB(0x3f, 0, 0x3f), c1
, 1, 1);
640 test_color(hdcmem
, PALETTERGB(0x40, 0, 0x40), c0
, 1, 1);
642 /* Bottom and 2nd row from top green, everything else magenta */
643 bits
[0] = bits
[1] = 0xff;
644 bits
[13 * 4] = bits
[13*4 + 1] = 0xff;
646 test_dib_info(hdib
, bits
, &pbmi
->bmiHeader
);
648 pbmi
->bmiHeader
.biBitCount
= 32;
650 hdib2
= CreateDIBSection(NULL
, pbmi
, DIB_RGB_COLORS
, (void **)&bits32
, NULL
, 0);
651 ok(hdib2
!= NULL
, "CreateDIBSection failed\n");
652 hdcmem2
= CreateCompatibleDC(hdc
);
653 oldbm2
= SelectObject(hdcmem2
, hdib2
);
655 BitBlt(hdcmem2
, 0, 0, 16,16, hdcmem
, 0, 0, SRCCOPY
);
657 ok(bits32
[0] == 0xff00, "lower left pixel is %08lx\n", bits32
[0]);
658 ok(bits32
[17] == 0xff00ff, "bottom but one, left pixel is %08lx\n", bits32
[17]);
660 SelectObject(hdcmem2
, oldbm2
);
661 test_dib_info(hdib2
, bits32
, &pbmi
->bmiHeader
);
664 SelectObject(hdcmem
, oldbm
);
665 SelectObject(hdcmem
, oldpal
);
670 pbmi
->bmiHeader
.biBitCount
= 8;
672 memset(plogpal
, 0, sizeof(logpalbuf
));
673 plogpal
->palVersion
= 0x300;
674 plogpal
->palNumEntries
= 256;
676 for (i
= 0; i
< 128; i
++) {
677 plogpal
->palPalEntry
[i
].peRed
= 255 - i
* 2;
678 plogpal
->palPalEntry
[i
].peBlue
= i
* 2;
679 plogpal
->palPalEntry
[i
].peGreen
= 0;
680 plogpal
->palPalEntry
[255 - i
].peRed
= 0;
681 plogpal
->palPalEntry
[255 - i
].peGreen
= i
* 2;
682 plogpal
->palPalEntry
[255 - i
].peBlue
= 255 - i
* 2;
685 index
= (WORD
*)pbmi
->bmiColors
;
686 for (i
= 0; i
< 256; i
++) {
690 hpal
= CreatePalette(plogpal
);
691 ok(hpal
!= NULL
, "CreatePalette failed\n");
692 oldpal
= SelectPalette(hdc
, hpal
, TRUE
);
693 hdib
= CreateDIBSection(hdc
, pbmi
, DIB_PAL_COLORS
, (void**)&bits
, NULL
, 0);
694 ok(hdib
!= NULL
, "CreateDIBSection failed\n");
695 ok(GetObject(hdib
, sizeof(DIBSECTION
), &dibsec
) != 0, "GetObject failed for DIB Section\n");
696 ok(dibsec
.dsBmih
.biClrUsed
== 256,
697 "created DIBSection: wrong biClrUsed field: %lu, should be: %u\n", dibsec
.dsBmih
.biClrUsed
, 256);
699 test_dib_info(hdib
, bits
, &pbmi
->bmiHeader
);
701 SelectPalette(hdc
, oldpal
, TRUE
);
702 oldbm
= SelectObject(hdcmem
, hdib
);
703 oldpal
= SelectPalette(hdcmem
, hpal
, TRUE
);
705 ret
= GetDIBColorTable(hdcmem
, 0, 256, rgb
);
706 ok(ret
== 256, "GetDIBColorTable returned %d\n", ret
);
707 for (i
= 0; i
< 256; i
++) {
708 ok(rgb
[i
].rgbRed
== plogpal
->palPalEntry
[i
].peRed
&&
709 rgb
[i
].rgbBlue
== plogpal
->palPalEntry
[i
].peBlue
&&
710 rgb
[i
].rgbGreen
== plogpal
->palPalEntry
[i
].peGreen
,
711 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
712 i
, rgb
[i
].rgbRed
, rgb
[i
].rgbGreen
, rgb
[i
].rgbBlue
, rgb
[i
].rgbReserved
);
715 for (i
= 0; i
< 256; i
++) {
716 test_color(hdcmem
, DIBINDEX(i
),
717 RGB(plogpal
->palPalEntry
[i
].peRed
, plogpal
->palPalEntry
[i
].peGreen
, plogpal
->palPalEntry
[i
].peBlue
), 0, 0);
718 test_color(hdcmem
, PALETTEINDEX(i
),
719 RGB(plogpal
->palPalEntry
[i
].peRed
, plogpal
->palPalEntry
[i
].peGreen
, plogpal
->palPalEntry
[i
].peBlue
), 0, 0);
720 test_color(hdcmem
, PALETTERGB(plogpal
->palPalEntry
[i
].peRed
, plogpal
->palPalEntry
[i
].peGreen
, plogpal
->palPalEntry
[i
].peBlue
),
721 RGB(plogpal
->palPalEntry
[i
].peRed
, plogpal
->palPalEntry
[i
].peGreen
, plogpal
->palPalEntry
[i
].peBlue
), 0, 0);
724 SelectPalette(hdcmem
, oldpal
, TRUE
);
725 SelectObject(hdcmem
, oldbm
);
734 void test_mono_dibsection(void)
737 HBITMAP old_bm
, mono_ds
;
738 char bmibuf
[sizeof(BITMAPINFO
) + 256 * sizeof(RGBQUAD
)];
739 BITMAPINFO
*pbmi
= (BITMAPINFO
*)bmibuf
;
746 memdc
= CreateCompatibleDC(hdc
);
748 memset(pbmi
, 0, sizeof(bmibuf
));
749 pbmi
->bmiHeader
.biSize
= sizeof(pbmi
->bmiHeader
);
750 pbmi
->bmiHeader
.biHeight
= 10;
751 pbmi
->bmiHeader
.biWidth
= 10;
752 pbmi
->bmiHeader
.biBitCount
= 1;
753 pbmi
->bmiHeader
.biPlanes
= 1;
754 pbmi
->bmiHeader
.biCompression
= BI_RGB
;
755 pbmi
->bmiColors
[0].rgbRed
= 0xff;
756 pbmi
->bmiColors
[0].rgbGreen
= 0xff;
757 pbmi
->bmiColors
[0].rgbBlue
= 0xff;
758 pbmi
->bmiColors
[1].rgbRed
= 0x0;
759 pbmi
->bmiColors
[1].rgbGreen
= 0x0;
760 pbmi
->bmiColors
[1].rgbBlue
= 0x0;
763 * First dib section is 'inverted' ie color[0] is white, color[1] is black
766 mono_ds
= CreateDIBSection(hdc
, pbmi
, DIB_RGB_COLORS
, (void**)&ds_bits
, NULL
, 0);
767 ok(mono_ds
!= NULL
, "CreateDIBSection rets NULL\n");
768 old_bm
= SelectObject(memdc
, mono_ds
);
770 /* black border, white interior */
771 Rectangle(memdc
, 0, 0, 10, 10);
772 ok(ds_bits
[0] == 0xff, "out_bits %02x\n", ds_bits
[0]);
773 ok(ds_bits
[4] == 0x80, "out_bits %02x\n", ds_bits
[4]);
775 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
777 memset(bits
, 0, sizeof(bits
));
780 SetDIBitsToDevice(memdc
, 0, 0, 10, 10, 0, 0, 0, 10, bits
, pbmi
, DIB_RGB_COLORS
);
781 ok(ds_bits
[0] == 0xaa, "out_bits %02x\n", ds_bits
[0]);
783 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
785 pbmi
->bmiColors
[0].rgbRed
= 0x0;
786 pbmi
->bmiColors
[0].rgbGreen
= 0x0;
787 pbmi
->bmiColors
[0].rgbBlue
= 0x0;
788 pbmi
->bmiColors
[1].rgbRed
= 0xff;
789 pbmi
->bmiColors
[1].rgbGreen
= 0xff;
790 pbmi
->bmiColors
[1].rgbBlue
= 0xff;
792 SetDIBitsToDevice(memdc
, 0, 0, 10, 10, 0, 0, 0, 10, bits
, pbmi
, DIB_RGB_COLORS
);
793 ok(ds_bits
[0] == 0x55, "out_bits %02x\n", ds_bits
[0]);
795 SelectObject(memdc
, old_bm
);
796 DeleteObject(mono_ds
);
799 * Next dib section is 'normal' ie color[0] is black, color[1] is white
802 pbmi
->bmiColors
[0].rgbRed
= 0x0;
803 pbmi
->bmiColors
[0].rgbGreen
= 0x0;
804 pbmi
->bmiColors
[0].rgbBlue
= 0x0;
805 pbmi
->bmiColors
[1].rgbRed
= 0xff;
806 pbmi
->bmiColors
[1].rgbGreen
= 0xff;
807 pbmi
->bmiColors
[1].rgbBlue
= 0xff;
809 mono_ds
= CreateDIBSection(hdc
, pbmi
, DIB_RGB_COLORS
, (void**)&ds_bits
, NULL
, 0);
810 ok(mono_ds
!= NULL
, "CreateDIBSection rets NULL\n");
811 old_bm
= SelectObject(memdc
, mono_ds
);
813 /* black border, white interior */
814 Rectangle(memdc
, 0, 0, 10, 10);
815 ok(ds_bits
[0] == 0x00, "out_bits %02x\n", ds_bits
[0]);
816 ok(ds_bits
[4] == 0x7f, "out_bits %02x\n", ds_bits
[4]);
818 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
820 SetDIBitsToDevice(memdc
, 0, 0, 10, 10, 0, 0, 0, 10, bits
, pbmi
, DIB_RGB_COLORS
);
821 ok(ds_bits
[0] == 0xaa, "out_bits %02x\n", ds_bits
[0]);
823 /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
825 pbmi
->bmiColors
[0].rgbRed
= 0xff;
826 pbmi
->bmiColors
[0].rgbGreen
= 0xff;
827 pbmi
->bmiColors
[0].rgbBlue
= 0xff;
828 pbmi
->bmiColors
[1].rgbRed
= 0x0;
829 pbmi
->bmiColors
[1].rgbGreen
= 0x0;
830 pbmi
->bmiColors
[1].rgbBlue
= 0x0;
832 SetDIBitsToDevice(memdc
, 0, 0, 10, 10, 0, 0, 0, 10, bits
, pbmi
, DIB_RGB_COLORS
);
833 ok(ds_bits
[0] == 0x55, "out_bits %02x\n", ds_bits
[0]);
836 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
839 pbmi
->bmiColors
[0].rgbRed
= 0xff;
840 pbmi
->bmiColors
[0].rgbGreen
= 0xff;
841 pbmi
->bmiColors
[0].rgbBlue
= 0xff;
842 pbmi
->bmiColors
[1].rgbRed
= 0x0;
843 pbmi
->bmiColors
[1].rgbGreen
= 0x0;
844 pbmi
->bmiColors
[1].rgbBlue
= 0x0;
845 num
= SetDIBColorTable(memdc
, 0, 2, pbmi
->bmiColors
);
846 ok(num
== 2, "num = %d\n", num
);
848 /* black border, white interior */
849 Rectangle(memdc
, 0, 0, 10, 10);
851 ok(ds_bits
[0] == 0xff, "out_bits %02x\n", ds_bits
[0]);
852 ok(ds_bits
[4] == 0x80, "out_bits %02x\n", ds_bits
[4]);
854 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
856 memset(bits
, 0, sizeof(bits
));
859 SetDIBitsToDevice(memdc
, 0, 0, 10, 10, 0, 0, 0, 10, bits
, pbmi
, DIB_RGB_COLORS
);
860 ok(ds_bits
[0] == 0xaa, "out_bits %02x\n", ds_bits
[0]);
862 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
864 pbmi
->bmiColors
[0].rgbRed
= 0x0;
865 pbmi
->bmiColors
[0].rgbGreen
= 0x0;
866 pbmi
->bmiColors
[0].rgbBlue
= 0x0;
867 pbmi
->bmiColors
[1].rgbRed
= 0xff;
868 pbmi
->bmiColors
[1].rgbGreen
= 0xff;
869 pbmi
->bmiColors
[1].rgbBlue
= 0xff;
871 SetDIBitsToDevice(memdc
, 0, 0, 10, 10, 0, 0, 0, 10, bits
, pbmi
, DIB_RGB_COLORS
);
872 ok(ds_bits
[0] == 0x55, "out_bits %02x\n", ds_bits
[0]);
874 SelectObject(memdc
, old_bm
);
875 DeleteObject(mono_ds
);
878 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
881 pbmi
->bmiColors
[0].rgbRed
= 0xff;
882 pbmi
->bmiColors
[0].rgbGreen
= 0x0;
883 pbmi
->bmiColors
[0].rgbBlue
= 0x0;
884 pbmi
->bmiColors
[1].rgbRed
= 0xfe;
885 pbmi
->bmiColors
[1].rgbGreen
= 0x0;
886 pbmi
->bmiColors
[1].rgbBlue
= 0x0;
888 mono_ds
= CreateDIBSection(hdc
, pbmi
, DIB_RGB_COLORS
, (void**)&ds_bits
, NULL
, 0);
889 ok(mono_ds
!= NULL
, "CreateDIBSection rets NULL\n");
890 old_bm
= SelectObject(memdc
, mono_ds
);
892 /* black border, white interior */
893 Rectangle(memdc
, 0, 0, 10, 10);
894 ok(ds_bits
[0] == 0xff, "out_bits %02x\n", ds_bits
[0]);
895 ok(ds_bits
[4] == 0x80, "out_bits %02x\n", ds_bits
[4]);
897 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
899 pbmi
->bmiColors
[0].rgbRed
= 0x0;
900 pbmi
->bmiColors
[0].rgbGreen
= 0x0;
901 pbmi
->bmiColors
[0].rgbBlue
= 0x0;
902 pbmi
->bmiColors
[1].rgbRed
= 0xff;
903 pbmi
->bmiColors
[1].rgbGreen
= 0xff;
904 pbmi
->bmiColors
[1].rgbBlue
= 0xff;
906 SetDIBitsToDevice(memdc
, 0, 0, 10, 10, 0, 0, 0, 10, bits
, pbmi
, DIB_RGB_COLORS
);
907 ok(ds_bits
[0] == 0x55, "out_bits %02x\n", ds_bits
[0]);
909 /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
911 pbmi
->bmiColors
[0].rgbRed
= 0xff;
912 pbmi
->bmiColors
[0].rgbGreen
= 0xff;
913 pbmi
->bmiColors
[0].rgbBlue
= 0xff;
914 pbmi
->bmiColors
[1].rgbRed
= 0x0;
915 pbmi
->bmiColors
[1].rgbGreen
= 0x0;
916 pbmi
->bmiColors
[1].rgbBlue
= 0x0;
918 SetDIBitsToDevice(memdc
, 0, 0, 10, 10, 0, 0, 0, 10, bits
, pbmi
, DIB_RGB_COLORS
);
919 ok(ds_bits
[0] == 0xaa, "out_bits %02x\n", ds_bits
[0]);
921 SelectObject(memdc
, old_bm
);
922 DeleteObject(mono_ds
);
928 static void test_bitmap(void)
930 char buf
[256], buf_cmp
[256];
931 HBITMAP hbmp
, hbmp_old
;
936 hdc
= CreateCompatibleDC(0);
939 hbmp
= CreateBitmap(15, 15, 1, 1, NULL
);
940 assert(hbmp
!= NULL
);
942 ret
= GetObject(hbmp
, sizeof(bm
), &bm
);
943 ok(ret
== sizeof(bm
), "wrong size %d\n", ret
);
945 ok(bm
.bmType
== 0, "wrong bm.bmType %d\n", bm
.bmType
);
946 ok(bm
.bmWidth
== 15, "wrong bm.bmWidth %d\n", bm
.bmWidth
);
947 ok(bm
.bmHeight
== 15, "wrong bm.bmHeight %d\n", bm
.bmHeight
);
948 ok(bm
.bmWidthBytes
== 2, "wrong bm.bmWidthBytes %d\n", bm
.bmWidthBytes
);
949 ok(bm
.bmPlanes
== 1, "wrong bm.bmPlanes %d\n", bm
.bmPlanes
);
950 ok(bm
.bmBitsPixel
== 1, "wrong bm.bmBitsPixel %d\n", bm
.bmBitsPixel
);
951 ok(bm
.bmBits
== NULL
, "wrong bm.bmBits %p\n", bm
.bmBits
);
953 assert(sizeof(buf
) >= bm
.bmWidthBytes
* bm
.bmHeight
);
954 assert(sizeof(buf
) == sizeof(buf_cmp
));
956 ret
= GetBitmapBits(hbmp
, 0, NULL
);
957 ok(ret
== bm
.bmWidthBytes
* bm
.bmHeight
, "%d != %d\n", ret
, bm
.bmWidthBytes
* bm
.bmHeight
);
959 memset(buf_cmp
, 0xAA, sizeof(buf_cmp
));
960 memset(buf_cmp
, 0, bm
.bmWidthBytes
* bm
.bmHeight
);
962 memset(buf
, 0xAA, sizeof(buf
));
963 ret
= GetBitmapBits(hbmp
, sizeof(buf
), buf
);
964 ok(ret
== bm
.bmWidthBytes
* bm
.bmHeight
, "%d != %d\n", ret
, bm
.bmWidthBytes
* bm
.bmHeight
);
965 ok(!memcmp(buf
, buf_cmp
, sizeof(buf
)), "buffers do not match\n");
967 hbmp_old
= SelectObject(hdc
, hbmp
);
969 ret
= GetObject(hbmp
, sizeof(bm
), &bm
);
970 ok(ret
== sizeof(bm
), "wrong size %d\n", ret
);
972 ok(bm
.bmType
== 0, "wrong bm.bmType %d\n", bm
.bmType
);
973 ok(bm
.bmWidth
== 15, "wrong bm.bmWidth %d\n", bm
.bmWidth
);
974 ok(bm
.bmHeight
== 15, "wrong bm.bmHeight %d\n", bm
.bmHeight
);
975 ok(bm
.bmWidthBytes
== 2, "wrong bm.bmWidthBytes %d\n", bm
.bmWidthBytes
);
976 ok(bm
.bmPlanes
== 1, "wrong bm.bmPlanes %d\n", bm
.bmPlanes
);
977 ok(bm
.bmBitsPixel
== 1, "wrong bm.bmBitsPixel %d\n", bm
.bmBitsPixel
);
978 ok(bm
.bmBits
== NULL
, "wrong bm.bmBits %p\n", bm
.bmBits
);
980 memset(buf
, 0xAA, sizeof(buf
));
981 ret
= GetBitmapBits(hbmp
, sizeof(buf
), buf
);
982 ok(ret
== bm
.bmWidthBytes
* bm
.bmHeight
, "%d != %d\n", ret
, bm
.bmWidthBytes
* bm
.bmHeight
);
983 ok(!memcmp(buf
, buf_cmp
, sizeof(buf
)), "buffers do not match\n");
985 hbmp_old
= SelectObject(hdc
, hbmp_old
);
986 ok(hbmp_old
== hbmp
, "wrong old bitmap %p\n", hbmp_old
);
988 /* test various buffer sizes for GetObject */
989 ret
= GetObject(hbmp
, sizeof(bm
) * 2, &bm
);
990 ok(ret
== sizeof(bm
), "wrong size %d\n", ret
);
992 ret
= GetObject(hbmp
, sizeof(bm
) / 2, &bm
);
993 ok(ret
== 0, "%d != 0\n", ret
);
995 ret
= GetObject(hbmp
, 0, &bm
);
996 ok(ret
== 0, "%d != 0\n", ret
);
998 ret
= GetObject(hbmp
, 1, &bm
);
999 ok(ret
== 0, "%d != 0\n", ret
);
1005 static void test_bmBits(void)
1011 memset(bits
, 0, sizeof(bits
));
1012 hbmp
= CreateBitmap(2, 2, 1, 4, bits
);
1013 ok(hbmp
!= NULL
, "CreateBitmap failed\n");
1015 memset(&bmp
, 0xFF, sizeof(bmp
));
1016 ok(GetObject(hbmp
, sizeof(bmp
), &bmp
) == sizeof(bmp
),
1017 "GetObject failed or returned a wrong structure size\n");
1018 ok(!bmp
.bmBits
, "bmBits must be NULL for device-dependent bitmaps\n");
1023 static void test_GetDIBits_selected_DIB(UINT bpp
)
1037 /* Create a DIB section with a color table */
1039 info
= (BITMAPINFO
*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(BITMAPINFOHEADER
) + (1 << bpp
) * sizeof(RGBQUAD
));
1040 info2
= (BITMAPINFO
*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(BITMAPINFOHEADER
) + (1 << bpp
) * sizeof(RGBQUAD
));
1044 info
->bmiHeader
.biSize
= sizeof(info
->bmiHeader
);
1046 /* Choose width and height such that the row length (in bytes)
1047 is a multiple of 4 (makes things easier) */
1048 info
->bmiHeader
.biWidth
= 32;
1049 info
->bmiHeader
.biHeight
= 32;
1050 info
->bmiHeader
.biPlanes
= 1;
1051 info
->bmiHeader
.biBitCount
= bpp
;
1052 info
->bmiHeader
.biCompression
= BI_RGB
;
1054 for (i
=0; i
< (1 << bpp
); i
++)
1056 BYTE c
= i
* (1 << (8 - bpp
));
1057 info
->bmiColors
[i
].rgbRed
= c
;
1058 info
->bmiColors
[i
].rgbGreen
= c
;
1059 info
->bmiColors
[i
].rgbBlue
= c
;
1060 info
->bmiColors
[i
].rgbReserved
= 0;
1063 dib
= CreateDIBSection(NULL
, info
, DIB_RGB_COLORS
, &bits
, NULL
, 0);
1065 dib_size
= bpp
* (info
->bmiHeader
.biWidth
* info
->bmiHeader
.biHeight
) / 8;
1067 /* Set the bits of the DIB section */
1068 for (i
=0; i
< dib_size
; i
++)
1070 ((BYTE
*)bits
)[i
] = i
% 256;
1073 /* Select the DIB into a DC */
1074 dib_dc
= CreateCompatibleDC(NULL
);
1075 old_bmp
= (HBITMAP
) SelectObject(dib_dc
, dib
);
1076 dc
= CreateCompatibleDC(NULL
);
1077 bits2
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dib_size
);
1080 /* Copy the DIB attributes but not the color table */
1081 memcpy(info2
, info
, sizeof(BITMAPINFOHEADER
));
1083 res
= GetDIBits(dc
, dib
, 0, info
->bmiHeader
.biHeight
, bits2
, info2
, DIB_RGB_COLORS
);
1084 ok(res
, "GetDIBits failed\n");
1086 /* Compare the color table and the bits */
1087 equalContents
= TRUE
;
1088 for (i
=0; i
< (1 << bpp
); i
++)
1090 if ((info
->bmiColors
[i
].rgbRed
!= info2
->bmiColors
[i
].rgbRed
)
1091 || (info
->bmiColors
[i
].rgbGreen
!= info2
->bmiColors
[i
].rgbGreen
)
1092 || (info
->bmiColors
[i
].rgbBlue
!= info2
->bmiColors
[i
].rgbBlue
)
1093 || (info
->bmiColors
[i
].rgbReserved
!= info2
->bmiColors
[i
].rgbReserved
))
1095 equalContents
= FALSE
;
1101 ok(equalContents
, "GetDIBits with DIB selected in DC: Invalid DIB color table\n");
1104 equalContents
= TRUE
;
1105 for (i
=0; i
< dib_size
/ sizeof(DWORD
); i
++)
1107 if (((DWORD
*)bits
)[i
] != ((DWORD
*)bits2
)[i
])
1109 equalContents
= FALSE
;
1115 ok(equalContents
, "GetDIBits with DIB selected in DC: Invalid DIB bits\n");
1118 HeapFree(GetProcessHeap(), 0, bits2
);
1121 SelectObject(dib_dc
, old_bmp
);
1125 HeapFree(GetProcessHeap(), 0, info2
);
1126 HeapFree(GetProcessHeap(), 0, info
);
1129 static void test_GetDIBits_selected_DDB(BOOL monochrome
)
1144 width
= height
= 16;
1146 /* Create a DDB (device-dependent bitmap) */
1150 ddb
= CreateBitmap(width
, height
, 1, 1, NULL
);
1154 HDC screen_dc
= GetDC(NULL
);
1155 bpp
= GetDeviceCaps(screen_dc
, BITSPIXEL
) * GetDeviceCaps(screen_dc
, PLANES
);
1156 ddb
= CreateCompatibleBitmap(screen_dc
, width
, height
);
1157 ReleaseDC(NULL
, screen_dc
);
1160 /* Set the pixels */
1161 ddb_dc
= CreateCompatibleDC(NULL
);
1162 old_bmp
= (HBITMAP
) SelectObject(ddb_dc
, ddb
);
1163 for (i
= 0; i
< width
; i
++)
1165 for (j
=0; j
< height
; j
++)
1167 BYTE c
= (i
* width
+ j
) % 256;
1168 SetPixelV(ddb_dc
, i
, j
, RGB(c
, c
, c
));
1171 SelectObject(ddb_dc
, old_bmp
);
1173 info
= (BITMAPINFO
*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(BITMAPINFOHEADER
) + 256 * sizeof(RGBQUAD
));
1174 info2
= (BITMAPINFO
*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(BITMAPINFOHEADER
) + 256 * sizeof(RGBQUAD
));
1178 info
->bmiHeader
.biSize
= sizeof(info
->bmiHeader
);
1179 info
->bmiHeader
.biWidth
= width
;
1180 info
->bmiHeader
.biHeight
= height
;
1181 info
->bmiHeader
.biPlanes
= 1;
1182 info
->bmiHeader
.biBitCount
= bpp
;
1183 info
->bmiHeader
.biCompression
= BI_RGB
;
1185 dc
= CreateCompatibleDC(NULL
);
1187 /* Fill in biSizeImage */
1188 GetDIBits(dc
, ddb
, 0, height
, NULL
, info
, DIB_RGB_COLORS
);
1189 ok(info
->bmiHeader
.biSizeImage
!= 0, "GetDIBits failed to get the DIB attributes\n");
1191 bits
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, info
->bmiHeader
.biSizeImage
);
1192 bits2
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, info
->bmiHeader
.biSizeImage
);
1197 res
= GetDIBits(dc
, ddb
, 0, height
, bits
, info
, DIB_RGB_COLORS
);
1198 ok(res
, "GetDIBits failed\n");
1200 /* Copy the DIB attributes but not the color table */
1201 memcpy(info2
, info
, sizeof(BITMAPINFOHEADER
));
1203 /* Select the DDB into another DC */
1204 old_bmp
= (HBITMAP
) SelectObject(ddb_dc
, ddb
);
1207 res
= GetDIBits(dc
, ddb
, 0, height
, bits2
, info2
, DIB_RGB_COLORS
);
1208 ok(res
, "GetDIBits failed\n");
1210 /* Compare the color table and the bits */
1213 equalContents
= TRUE
;
1214 for (i
=0; i
< (1 << bpp
); i
++)
1216 if ((info
->bmiColors
[i
].rgbRed
!= info2
->bmiColors
[i
].rgbRed
)
1217 || (info
->bmiColors
[i
].rgbGreen
!= info2
->bmiColors
[i
].rgbGreen
)
1218 || (info
->bmiColors
[i
].rgbBlue
!= info2
->bmiColors
[i
].rgbBlue
)
1219 || (info
->bmiColors
[i
].rgbReserved
!= info2
->bmiColors
[i
].rgbReserved
))
1221 equalContents
= FALSE
;
1225 ok(equalContents
, "GetDIBits with DDB selected in DC: Got a different color table\n");
1228 equalContents
= TRUE
;
1229 for (i
=0; i
< info
->bmiHeader
.biSizeImage
/ sizeof(DWORD
); i
++)
1231 if (((DWORD
*)bits
)[i
] != ((DWORD
*)bits2
)[i
])
1233 equalContents
= FALSE
;
1236 ok(equalContents
, "GetDIBits with DDB selected in DC: Got different DIB bits\n");
1238 HeapFree(GetProcessHeap(), 0, bits2
);
1239 HeapFree(GetProcessHeap(), 0, bits
);
1242 SelectObject(ddb_dc
, old_bmp
);
1246 HeapFree(GetProcessHeap(), 0, info2
);
1247 HeapFree(GetProcessHeap(), 0, info
);
1252 is_win9x
= GetWindowLongPtrW(GetDesktopWindow(), GWLP_WNDPROC
) == 0;
1254 test_createdibitmap();
1256 test_mono_dibsection();
1259 test_GetDIBits_selected_DIB(1);
1260 test_GetDIBits_selected_DIB(4);
1261 test_GetDIBits_selected_DIB(8);
1262 test_GetDIBits_selected_DDB(TRUE
);
1263 test_GetDIBits_selected_DDB(FALSE
);