gdi32: Remove superfluous casts of void pointers to other pointer types.
[wine/multimedia.git] / dlls / gdi32 / tests / bitmap.c
blob019bb35dbe2ad07d375ad6a3c45939d2439c0db2
1 /*
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
22 #include <stdarg.h>
23 #include <assert.h>
24 #include <string.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wingdi.h"
29 #include "winuser.h"
30 #include "mmsystem.h"
32 #include "wine/test.h"
34 static BOOL is_win9x;
36 static INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp )
38 switch(bpp)
40 case 1:
41 return 2 * ((bmWidth+15) >> 4);
43 case 24:
44 bmWidth *= 3; /* fall through */
45 case 8:
46 return bmWidth + (bmWidth & 1);
48 case 32:
49 return bmWidth * 4;
51 case 16:
52 case 15:
53 return bmWidth * 2;
55 case 4:
56 return 2 * ((bmWidth+3) >> 2);
58 default:
59 trace("Unknown depth %d, please report.\n", bpp );
60 assert(0);
62 return -1;
65 static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHEADER *bmih)
67 BITMAP bm;
68 INT ret, width_bytes;
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)
116 HDC hdc, hdcmem;
117 BITMAPINFOHEADER bmih;
118 HBITMAP hbm, hbm_colour, hbm_old;
119 INT screen_depth;
121 hdc = GetDC(0);
122 screen_depth = GetDeviceCaps(hdc, BITSPIXEL);
123 memset(&bmih, 0, sizeof(bmih));
124 bmih.biSize = sizeof(bmih);
125 bmih.biWidth = 10;
126 bmih.biHeight = 10;
127 bmih.biPlanes = 1;
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);
139 DeleteObject(hbm);
141 /* Then 16 */
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);
146 DeleteObject(hbm);
148 /* Then 1 */
149 bmih.biBitCount = 1;
150 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
151 ok(hbm != NULL, "CreateDIBitmap failed\n");
152 test_bitmap_info(hbm, screen_depth, &bmih);
153 DeleteObject(hbm);
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);
163 DeleteObject(hbm);
165 /* Then 16 */
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);
170 DeleteObject(hbm);
172 /* Then 1 */
173 bmih.biBitCount = 1;
174 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
175 ok(hbm != NULL, "CreateDIBitmap failed\n");
176 test_bitmap_info(hbm, 1, &bmih);
177 DeleteObject(hbm);
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);
189 DeleteObject(hbm);
191 /* Then 16 */
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);
196 DeleteObject(hbm);
198 /* Then 1 */
199 bmih.biBitCount = 1;
200 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
201 ok(hbm != NULL, "CreateDIBitmap failed\n");
202 test_bitmap_info(hbm, screen_depth, &bmih);
203 DeleteObject(hbm);
205 SelectObject(hdcmem, hbm_old);
206 DeleteObject(hbm_colour);
207 DeleteDC(hdcmem);
209 /* If hdc == 0 then we get a 1 bpp bitmap */
210 if (!is_win9x) {
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);
215 DeleteObject(hbm);
218 ReleaseDC(0, hdc);
221 static INT DIB_GetWidthBytes( int width, int bpp )
223 int words;
225 switch (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;
230 case 15:
231 case 16: words = (width + 1) / 2; break;
232 case 24: words = (width * 3 + 3)/4; break;
233 case 32: words = width; break;
235 default:
236 words=0;
237 trace("Unknown depth %d, please report.\n", bpp );
238 assert(0);
239 break;
241 return 4 * words;
244 static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
246 BITMAP bm;
247 DIBSECTION ds;
248 INT ret, width_bytes;
249 BYTE *buf;
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, "%u != %u\n",
304 ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
305 ok(bmih->biSizeImage == 0, "%u != 0\n", bmih->biSizeImage);
306 ds.dsBmih.biSizeImage = 0;
308 ok(ds.dsBmih.biSize == bmih->biSize, "%u != %u\n", ds.dsBmih.biSize, bmih->biSize);
309 ok(ds.dsBmih.biWidth == bmih->biWidth, "%u != %u\n", ds.dsBmih.biWidth, bmih->biWidth);
310 ok(ds.dsBmih.biHeight == bmih->biHeight, "%u != %u\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, "%u != %u\n", ds.dsBmih.biCompression, bmih->biCompression);
314 ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%u != %u\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
315 ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%u != %u\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
316 ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%u != %u\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, "%u != %u\n", ds.dsBmih.biWidth, bmih->biWidth);
322 ok(ds.dsBm.bmHeight == bmih->biHeight, "%u != %u\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); \
336 return; \
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) \
342 COLORREF c; \
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;
357 HBITMAP hcoredib;
358 char coreBits[256];
359 BYTE *bits;
360 RGBQUAD rgb[256];
361 int ret;
362 char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
363 LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
364 WORD *index;
365 DWORD *bits32;
366 HPALETTE hpal, oldpal;
367 DIBSECTION dibsec;
368 COLORREF c0, c1;
369 int i;
370 int screen_depth;
371 MEMORY_BASIC_INFORMATION info;
373 hdc = GetDC(0);
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 %d\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, "%x != PAGE_READWRITE\n", info.AllocationProtect);
396 ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
397 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
398 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
399 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
401 test_dib_info(hdib, bits, &pbmi->bmiHeader);
402 DeleteObject(hdib);
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 %d\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 %d\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, "%x != PAGE_READWRITE\n", info.AllocationProtect);
426 ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
427 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
428 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
429 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
431 test_dib_info(hdib, bits, &pbmi->bmiHeader);
432 DeleteObject(hdib);
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: %u, 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;
459 if (!is_win9x) {
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);
515 DeleteObject(hdib);
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);
540 DeleteObject(hdib);
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: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
553 test_dib_info(hdib, bits, &pbmi->bmiHeader);
554 DeleteObject(hdib);
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: %u, 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);
583 DeleteObject(hdib);
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;
596 *index++ = 0;
597 *index = 1;
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: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
607 /* The colour table has already been grabbed from the dc, so we select back the
608 old palette */
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 %08x\n", bits32[0]);
658 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
660 SelectObject(hdcmem2, oldbm2);
661 test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
662 DeleteObject(hdib2);
664 SelectObject(hdcmem, oldbm);
665 SelectObject(hdcmem, oldpal);
666 DeleteObject(hdib);
667 DeleteObject(hpal);
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++) {
687 *index++ = 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: %u, 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);
726 DeleteObject(hdib);
727 DeleteObject(hpal);
730 DeleteDC(hdcmem);
731 ReleaseDC(0, hdc);
734 static void test_mono_dibsection(void)
736 HDC hdc, memdc;
737 HBITMAP old_bm, mono_ds;
738 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
739 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
740 BYTE bits[10 * 4];
741 BYTE *ds_bits;
742 int num;
744 hdc = GetDC(0);
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));
778 bits[0] = 0xaa;
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);
850 todo_wine {
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));
857 bits[0] = 0xaa;
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);
924 DeleteDC(memdc);
925 ReleaseDC(0, hdc);
928 static void test_bitmap(void)
930 char buf[256], buf_cmp[256];
931 HBITMAP hbmp, hbmp_old;
932 HDC hdc;
933 BITMAP bm;
934 INT ret;
936 hdc = CreateCompatibleDC(0);
937 assert(hdc != 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);
1001 DeleteObject(hbmp);
1002 DeleteDC(hdc);
1005 static void test_bmBits(void)
1007 BYTE bits[4];
1008 HBITMAP hbmp;
1009 BITMAP bmp;
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");
1020 DeleteObject(hbmp);
1023 static void test_GetDIBits_selected_DIB(UINT bpp)
1025 HBITMAP dib;
1026 BITMAPINFO * info;
1027 BITMAPINFO * info2;
1028 void * bits;
1029 void * bits2;
1030 UINT dib_size;
1031 HDC dib_dc, dc;
1032 HBITMAP old_bmp;
1033 BOOL equalContents;
1034 UINT i;
1035 int res;
1037 /* Create a DIB section with a color table */
1039 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD));
1040 info2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD));
1041 assert(info);
1042 assert(info2);
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 < (1u << 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);
1064 assert(dib);
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);
1078 assert(bits2);
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 < (1u << 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;
1096 break;
1099 ok(equalContents, "GetDIBits with DIB selected in DC: Invalid DIB color table\n");
1101 equalContents = TRUE;
1102 for (i=0; i < dib_size / sizeof(DWORD); i++)
1104 if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i])
1106 equalContents = FALSE;
1107 break;
1110 if (bpp != 1)
1111 ok(equalContents, "GetDIBits with %d bpp DIB selected in DC: Invalid DIB bits\n",bpp);
1112 else
1113 todo_wine ok(equalContents, "GetDIBits with %d bpp DIB selected in DC: Invalid DIB bits\n",bpp);
1115 HeapFree(GetProcessHeap(), 0, bits2);
1116 DeleteDC(dc);
1118 SelectObject(dib_dc, old_bmp);
1119 DeleteDC(dib_dc);
1120 DeleteObject(dib);
1122 HeapFree(GetProcessHeap(), 0, info2);
1123 HeapFree(GetProcessHeap(), 0, info);
1126 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1128 HBITMAP ddb;
1129 BITMAPINFO * info;
1130 BITMAPINFO * info2;
1131 void * bits;
1132 void * bits2;
1133 HDC ddb_dc, dc;
1134 HBITMAP old_bmp;
1135 BOOL equalContents;
1136 UINT width, height;
1137 UINT bpp;
1138 UINT i, j;
1139 int res;
1141 width = height = 16;
1143 /* Create a DDB (device-dependent bitmap) */
1144 if (monochrome)
1146 bpp = 1;
1147 ddb = CreateBitmap(width, height, 1, 1, NULL);
1149 else
1151 HDC screen_dc = GetDC(NULL);
1152 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1153 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1154 ReleaseDC(NULL, screen_dc);
1157 /* Set the pixels */
1158 ddb_dc = CreateCompatibleDC(NULL);
1159 old_bmp = (HBITMAP) SelectObject(ddb_dc, ddb);
1160 for (i = 0; i < width; i++)
1162 for (j=0; j < height; j++)
1164 BYTE c = (i * width + j) % 256;
1165 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1168 SelectObject(ddb_dc, old_bmp);
1170 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1171 info2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1172 assert(info);
1173 assert(info2);
1175 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1176 info->bmiHeader.biWidth = width;
1177 info->bmiHeader.biHeight = height;
1178 info->bmiHeader.biPlanes = 1;
1179 info->bmiHeader.biBitCount = bpp;
1180 info->bmiHeader.biCompression = BI_RGB;
1182 dc = CreateCompatibleDC(NULL);
1184 /* Fill in biSizeImage */
1185 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1186 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1188 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1189 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1190 assert(bits);
1191 assert(bits2);
1193 /* Get the bits */
1194 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1195 ok(res, "GetDIBits failed\n");
1197 /* Copy the DIB attributes but not the color table */
1198 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1200 /* Select the DDB into another DC */
1201 old_bmp = (HBITMAP) SelectObject(ddb_dc, ddb);
1203 /* Get the bits */
1204 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1205 ok(res, "GetDIBits failed\n");
1207 /* Compare the color table and the bits */
1208 if (bpp <= 8)
1210 equalContents = TRUE;
1211 for (i=0; i < (1u << bpp); i++)
1213 if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed)
1214 || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen)
1215 || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue)
1216 || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved))
1218 equalContents = FALSE;
1219 break;
1222 ok(equalContents, "GetDIBits with DDB selected in DC: Got a different color table\n");
1225 equalContents = TRUE;
1226 for (i=0; i < info->bmiHeader.biSizeImage / sizeof(DWORD); i++)
1228 if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i])
1230 equalContents = FALSE;
1233 ok(equalContents, "GetDIBits with DDB selected in DC: Got different DIB bits\n");
1235 HeapFree(GetProcessHeap(), 0, bits2);
1236 HeapFree(GetProcessHeap(), 0, bits);
1237 DeleteDC(dc);
1239 SelectObject(ddb_dc, old_bmp);
1240 DeleteDC(ddb_dc);
1241 DeleteObject(ddb);
1243 HeapFree(GetProcessHeap(), 0, info2);
1244 HeapFree(GetProcessHeap(), 0, info);
1247 static void test_GetDIBits(void)
1249 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1250 static const BYTE bmp_bits_1[16 * 2] =
1252 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1253 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1254 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1255 0xff,0xff, 0,0, 0xff,0xff, 0,0
1257 /* 4-bytes aligned 1-bit DIB data: 16x16 */
1258 static const BYTE dib_bits_1[16 * 4] =
1260 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1261 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1262 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1263 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1265 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1266 static const BYTE bmp_bits_24[16 * 16*3] =
1268 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1269 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1270 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1271 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1272 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1273 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1274 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1275 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1276 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1277 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1278 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1279 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1280 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1281 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1282 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1283 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1284 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1285 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1286 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1287 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1288 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1289 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1290 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1291 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1292 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1293 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1294 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1295 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1296 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1297 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1298 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1299 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1301 /* 4-bytes aligned 24-bit DIB data: 16x16 */
1302 static const BYTE dib_bits_24[16 * 16*3] =
1304 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1305 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1306 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1307 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1308 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1309 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1310 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1311 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1312 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1313 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1314 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1315 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1316 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1317 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1318 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1319 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1320 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1321 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1322 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1323 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1324 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1325 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1326 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1327 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1328 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1329 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1330 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1331 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1332 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1333 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1334 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1335 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1337 HBITMAP hbmp;
1338 BITMAP bm;
1339 HDC hdc;
1340 int i, bytes, lines;
1341 BYTE buf[1024];
1342 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1343 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1345 hdc = GetDC(0);
1347 /* 1-bit source bitmap data */
1348 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1349 ok(hbmp != 0, "CreateBitmap failed\n");
1351 memset(&bm, 0xAA, sizeof(bm));
1352 bytes = GetObject(hbmp, sizeof(bm), &bm);
1353 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1354 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1355 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1356 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1357 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1358 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1359 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1360 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1362 bytes = GetBitmapBits(hbmp, 0, NULL);
1363 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1364 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1365 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1366 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1368 /* retrieve 1-bit DIB data */
1369 memset(bi, 0, sizeof(*bi));
1370 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1371 bi->bmiHeader.biWidth = bm.bmWidth;
1372 bi->bmiHeader.biHeight = bm.bmHeight;
1373 bi->bmiHeader.biPlanes = 1;
1374 bi->bmiHeader.biBitCount = 1;
1375 bi->bmiHeader.biCompression = BI_RGB;
1376 bi->bmiHeader.biSizeImage = 0;
1377 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1378 SetLastError(0xdeadbeef);
1379 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1380 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1381 ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
1382 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1384 memset(buf, 0xAA, sizeof(buf));
1385 SetLastError(0xdeadbeef);
1386 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1387 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1388 lines, bm.bmHeight, GetLastError());
1389 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1391 /* the color table consists of black and white */
1392 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1393 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1394 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1395 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1396 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1397 todo_wine
1398 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1399 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1400 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1401 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1402 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1403 for (i = 2; i < 256; i++)
1405 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1406 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1407 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1408 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1409 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1412 /* returned bits are DWORD aligned and upside down */
1413 todo_wine
1414 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1416 /* retrieve 24-bit DIB data */
1417 memset(bi, 0, sizeof(*bi));
1418 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1419 bi->bmiHeader.biWidth = bm.bmWidth;
1420 bi->bmiHeader.biHeight = bm.bmHeight;
1421 bi->bmiHeader.biPlanes = 1;
1422 bi->bmiHeader.biBitCount = 24;
1423 bi->bmiHeader.biCompression = BI_RGB;
1424 bi->bmiHeader.biSizeImage = 0;
1425 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1426 memset(buf, 0xAA, sizeof(buf));
1427 SetLastError(0xdeadbeef);
1428 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1429 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1430 lines, bm.bmHeight, GetLastError());
1431 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1433 /* the color table doesn't exist for 24-bit images */
1434 for (i = 0; i < 256; i++)
1436 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1437 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1438 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1439 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1440 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1443 /* returned bits are DWORD aligned and upside down */
1444 todo_wine
1445 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1446 DeleteObject(hbmp);
1448 /* 24-bit source bitmap data */
1449 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1450 ok(hbmp != 0, "CreateBitmap failed\n");
1451 SetLastError(0xdeadbeef);
1452 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1453 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1454 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1455 lines, bm.bmHeight, GetLastError());
1457 memset(&bm, 0xAA, sizeof(bm));
1458 bytes = GetObject(hbmp, sizeof(bm), &bm);
1459 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1460 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1461 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1462 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1463 ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1464 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1465 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1466 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1468 bytes = GetBitmapBits(hbmp, 0, NULL);
1469 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1470 bm.bmWidthBytes * bm.bmHeight, bytes);
1471 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1472 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1473 bm.bmWidthBytes * bm.bmHeight, bytes);
1475 /* retrieve 1-bit DIB data */
1476 memset(bi, 0, sizeof(*bi));
1477 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1478 bi->bmiHeader.biWidth = bm.bmWidth;
1479 bi->bmiHeader.biHeight = bm.bmHeight;
1480 bi->bmiHeader.biPlanes = 1;
1481 bi->bmiHeader.biBitCount = 1;
1482 bi->bmiHeader.biCompression = BI_RGB;
1483 bi->bmiHeader.biSizeImage = 0;
1484 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1485 memset(buf, 0xAA, sizeof(buf));
1486 SetLastError(0xdeadbeef);
1487 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1488 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1489 lines, bm.bmHeight, GetLastError());
1490 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1492 /* the color table consists of black and white */
1493 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1494 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1495 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1496 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1497 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1498 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1499 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1500 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1501 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1502 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1503 for (i = 2; i < 256; i++)
1505 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1506 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1507 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1508 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1509 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1512 /* returned bits are DWORD aligned and upside down */
1513 todo_wine
1514 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1516 /* retrieve 24-bit DIB data */
1517 memset(bi, 0, sizeof(*bi));
1518 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1519 bi->bmiHeader.biWidth = bm.bmWidth;
1520 bi->bmiHeader.biHeight = bm.bmHeight;
1521 bi->bmiHeader.biPlanes = 1;
1522 bi->bmiHeader.biBitCount = 24;
1523 bi->bmiHeader.biCompression = BI_RGB;
1524 bi->bmiHeader.biSizeImage = 0;
1525 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1526 memset(buf, 0xAA, sizeof(buf));
1527 SetLastError(0xdeadbeef);
1528 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1529 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1530 lines, bm.bmHeight, GetLastError());
1531 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1533 /* the color table doesn't exist for 24-bit images */
1534 for (i = 0; i < 256; i++)
1536 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1537 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1538 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1539 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1540 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1543 /* returned bits are DWORD aligned and upside down */
1544 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1545 DeleteObject(hbmp);
1547 ReleaseDC(0, hdc);
1550 static void test_select_object(void)
1552 HDC hdc;
1553 HBITMAP hbm, hbm_old;
1554 INT planes, bpp;
1556 hdc = GetDC(0);
1557 ok(hdc != 0, "GetDC(0) failed\n");
1558 hbm = CreateCompatibleBitmap(hdc, 10, 10);
1559 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
1561 hbm_old = SelectObject(hdc, hbm);
1562 ok(hbm_old == 0, "SelectObject should fail\n");
1564 DeleteObject(hbm);
1565 ReleaseDC(0, hdc);
1567 hdc = CreateCompatibleDC(0);
1568 ok(hdc != 0, "GetDC(0) failed\n");
1569 hbm = CreateCompatibleBitmap(hdc, 10, 10);
1570 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
1572 hbm_old = SelectObject(hdc, hbm);
1573 ok(hbm_old != 0, "SelectObject failed\n");
1574 hbm_old = SelectObject(hdc, hbm_old);
1575 ok(hbm_old == hbm, "SelectObject failed\n");
1577 DeleteObject(hbm);
1579 /* test an 1-bpp bitmap */
1580 planes = GetDeviceCaps(hdc, PLANES);
1581 bpp = 1;
1583 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
1584 ok(hbm != 0, "CreateBitmap failed\n");
1586 hbm_old = SelectObject(hdc, hbm);
1587 ok(hbm_old != 0, "SelectObject failed\n");
1588 hbm_old = SelectObject(hdc, hbm_old);
1589 ok(hbm_old == hbm, "SelectObject failed\n");
1591 DeleteObject(hbm);
1593 /* test a color bitmap that doesn't match the dc's bpp */
1594 planes = GetDeviceCaps(hdc, PLANES);
1595 bpp = GetDeviceCaps(hdc, BITSPIXEL) == 24 ? 8 : 24;
1597 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
1598 ok(hbm != 0, "CreateBitmap failed\n");
1600 hbm_old = SelectObject(hdc, hbm);
1601 ok(hbm_old == 0, "SelectObject should fail\n");
1603 DeleteObject(hbm);
1605 DeleteDC(hdc);
1608 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
1610 INT ret;
1611 BITMAP bm;
1613 ret = GetObjectType(hbmp);
1614 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
1616 ret = GetObject(hbmp, 0, 0);
1617 ok_(__FILE__, line)(ret == sizeof(BITMAP) /* XP */ ||
1618 ret == sizeof(DIBSECTION) /* Win9x */, "object size %d\n", ret);
1620 memset(&bm, 0xDA, sizeof(bm));
1621 SetLastError(0xdeadbeef);
1622 ret = GetObject(hbmp, sizeof(bm), &bm);
1623 if (!ret) /* XP, only for curObj2 */ return;
1624 ok_(__FILE__, line)(ret == sizeof(BITMAP) ||
1625 ret == sizeof(DIBSECTION) /* Win9x, only for curObj2 */,
1626 "GetObject returned %d, error %u\n", ret, GetLastError());
1627 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1628 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth %d\n", bm.bmWidth);
1629 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight %d\n", bm.bmHeight);
1630 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1631 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1632 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1633 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1636 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
1638 static void test_CreateBitmap(void)
1640 BITMAP bmp;
1641 HDC screenDC = GetDC(0);
1642 HDC hdc = CreateCompatibleDC(screenDC);
1644 /* all of these are the stock monochrome bitmap */
1645 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
1646 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
1647 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
1648 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
1649 HBITMAP curObj1 = (HBITMAP)GetCurrentObject(hdc, OBJ_BITMAP);
1650 HBITMAP curObj2 = (HBITMAP)GetCurrentObject(screenDC, OBJ_BITMAP);
1652 /* these 2 are not the stock monochrome bitmap */
1653 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
1654 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
1656 HBITMAP old1 = (HBITMAP)SelectObject(hdc, bm2);
1657 HBITMAP old2 = (HBITMAP)SelectObject(screenDC, bm3);
1658 SelectObject(hdc, old1);
1659 SelectObject(screenDC, old2);
1661 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
1662 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
1663 bm, bm1, bm4, bm5, curObj1, old1);
1664 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
1665 ok(bm != curObj2 /* XP */ || bm == curObj2 /* Win9x */,
1666 "0: %p, curObj2 %p\n", bm, curObj2);
1667 ok(old2 == 0, "old2 %p\n", old2);
1669 test_mono_1x1_bmp(bm);
1670 test_mono_1x1_bmp(bm1);
1671 test_mono_1x1_bmp(bm2);
1672 test_mono_1x1_bmp(bm3);
1673 test_mono_1x1_bmp(bm4);
1674 test_mono_1x1_bmp(bm5);
1675 test_mono_1x1_bmp(old1);
1676 test_mono_1x1_bmp(curObj1);
1677 test_mono_1x1_bmp(curObj2);
1679 DeleteObject(bm);
1680 DeleteObject(bm1);
1681 DeleteObject(bm2);
1682 DeleteObject(bm3);
1683 DeleteObject(bm4);
1684 DeleteObject(bm5);
1686 DeleteDC(hdc);
1687 ReleaseDC(0, screenDC);
1689 /* show that Windows ignores the provided bm.bmWidthBytes */
1690 bmp.bmType = 0;
1691 bmp.bmWidth = 1;
1692 bmp.bmHeight = 1;
1693 bmp.bmWidthBytes = 28;
1694 bmp.bmPlanes = 1;
1695 bmp.bmBitsPixel = 1;
1696 bmp.bmBits = NULL;
1697 bm = CreateBitmapIndirect(&bmp);
1698 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
1699 test_mono_1x1_bmp(bm);
1700 DeleteObject(bm);
1703 static void test_bitmapinfoheadersize(void)
1705 HBITMAP hdib;
1706 BITMAPINFO bmi;
1707 BITMAPCOREINFO bci;
1708 HDC hdc = GetDC(0);
1710 memset(&bmi, 0, sizeof(BITMAPINFO));
1711 bmi.bmiHeader.biHeight = 100;
1712 bmi.bmiHeader.biWidth = 512;
1713 bmi.bmiHeader.biBitCount = 24;
1714 bmi.bmiHeader.biPlanes = 1;
1716 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
1718 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1719 ok(hdib == NULL, "CreateDIBSection succeeded\n");
1721 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1723 SetLastError(0xdeadbeef);
1724 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1725 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1726 DeleteObject(hdib);
1728 bmi.bmiHeader.biSize++;
1730 SetLastError(0xdeadbeef);
1731 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1732 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1733 DeleteObject(hdib);
1735 bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
1737 SetLastError(0xdeadbeef);
1738 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1739 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1740 DeleteObject(hdib);
1742 bmi.bmiHeader.biSize++;
1744 SetLastError(0xdeadbeef);
1745 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1746 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1747 DeleteObject(hdib);
1749 bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
1751 SetLastError(0xdeadbeef);
1752 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1753 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1754 DeleteObject(hdib);
1756 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
1758 SetLastError(0xdeadbeef);
1759 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1760 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1761 DeleteObject(hdib);
1763 memset(&bci, 0, sizeof(BITMAPCOREINFO));
1764 bci.bmciHeader.bcHeight = 100;
1765 bci.bmciHeader.bcWidth = 512;
1766 bci.bmciHeader.bcBitCount = 24;
1767 bci.bmciHeader.bcPlanes = 1;
1769 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
1771 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
1772 ok(hdib == NULL, "CreateDIBSection succeeded\n");
1774 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
1776 SetLastError(0xdeadbeef);
1777 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
1778 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1779 DeleteObject(hdib);
1781 bci.bmciHeader.bcSize++;
1783 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
1784 ok(hdib == NULL, "CreateDIBSection succeeded\n");
1786 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
1788 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
1789 ok(hdib == NULL, "CreateDIBSection succeeded\n");
1791 ReleaseDC(0, hdc);
1794 START_TEST(bitmap)
1796 is_win9x = GetWindowLongPtrW(GetDesktopWindow(), GWLP_WNDPROC) == 0;
1798 test_createdibitmap();
1799 test_dibsections();
1800 test_mono_dibsection();
1801 test_bitmap();
1802 test_bmBits();
1803 test_GetDIBits_selected_DIB(1);
1804 test_GetDIBits_selected_DIB(4);
1805 test_GetDIBits_selected_DIB(8);
1806 test_GetDIBits_selected_DDB(TRUE);
1807 test_GetDIBits_selected_DDB(FALSE);
1808 test_GetDIBits();
1809 test_select_object();
1810 test_CreateBitmap();
1811 test_bitmapinfoheadersize();