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
33 #include "wine/test.h"
35 static BOOL (WINAPI *pGdiAlphaBlend)(HDC,int,int,int,int,HDC,int,int,int,int,BLENDFUNCTION);
37 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
41 static INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp )
46 return 2 * ((bmWidth+15) >> 4);
49 bmWidth *= 3; /* fall through */
51 return bmWidth + (bmWidth & 1);
61 return 2 * ((bmWidth+3) >> 2);
64 trace("Unknown depth %d, please report.\n", bpp );
70 static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHEADER *bmih)
74 char buf[512], buf_cmp[512];
76 ret = GetObject(hbm, sizeof(bm), &bm);
77 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
79 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
80 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
81 ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
82 width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
83 ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
84 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
85 ok(bm.bmBitsPixel == expected_depth, "wrong bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, expected_depth);
86 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
88 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
89 assert(sizeof(buf) == sizeof(buf_cmp));
91 ret = GetBitmapBits(hbm, 0, NULL);
92 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
94 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
95 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
97 memset(buf, 0xAA, sizeof(buf));
98 ret = GetBitmapBits(hbm, sizeof(buf), buf);
99 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
100 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
102 /* test various buffer sizes for GetObject */
103 ret = GetObject(hbm, 0, NULL);
104 ok(ret == sizeof(bm), "wrong size %d\n", ret);
106 ret = GetObject(hbm, sizeof(bm) * 2, &bm);
107 ok(ret == sizeof(bm), "wrong size %d\n", ret);
109 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
110 ok(ret == 0, "%d != 0\n", ret);
112 ret = GetObject(hbm, 0, &bm);
113 ok(ret == 0, "%d != 0\n", ret);
115 ret = GetObject(hbm, 1, &bm);
116 ok(ret == 0, "%d != 0\n", ret);
119 static void test_createdibitmap(void)
122 BITMAPINFOHEADER bmih;
124 HBITMAP hbm, hbm_colour, hbm_old;
129 screen_depth = GetDeviceCaps(hdc, BITSPIXEL);
130 memset(&bmih, 0, sizeof(bmih));
131 bmih.biSize = sizeof(bmih);
135 bmih.biBitCount = 32;
136 bmih.biCompression = BI_RGB;
138 /* First create an un-initialised bitmap. The depth of the bitmap
139 should match that of the hdc and not that supplied in bmih.
142 /* First try 32 bits */
143 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
144 ok(hbm != NULL, "CreateDIBitmap failed\n");
145 test_bitmap_info(hbm, screen_depth, &bmih);
149 bmih.biBitCount = 16;
150 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
151 ok(hbm != NULL, "CreateDIBitmap failed\n");
152 test_bitmap_info(hbm, screen_depth, &bmih);
157 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
158 ok(hbm != NULL, "CreateDIBitmap failed\n");
159 test_bitmap_info(hbm, screen_depth, &bmih);
162 /* Now with a monochrome dc we expect a monochrome bitmap */
163 hdcmem = CreateCompatibleDC(hdc);
165 /* First try 32 bits */
166 bmih.biBitCount = 32;
167 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
168 ok(hbm != NULL, "CreateDIBitmap failed\n");
169 test_bitmap_info(hbm, 1, &bmih);
173 bmih.biBitCount = 16;
174 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
175 ok(hbm != NULL, "CreateDIBitmap failed\n");
176 test_bitmap_info(hbm, 1, &bmih);
181 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
182 ok(hbm != NULL, "CreateDIBitmap failed\n");
183 test_bitmap_info(hbm, 1, &bmih);
186 /* Now select a polychrome bitmap into the dc and we expect
187 screen_depth bitmaps again */
188 hbm_colour = CreateCompatibleBitmap(hdc, bmih.biWidth, bmih.biHeight);
189 test_bitmap_info(hbm_colour, screen_depth, &bmih);
190 hbm_old = SelectObject(hdcmem, hbm_colour);
192 /* First try 32 bits */
193 bmih.biBitCount = 32;
194 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
195 ok(hbm != NULL, "CreateDIBitmap failed\n");
196 test_bitmap_info(hbm, screen_depth, &bmih);
200 bmih.biBitCount = 16;
201 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
202 ok(hbm != NULL, "CreateDIBitmap failed\n");
203 test_bitmap_info(hbm, screen_depth, &bmih);
208 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
209 ok(hbm != NULL, "CreateDIBitmap failed\n");
210 test_bitmap_info(hbm, screen_depth, &bmih);
213 SelectObject(hdcmem, hbm_old);
214 DeleteObject(hbm_colour);
217 /* If hdc == 0 then we get a 1 bpp bitmap */
219 bmih.biBitCount = 32;
220 hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0);
221 ok(hbm != NULL, "CreateDIBitmap failed\n");
222 test_bitmap_info(hbm, 1, &bmih);
226 /* Test how formats are converted */
232 memset(&bm, 0, sizeof(bm));
233 bm.bmiHeader.biSize = sizeof(bm.bmiHeader);
234 bm.bmiHeader.biWidth = 1;
235 bm.bmiHeader.biHeight = 1;
236 bm.bmiHeader.biPlanes = 1;
237 bm.bmiHeader.biBitCount= 24;
238 bm.bmiHeader.biCompression= BI_RGB;
239 bm.bmiHeader.biSizeImage = 0;
240 hbm = CreateDIBitmap(hdc, &bmih, CBM_INIT, &pixel, &bm, DIB_RGB_COLORS);
241 ok(hbm != NULL, "CreateDIBitmap failed\n");
244 bm.bmiHeader.biBitCount= 32;
245 GetDIBits(hdc, hbm, 0, 1, &pixel, &bm, DIB_RGB_COLORS);
246 ok(pixel == 0x00ffffff, "Reading a 32 bit pixel from a DDB returned %08x\n", pixel);
252 static INT DIB_GetWidthBytes( int width, int bpp )
258 case 1: words = (width + 31) / 32; break;
259 case 4: words = (width + 7) / 8; break;
260 case 8: words = (width + 3) / 4; break;
262 case 16: words = (width + 1) / 2; break;
263 case 24: words = (width * 3 + 3)/4; break;
264 case 32: words = width; break;
268 trace("Unknown depth %d, please report.\n", bpp );
275 static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
279 INT ret, bm_width_bytes, dib_width_bytes;
282 ret = GetObject(hbm, sizeof(bm), &bm);
283 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
285 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
286 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
287 ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
288 dib_width_bytes = DIB_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
289 bm_width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
290 if (bm.bmWidthBytes != dib_width_bytes) /* Win2k bug */
291 ok(bm.bmWidthBytes == bm_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, bm_width_bytes);
293 ok(bm.bmWidthBytes == dib_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, dib_width_bytes);
294 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
295 ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount);
296 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
298 buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);
300 /* GetBitmapBits returns not 32-bit aligned data */
301 ret = GetBitmapBits(hbm, 0, NULL);
302 ok(ret == bm_width_bytes * bm.bmHeight, "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
304 memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
305 ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
306 ok(ret == bm_width_bytes * bm.bmHeight, "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
308 HeapFree(GetProcessHeap(), 0, buf);
310 /* test various buffer sizes for GetObject */
311 memset(&ds, 0xAA, sizeof(ds));
312 ret = GetObject(hbm, sizeof(bm) * 2, &bm);
313 ok(ret == sizeof(bm), "wrong size %d\n", ret);
314 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
315 ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
316 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
318 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
319 ok(ret == 0, "%d != 0\n", ret);
321 ret = GetObject(hbm, 0, &bm);
322 ok(ret == 0, "%d != 0\n", ret);
324 ret = GetObject(hbm, 1, &bm);
325 ok(ret == 0, "%d != 0\n", ret);
327 /* test various buffer sizes for GetObject */
328 ret = GetObject(hbm, 0, NULL);
329 ok(ret == sizeof(bm), "wrong size %d\n", ret);
331 memset(&ds, 0xAA, sizeof(ds));
332 ret = GetObject(hbm, sizeof(ds) * 2, &ds);
333 ok(ret == sizeof(ds), "wrong size %d\n", ret);
335 ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
336 if (ds.dsBm.bmWidthBytes != bm_width_bytes) /* Win2k bug */
337 ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%u != %u\n",
338 ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
339 ok(bmih->biSizeImage == 0, "%u != 0\n", bmih->biSizeImage);
340 ds.dsBmih.biSizeImage = 0;
342 ok(ds.dsBmih.biSize == bmih->biSize, "%u != %u\n", ds.dsBmih.biSize, bmih->biSize);
343 ok(ds.dsBmih.biWidth == bmih->biWidth, "%u != %u\n", ds.dsBmih.biWidth, bmih->biWidth);
344 ok(ds.dsBmih.biHeight == bmih->biHeight, "%u != %u\n", ds.dsBmih.biHeight, bmih->biHeight);
345 ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes);
346 ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount);
347 ok(ds.dsBmih.biCompression == bmih->biCompression, "%u != %u\n", ds.dsBmih.biCompression, bmih->biCompression);
348 ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%u != %u\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
349 ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%u != %u\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
350 ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%u != %u\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);
352 memset(&ds, 0xAA, sizeof(ds));
353 ret = GetObject(hbm, sizeof(ds) - 4, &ds);
354 ok(ret == sizeof(ds.dsBm), "wrong size %d\n", ret);
355 ok(ds.dsBm.bmWidth == bmih->biWidth, "%u != %u\n", ds.dsBmih.biWidth, bmih->biWidth);
356 ok(ds.dsBm.bmHeight == bmih->biHeight, "%u != %u\n", ds.dsBmih.biHeight, bmih->biHeight);
357 ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);
359 ret = GetObject(hbm, 0, &ds);
360 ok(ret == 0, "%d != 0\n", ret);
362 ret = GetObject(hbm, 1, &ds);
363 ok(ret == 0, "%d != 0\n", ret);
366 #define test_color_todo(got, exp, txt, todo) \
367 if (!todo && got != exp && screen_depth < 24) { \
368 todo_wine ok(0, #txt " failed at %d-bit screen depth: got 0x%06x expected 0x%06x - skipping DIB tests\n", \
369 screen_depth, (UINT)got, (UINT)exp); \
371 } else if (todo) todo_wine { ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp); } \
372 else ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp) \
374 #define test_color(hdc, color, exp, todo_setp, todo_getp) \
377 c = SetPixel(hdc, 0, 0, color); \
378 if (!is_win9x) { test_color_todo(c, exp, SetPixel, todo_setp); } \
379 c = GetPixel(hdc, 0, 0); \
380 test_color_todo(c, exp, GetPixel, todo_getp); \
383 static void test_dibsections(void)
385 HDC hdc, hdcmem, hdcmem2;
386 HBITMAP hdib, oldbm, hdib2, oldbm2;
387 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
388 char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
389 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
390 BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
396 char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
397 LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
400 HPALETTE hpal, oldpal;
405 MEMORY_BASIC_INFORMATION info;
408 screen_depth = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
410 memset(pbmi, 0, sizeof(bmibuf));
411 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
412 pbmi->bmiHeader.biHeight = 100;
413 pbmi->bmiHeader.biWidth = 512;
414 pbmi->bmiHeader.biBitCount = 24;
415 pbmi->bmiHeader.biPlanes = 1;
416 pbmi->bmiHeader.biCompression = BI_RGB;
418 SetLastError(0xdeadbeef);
420 /* invalid pointer for BITMAPINFO
421 (*bits should be NULL on error) */
422 bits = (BYTE*)0xdeadbeef;
423 hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
424 ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n");
426 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
427 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
428 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
429 ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
431 /* test the DIB memory */
432 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
433 "VirtualQuery failed\n");
434 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
435 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
436 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
437 ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
438 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
439 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
440 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
442 test_dib_info(hdib, bits, &pbmi->bmiHeader);
445 pbmi->bmiHeader.biBitCount = 8;
446 pbmi->bmiHeader.biCompression = BI_RLE8;
447 SetLastError(0xdeadbeef);
448 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
449 ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
450 ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
452 pbmi->bmiHeader.biBitCount = 16;
453 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
454 ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
455 ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
456 ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
457 SetLastError(0xdeadbeef);
458 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
459 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
461 /* test the DIB memory */
462 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
463 "VirtualQuery failed\n");
464 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
465 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
466 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
467 ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
468 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
469 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
470 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
472 test_dib_info(hdib, bits, &pbmi->bmiHeader);
475 memset(pbmi, 0, sizeof(bmibuf));
476 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
477 pbmi->bmiHeader.biHeight = 16;
478 pbmi->bmiHeader.biWidth = 16;
479 pbmi->bmiHeader.biBitCount = 1;
480 pbmi->bmiHeader.biPlanes = 1;
481 pbmi->bmiHeader.biCompression = BI_RGB;
482 pbmi->bmiColors[0].rgbRed = 0xff;
483 pbmi->bmiColors[0].rgbGreen = 0;
484 pbmi->bmiColors[0].rgbBlue = 0;
485 pbmi->bmiColors[1].rgbRed = 0;
486 pbmi->bmiColors[1].rgbGreen = 0;
487 pbmi->bmiColors[1].rgbBlue = 0xff;
489 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
490 ok(hdib != NULL, "CreateDIBSection failed\n");
491 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
492 ok(dibsec.dsBmih.biClrUsed == 2,
493 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
495 /* Test if the old BITMAPCOREINFO structure is supported */
497 pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
498 pbci->bmciHeader.bcBitCount = 0;
501 ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
502 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
503 ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
504 && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
505 "GetDIBits did't fill in the BITMAPCOREHEADER structure properly\n");
507 ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
508 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
509 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
510 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
511 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
512 "The color table has not been translated to the old BITMAPCOREINFO format\n");
514 hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
515 ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
517 ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
518 ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
519 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
520 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
521 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
522 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
523 "The color table has not been translated to the old BITMAPCOREINFO format\n");
525 DeleteObject(hcoredib);
528 hdcmem = CreateCompatibleDC(hdc);
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 c0 = RGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen, pbmi->bmiColors[0].rgbBlue);
539 c1 = RGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen, pbmi->bmiColors[1].rgbBlue);
541 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
542 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
543 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
544 test_color(hdcmem, PALETTEINDEX(0), c0, 1, 1);
545 test_color(hdcmem, PALETTEINDEX(1), c0, 1, 1);
546 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
547 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen,
548 pbmi->bmiColors[0].rgbBlue), c0, 1, 1);
549 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen,
550 pbmi->bmiColors[1].rgbBlue), c1, 1, 1);
551 test_color(hdcmem, PALETTERGB(0, 0, 0), c0, 1, 1);
552 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
553 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1, 1, 1);
555 SelectObject(hdcmem, oldbm);
558 pbmi->bmiColors[0].rgbRed = 0xff;
559 pbmi->bmiColors[0].rgbGreen = 0xff;
560 pbmi->bmiColors[0].rgbBlue = 0xff;
561 pbmi->bmiColors[1].rgbRed = 0;
562 pbmi->bmiColors[1].rgbGreen = 0;
563 pbmi->bmiColors[1].rgbBlue = 0;
565 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
566 ok(hdib != NULL, "CreateDIBSection failed\n");
568 test_dib_info(hdib, bits, &pbmi->bmiHeader);
570 oldbm = SelectObject(hdcmem, hdib);
572 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
573 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
574 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
575 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
576 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
577 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
579 SelectObject(hdcmem, oldbm);
580 test_dib_info(hdib, bits, &pbmi->bmiHeader);
583 pbmi->bmiHeader.biBitCount = 4;
584 for (i = 0; i < 16; i++) {
585 pbmi->bmiColors[i].rgbRed = i;
586 pbmi->bmiColors[i].rgbGreen = 16-i;
587 pbmi->bmiColors[i].rgbBlue = 0;
589 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
590 ok(hdib != NULL, "CreateDIBSection failed\n");
591 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
592 ok(dibsec.dsBmih.biClrUsed == 16,
593 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
594 test_dib_info(hdib, bits, &pbmi->bmiHeader);
597 pbmi->bmiHeader.biBitCount = 8;
599 for (i = 0; i < 128; i++) {
600 pbmi->bmiColors[i].rgbRed = 255 - i * 2;
601 pbmi->bmiColors[i].rgbGreen = i * 2;
602 pbmi->bmiColors[i].rgbBlue = 0;
603 pbmi->bmiColors[255 - i].rgbRed = 0;
604 pbmi->bmiColors[255 - i].rgbGreen = i * 2;
605 pbmi->bmiColors[255 - i].rgbBlue = 255 - i * 2;
607 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
608 ok(hdib != NULL, "CreateDIBSection failed\n");
609 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
610 ok(dibsec.dsBmih.biClrUsed == 256,
611 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
613 oldbm = SelectObject(hdcmem, hdib);
615 for (i = 0; i < 256; i++) {
616 test_color(hdcmem, DIBINDEX(i),
617 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
618 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue),
619 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
622 SelectObject(hdcmem, oldbm);
623 test_dib_info(hdib, bits, &pbmi->bmiHeader);
626 pbmi->bmiHeader.biBitCount = 1;
628 /* Now create a palette and a palette indexed dib section */
629 memset(plogpal, 0, sizeof(logpalbuf));
630 plogpal->palVersion = 0x300;
631 plogpal->palNumEntries = 2;
632 plogpal->palPalEntry[0].peRed = 0xff;
633 plogpal->palPalEntry[0].peBlue = 0xff;
634 plogpal->palPalEntry[1].peGreen = 0xff;
636 index = (WORD*)pbmi->bmiColors;
639 hpal = CreatePalette(plogpal);
640 ok(hpal != NULL, "CreatePalette failed\n");
641 oldpal = SelectPalette(hdc, hpal, TRUE);
642 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
643 ok(hdib != NULL, "CreateDIBSection failed\n");
644 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
645 ok(dibsec.dsBmih.biClrUsed == 2,
646 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
648 /* The colour table has already been grabbed from the dc, so we select back the
651 SelectPalette(hdc, oldpal, TRUE);
652 oldbm = SelectObject(hdcmem, hdib);
653 oldpal = SelectPalette(hdcmem, hpal, TRUE);
655 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
656 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
657 ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
658 rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
659 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
660 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
661 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
663 c0 = RGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen, plogpal->palPalEntry[0].peBlue);
664 c1 = RGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen, plogpal->palPalEntry[1].peBlue);
666 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
667 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
668 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
669 test_color(hdcmem, PALETTEINDEX(0), c0, 0, 1);
670 test_color(hdcmem, PALETTEINDEX(1), c1, 0, 1);
671 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
672 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen,
673 plogpal->palPalEntry[0].peBlue), c0, 1, 1);
674 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen,
675 plogpal->palPalEntry[1].peBlue), c1, 1, 1);
676 test_color(hdcmem, PALETTERGB(0, 0, 0), c1, 1, 1);
677 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
678 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0, 1, 1);
679 test_color(hdcmem, PALETTERGB(0, 1, 0), c1, 1, 1);
680 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1, 1, 1);
681 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0, 1, 1);
683 /* Bottom and 2nd row from top green, everything else magenta */
684 bits[0] = bits[1] = 0xff;
685 bits[13 * 4] = bits[13*4 + 1] = 0xff;
687 test_dib_info(hdib, bits, &pbmi->bmiHeader);
689 pbmi->bmiHeader.biBitCount = 32;
691 hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
692 ok(hdib2 != NULL, "CreateDIBSection failed\n");
693 hdcmem2 = CreateCompatibleDC(hdc);
694 oldbm2 = SelectObject(hdcmem2, hdib2);
696 BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
698 ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
699 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
701 SelectObject(hdcmem2, oldbm2);
702 test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
705 SelectObject(hdcmem, oldbm);
706 SelectObject(hdcmem, oldpal);
711 pbmi->bmiHeader.biBitCount = 8;
713 memset(plogpal, 0, sizeof(logpalbuf));
714 plogpal->palVersion = 0x300;
715 plogpal->palNumEntries = 256;
717 for (i = 0; i < 128; i++) {
718 plogpal->palPalEntry[i].peRed = 255 - i * 2;
719 plogpal->palPalEntry[i].peBlue = i * 2;
720 plogpal->palPalEntry[i].peGreen = 0;
721 plogpal->palPalEntry[255 - i].peRed = 0;
722 plogpal->palPalEntry[255 - i].peGreen = i * 2;
723 plogpal->palPalEntry[255 - i].peBlue = 255 - i * 2;
726 index = (WORD*)pbmi->bmiColors;
727 for (i = 0; i < 256; i++) {
731 hpal = CreatePalette(plogpal);
732 ok(hpal != NULL, "CreatePalette failed\n");
733 oldpal = SelectPalette(hdc, hpal, TRUE);
734 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
735 ok(hdib != NULL, "CreateDIBSection failed\n");
736 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
737 ok(dibsec.dsBmih.biClrUsed == 256,
738 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
740 test_dib_info(hdib, bits, &pbmi->bmiHeader);
742 SelectPalette(hdc, oldpal, TRUE);
743 oldbm = SelectObject(hdcmem, hdib);
744 oldpal = SelectPalette(hdcmem, hpal, TRUE);
746 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
747 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
748 for (i = 0; i < 256; i++) {
749 ok(rgb[i].rgbRed == plogpal->palPalEntry[i].peRed &&
750 rgb[i].rgbBlue == plogpal->palPalEntry[i].peBlue &&
751 rgb[i].rgbGreen == plogpal->palPalEntry[i].peGreen,
752 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
753 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
756 for (i = 0; i < 256; i++) {
757 test_color(hdcmem, DIBINDEX(i),
758 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
759 test_color(hdcmem, PALETTEINDEX(i),
760 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
761 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue),
762 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
765 SelectPalette(hdcmem, oldpal, TRUE);
766 SelectObject(hdcmem, oldbm);
775 static void test_mono_dibsection(void)
778 HBITMAP old_bm, mono_ds;
779 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
780 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
787 memdc = CreateCompatibleDC(hdc);
789 memset(pbmi, 0, sizeof(bmibuf));
790 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
791 pbmi->bmiHeader.biHeight = 10;
792 pbmi->bmiHeader.biWidth = 10;
793 pbmi->bmiHeader.biBitCount = 1;
794 pbmi->bmiHeader.biPlanes = 1;
795 pbmi->bmiHeader.biCompression = BI_RGB;
796 pbmi->bmiColors[0].rgbRed = 0xff;
797 pbmi->bmiColors[0].rgbGreen = 0xff;
798 pbmi->bmiColors[0].rgbBlue = 0xff;
799 pbmi->bmiColors[1].rgbRed = 0x0;
800 pbmi->bmiColors[1].rgbGreen = 0x0;
801 pbmi->bmiColors[1].rgbBlue = 0x0;
804 * First dib section is 'inverted' ie color[0] is white, color[1] is black
807 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
808 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
809 old_bm = SelectObject(memdc, mono_ds);
811 /* black border, white interior */
812 Rectangle(memdc, 0, 0, 10, 10);
813 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
814 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
816 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
818 memset(bits, 0, sizeof(bits));
821 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
822 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
824 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
826 pbmi->bmiColors[0].rgbRed = 0x0;
827 pbmi->bmiColors[0].rgbGreen = 0x0;
828 pbmi->bmiColors[0].rgbBlue = 0x0;
829 pbmi->bmiColors[1].rgbRed = 0xff;
830 pbmi->bmiColors[1].rgbGreen = 0xff;
831 pbmi->bmiColors[1].rgbBlue = 0xff;
833 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
834 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
836 SelectObject(memdc, old_bm);
837 DeleteObject(mono_ds);
840 * Next dib section is 'normal' ie color[0] is black, color[1] is white
843 pbmi->bmiColors[0].rgbRed = 0x0;
844 pbmi->bmiColors[0].rgbGreen = 0x0;
845 pbmi->bmiColors[0].rgbBlue = 0x0;
846 pbmi->bmiColors[1].rgbRed = 0xff;
847 pbmi->bmiColors[1].rgbGreen = 0xff;
848 pbmi->bmiColors[1].rgbBlue = 0xff;
850 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
851 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
852 old_bm = SelectObject(memdc, mono_ds);
854 /* black border, white interior */
855 Rectangle(memdc, 0, 0, 10, 10);
856 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
857 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
859 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
861 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
862 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
864 /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
866 pbmi->bmiColors[0].rgbRed = 0xff;
867 pbmi->bmiColors[0].rgbGreen = 0xff;
868 pbmi->bmiColors[0].rgbBlue = 0xff;
869 pbmi->bmiColors[1].rgbRed = 0x0;
870 pbmi->bmiColors[1].rgbGreen = 0x0;
871 pbmi->bmiColors[1].rgbBlue = 0x0;
873 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
874 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
877 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
880 pbmi->bmiColors[0].rgbRed = 0xff;
881 pbmi->bmiColors[0].rgbGreen = 0xff;
882 pbmi->bmiColors[0].rgbBlue = 0xff;
883 pbmi->bmiColors[1].rgbRed = 0x0;
884 pbmi->bmiColors[1].rgbGreen = 0x0;
885 pbmi->bmiColors[1].rgbBlue = 0x0;
886 num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors);
887 ok(num == 2, "num = %d\n", num);
889 /* black border, white interior */
890 Rectangle(memdc, 0, 0, 10, 10);
892 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
893 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
895 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
897 memset(bits, 0, sizeof(bits));
900 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
901 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
903 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
905 pbmi->bmiColors[0].rgbRed = 0x0;
906 pbmi->bmiColors[0].rgbGreen = 0x0;
907 pbmi->bmiColors[0].rgbBlue = 0x0;
908 pbmi->bmiColors[1].rgbRed = 0xff;
909 pbmi->bmiColors[1].rgbGreen = 0xff;
910 pbmi->bmiColors[1].rgbBlue = 0xff;
912 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
913 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
915 SelectObject(memdc, old_bm);
916 DeleteObject(mono_ds);
919 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
922 pbmi->bmiColors[0].rgbRed = 0xff;
923 pbmi->bmiColors[0].rgbGreen = 0x0;
924 pbmi->bmiColors[0].rgbBlue = 0x0;
925 pbmi->bmiColors[1].rgbRed = 0xfe;
926 pbmi->bmiColors[1].rgbGreen = 0x0;
927 pbmi->bmiColors[1].rgbBlue = 0x0;
929 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
930 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
931 old_bm = SelectObject(memdc, mono_ds);
933 /* black border, white interior */
934 Rectangle(memdc, 0, 0, 10, 10);
935 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
936 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
938 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
940 pbmi->bmiColors[0].rgbRed = 0x0;
941 pbmi->bmiColors[0].rgbGreen = 0x0;
942 pbmi->bmiColors[0].rgbBlue = 0x0;
943 pbmi->bmiColors[1].rgbRed = 0xff;
944 pbmi->bmiColors[1].rgbGreen = 0xff;
945 pbmi->bmiColors[1].rgbBlue = 0xff;
947 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
948 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
950 /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
952 pbmi->bmiColors[0].rgbRed = 0xff;
953 pbmi->bmiColors[0].rgbGreen = 0xff;
954 pbmi->bmiColors[0].rgbBlue = 0xff;
955 pbmi->bmiColors[1].rgbRed = 0x0;
956 pbmi->bmiColors[1].rgbGreen = 0x0;
957 pbmi->bmiColors[1].rgbBlue = 0x0;
959 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
960 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
962 SelectObject(memdc, old_bm);
963 DeleteObject(mono_ds);
969 static void test_bitmap(void)
971 char buf[256], buf_cmp[256];
972 HBITMAP hbmp, hbmp_old;
977 hdc = CreateCompatibleDC(0);
980 SetLastError(0xdeadbeef);
981 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
984 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
985 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
986 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
991 SetLastError(0xdeadbeef);
992 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
995 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
996 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
997 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1002 SetLastError(0xdeadbeef);
1003 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1004 ok(!hbmp, "CreateBitmap should fail\n");
1005 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1006 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1008 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1009 assert(hbmp != NULL);
1011 ret = GetObject(hbmp, sizeof(bm), &bm);
1012 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1014 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1015 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1016 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1017 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1018 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1019 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1020 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1022 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1023 assert(sizeof(buf) == sizeof(buf_cmp));
1025 ret = GetBitmapBits(hbmp, 0, NULL);
1026 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1028 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1029 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1031 memset(buf, 0xAA, sizeof(buf));
1032 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1033 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1034 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1036 hbmp_old = SelectObject(hdc, hbmp);
1038 ret = GetObject(hbmp, sizeof(bm), &bm);
1039 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1041 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1042 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1043 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1044 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1045 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1046 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1047 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1049 memset(buf, 0xAA, sizeof(buf));
1050 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1051 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1052 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1054 hbmp_old = SelectObject(hdc, hbmp_old);
1055 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1057 /* test various buffer sizes for GetObject */
1058 ret = GetObject(hbmp, sizeof(bm) * 2, &bm);
1059 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1061 ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1062 ok(ret == 0, "%d != 0\n", ret);
1064 ret = GetObject(hbmp, 0, &bm);
1065 ok(ret == 0, "%d != 0\n", ret);
1067 ret = GetObject(hbmp, 1, &bm);
1068 ok(ret == 0, "%d != 0\n", ret);
1074 static void test_bmBits(void)
1080 memset(bits, 0, sizeof(bits));
1081 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1082 ok(hbmp != NULL, "CreateBitmap failed\n");
1084 memset(&bmp, 0xFF, sizeof(bmp));
1085 ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1086 "GetObject failed or returned a wrong structure size\n");
1087 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1092 static void test_GetDIBits_selected_DIB(UINT bpp)
1106 /* Create a DIB section with a color table */
1108 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD));
1109 info2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD));
1113 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1115 /* Choose width and height such that the row length (in bytes)
1116 is a multiple of 4 (makes things easier) */
1117 info->bmiHeader.biWidth = 32;
1118 info->bmiHeader.biHeight = 32;
1119 info->bmiHeader.biPlanes = 1;
1120 info->bmiHeader.biBitCount = bpp;
1121 info->bmiHeader.biCompression = BI_RGB;
1123 for (i=0; i < (1u << bpp); i++)
1125 BYTE c = i * (1 << (8 - bpp));
1126 info->bmiColors[i].rgbRed = c;
1127 info->bmiColors[i].rgbGreen = c;
1128 info->bmiColors[i].rgbBlue = c;
1129 info->bmiColors[i].rgbReserved = 0;
1132 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1134 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1136 /* Set the bits of the DIB section */
1137 for (i=0; i < dib_size; i++)
1139 ((BYTE *)bits)[i] = i % 256;
1142 /* Select the DIB into a DC */
1143 dib_dc = CreateCompatibleDC(NULL);
1144 old_bmp = (HBITMAP) SelectObject(dib_dc, dib);
1145 dc = CreateCompatibleDC(NULL);
1146 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib_size);
1149 /* Copy the DIB attributes but not the color table */
1150 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1152 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1153 ok(res, "GetDIBits failed\n");
1155 /* Compare the color table and the bits */
1156 equalContents = TRUE;
1157 for (i=0; i < (1u << bpp); i++)
1159 if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed)
1160 || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen)
1161 || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue)
1162 || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved))
1164 equalContents = FALSE;
1168 ok(equalContents, "GetDIBits with DIB selected in DC: Invalid DIB color table\n");
1170 equalContents = TRUE;
1171 for (i=0; i < dib_size / sizeof(DWORD); i++)
1173 if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i])
1175 equalContents = FALSE;
1180 ok(equalContents, "GetDIBits with %d bpp DIB selected in DC: Invalid DIB bits\n",bpp);
1182 todo_wine ok(equalContents, "GetDIBits with %d bpp DIB selected in DC: Invalid DIB bits\n",bpp);
1184 HeapFree(GetProcessHeap(), 0, bits2);
1187 SelectObject(dib_dc, old_bmp);
1191 HeapFree(GetProcessHeap(), 0, info2);
1192 HeapFree(GetProcessHeap(), 0, info);
1195 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1210 width = height = 16;
1212 /* Create a DDB (device-dependent bitmap) */
1216 ddb = CreateBitmap(width, height, 1, 1, NULL);
1220 HDC screen_dc = GetDC(NULL);
1221 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1222 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1223 ReleaseDC(NULL, screen_dc);
1226 /* Set the pixels */
1227 ddb_dc = CreateCompatibleDC(NULL);
1228 old_bmp = (HBITMAP) SelectObject(ddb_dc, ddb);
1229 for (i = 0; i < width; i++)
1231 for (j=0; j < height; j++)
1233 BYTE c = (i * width + j) % 256;
1234 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1237 SelectObject(ddb_dc, old_bmp);
1239 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1240 info2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1244 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1245 info->bmiHeader.biWidth = width;
1246 info->bmiHeader.biHeight = height;
1247 info->bmiHeader.biPlanes = 1;
1248 info->bmiHeader.biBitCount = bpp;
1249 info->bmiHeader.biCompression = BI_RGB;
1251 dc = CreateCompatibleDC(NULL);
1253 /* Fill in biSizeImage */
1254 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1255 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1257 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1258 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1263 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1264 ok(res, "GetDIBits failed\n");
1266 /* Copy the DIB attributes but not the color table */
1267 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1269 /* Select the DDB into another DC */
1270 old_bmp = (HBITMAP) SelectObject(ddb_dc, ddb);
1273 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1274 ok(res, "GetDIBits failed\n");
1276 /* Compare the color table and the bits */
1279 equalContents = TRUE;
1280 for (i=0; i < (1u << bpp); i++)
1282 if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed)
1283 || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen)
1284 || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue)
1285 || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved))
1287 equalContents = FALSE;
1291 ok(equalContents, "GetDIBits with DDB selected in DC: Got a different color table\n");
1294 equalContents = TRUE;
1295 for (i=0; i < info->bmiHeader.biSizeImage / sizeof(DWORD); i++)
1297 if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i])
1299 equalContents = FALSE;
1302 ok(equalContents, "GetDIBits with DDB selected in DC: Got different DIB bits\n");
1304 HeapFree(GetProcessHeap(), 0, bits2);
1305 HeapFree(GetProcessHeap(), 0, bits);
1308 SelectObject(ddb_dc, old_bmp);
1312 HeapFree(GetProcessHeap(), 0, info2);
1313 HeapFree(GetProcessHeap(), 0, info);
1316 static void test_GetDIBits(void)
1318 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1319 static const BYTE bmp_bits_1[16 * 2] =
1321 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1322 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1323 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1324 0xff,0xff, 0,0, 0xff,0xff, 0,0
1326 /* 4-bytes aligned 1-bit DIB data: 16x16 */
1327 static const BYTE dib_bits_1[16 * 4] =
1329 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1330 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1331 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1332 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1334 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1335 static const BYTE bmp_bits_24[16 * 16*3] =
1337 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1338 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1339 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1340 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1341 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1342 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1343 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1344 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1345 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1346 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1347 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1348 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1349 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1350 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1351 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1352 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1353 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1354 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1355 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1356 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1357 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1358 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1359 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1360 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1361 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1362 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1363 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1364 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1365 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1366 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1367 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1368 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1370 /* 4-bytes aligned 24-bit DIB data: 16x16 */
1371 static const BYTE dib_bits_24[16 * 16*3] =
1373 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1374 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1375 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1376 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1377 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1378 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1379 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1380 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1381 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1382 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1383 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1384 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1385 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1386 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1387 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1388 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1389 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1390 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1391 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1392 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1393 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1394 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1395 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1396 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1397 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1398 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1399 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1400 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1401 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1402 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1403 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1404 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1409 int i, bytes, lines;
1411 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1412 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1416 /* 1-bit source bitmap data */
1417 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1418 ok(hbmp != 0, "CreateBitmap failed\n");
1420 memset(&bm, 0xAA, sizeof(bm));
1421 bytes = GetObject(hbmp, sizeof(bm), &bm);
1422 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1423 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1424 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1425 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1426 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1427 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1428 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1429 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1431 bytes = GetBitmapBits(hbmp, 0, NULL);
1432 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1433 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1434 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1435 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1437 /* retrieve 1-bit DIB data */
1438 memset(bi, 0, sizeof(*bi));
1439 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1440 bi->bmiHeader.biWidth = bm.bmWidth;
1441 bi->bmiHeader.biHeight = bm.bmHeight;
1442 bi->bmiHeader.biPlanes = 1;
1443 bi->bmiHeader.biBitCount = 1;
1444 bi->bmiHeader.biCompression = BI_RGB;
1445 bi->bmiHeader.biSizeImage = 0;
1446 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1447 SetLastError(0xdeadbeef);
1448 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1449 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1450 ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
1451 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1453 memset(buf, 0xAA, sizeof(buf));
1454 SetLastError(0xdeadbeef);
1455 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1456 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1457 lines, bm.bmHeight, GetLastError());
1458 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1460 /* the color table consists of black and white */
1461 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1462 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1463 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1464 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1465 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1467 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1468 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1469 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1470 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1471 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1472 for (i = 2; i < 256; i++)
1474 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1475 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1476 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1477 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1478 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1481 /* returned bits are DWORD aligned and upside down */
1483 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1485 /* retrieve 24-bit DIB data */
1486 memset(bi, 0, sizeof(*bi));
1487 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1488 bi->bmiHeader.biWidth = bm.bmWidth;
1489 bi->bmiHeader.biHeight = bm.bmHeight;
1490 bi->bmiHeader.biPlanes = 1;
1491 bi->bmiHeader.biBitCount = 24;
1492 bi->bmiHeader.biCompression = BI_RGB;
1493 bi->bmiHeader.biSizeImage = 0;
1494 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1495 memset(buf, 0xAA, sizeof(buf));
1496 SetLastError(0xdeadbeef);
1497 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1498 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1499 lines, bm.bmHeight, GetLastError());
1500 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1502 /* the color table doesn't exist for 24-bit images */
1503 for (i = 0; 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 */
1514 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1517 /* 24-bit source bitmap data */
1518 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1519 ok(hbmp != 0, "CreateBitmap failed\n");
1520 SetLastError(0xdeadbeef);
1521 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1522 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1523 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1524 lines, bm.bmHeight, GetLastError());
1526 memset(&bm, 0xAA, sizeof(bm));
1527 bytes = GetObject(hbmp, sizeof(bm), &bm);
1528 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1529 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1530 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1531 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1532 ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1533 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1534 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1535 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1537 bytes = GetBitmapBits(hbmp, 0, NULL);
1538 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1539 bm.bmWidthBytes * bm.bmHeight, bytes);
1540 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1541 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1542 bm.bmWidthBytes * bm.bmHeight, bytes);
1544 /* retrieve 1-bit DIB data */
1545 memset(bi, 0, sizeof(*bi));
1546 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1547 bi->bmiHeader.biWidth = bm.bmWidth;
1548 bi->bmiHeader.biHeight = bm.bmHeight;
1549 bi->bmiHeader.biPlanes = 1;
1550 bi->bmiHeader.biBitCount = 1;
1551 bi->bmiHeader.biCompression = BI_RGB;
1552 bi->bmiHeader.biSizeImage = 0;
1553 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1554 memset(buf, 0xAA, sizeof(buf));
1555 SetLastError(0xdeadbeef);
1556 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1557 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1558 lines, bm.bmHeight, GetLastError());
1559 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1561 /* the color table consists of black and white */
1562 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1563 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1564 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1565 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1566 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1567 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1568 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1569 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1570 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1571 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1572 for (i = 2; i < 256; i++)
1574 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1575 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1576 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1577 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1578 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1581 /* returned bits are DWORD aligned and upside down */
1583 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1585 /* retrieve 24-bit DIB data */
1586 memset(bi, 0, sizeof(*bi));
1587 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1588 bi->bmiHeader.biWidth = bm.bmWidth;
1589 bi->bmiHeader.biHeight = bm.bmHeight;
1590 bi->bmiHeader.biPlanes = 1;
1591 bi->bmiHeader.biBitCount = 24;
1592 bi->bmiHeader.biCompression = BI_RGB;
1593 bi->bmiHeader.biSizeImage = 0;
1594 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1595 memset(buf, 0xAA, sizeof(buf));
1596 SetLastError(0xdeadbeef);
1597 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1598 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1599 lines, bm.bmHeight, GetLastError());
1600 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1602 /* the color table doesn't exist for 24-bit images */
1603 for (i = 0; i < 256; i++)
1605 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1606 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1607 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1608 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1609 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1612 /* returned bits are DWORD aligned and upside down */
1613 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1619 static void test_GetDIBits_BI_BITFIELDS(void)
1621 /* Try a screen resolution detection technique
1622 * from the September 1999 issue of Windows Developer's Journal
1623 * which seems to be in widespread use.
1624 * http://www.lesher.ws/highcolor.html
1625 * http://www.lesher.ws/vidfmt.c
1626 * It hinges on being able to retrieve the bitmaps
1627 * for the three primary colors in non-paletted 16 bit mode.
1629 char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
1631 LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
1636 memset(dibinfo, 0, sizeof(dibinfo_buf));
1637 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1640 ok(hdc != NULL, "GetDC failed?\n");
1641 hbm = CreateCompatibleBitmap(hdc, 1, 1);
1642 ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
1644 /* Call GetDIBits to fill in bmiHeader. */
1645 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1646 ok(ret == 1, "GetDIBits failed\n");
1647 if (dibinfo->bmiHeader.biBitCount > 8)
1649 DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
1651 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
1652 "compression is %u\n", dibinfo->bmiHeader.biCompression );
1654 ok( !bitmasks[0], "red mask is set\n" );
1655 ok( !bitmasks[1], "green mask is set\n" );
1656 ok( !bitmasks[2], "blue mask is set\n" );
1658 /* test with NULL bits pointer and correct bpp */
1659 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1660 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1661 ok(ret == 1, "GetDIBits failed\n");
1663 ok( bitmasks[0] != 0, "red mask is not set\n" );
1664 ok( bitmasks[1] != 0, "green mask is not set\n" );
1665 ok( bitmasks[2] != 0, "blue mask is not set\n" );
1666 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1668 /* test with valid bits pointer */
1669 memset(dibinfo, 0, sizeof(dibinfo_buf));
1670 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1671 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1672 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1673 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1674 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
1675 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1677 ok( bitmasks[0] != 0, "red mask is not set\n" );
1678 ok( bitmasks[1] != 0, "green mask is not set\n" );
1679 ok( bitmasks[2] != 0, "blue mask is not set\n" );
1680 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1682 /* now with bits and 0 lines */
1683 memset(dibinfo, 0, sizeof(dibinfo_buf));
1684 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1685 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1686 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
1688 ok( !bitmasks[0], "red mask is set\n" );
1689 ok( !bitmasks[1], "green mask is set\n" );
1690 ok( !bitmasks[2], "blue mask is set\n" );
1691 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1693 memset(bitmasks, 0, 3*sizeof(DWORD));
1694 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1695 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
1696 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1698 ok( bitmasks[0] != 0, "red mask is not set\n" );
1699 ok( bitmasks[1] != 0, "green mask is not set\n" );
1700 ok( bitmasks[2] != 0, "blue mask is not set\n" );
1701 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1703 else skip("not in 16 bpp BI_BITFIELDS mode, skipping that test\n");
1706 ReleaseDC(NULL, hdc);
1709 static void test_select_object(void)
1712 HBITMAP hbm, hbm_old;
1714 DWORD depths[] = {8, 15, 16, 24, 32};
1719 ok(hdc != 0, "GetDC(0) failed\n");
1720 hbm = CreateCompatibleBitmap(hdc, 10, 10);
1721 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
1723 hbm_old = SelectObject(hdc, hbm);
1724 ok(hbm_old == 0, "SelectObject should fail\n");
1729 hdc = CreateCompatibleDC(0);
1730 ok(hdc != 0, "GetDC(0) failed\n");
1731 hbm = CreateCompatibleBitmap(hdc, 10, 10);
1732 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
1734 hbm_old = SelectObject(hdc, hbm);
1735 ok(hbm_old != 0, "SelectObject failed\n");
1736 hbm_old = SelectObject(hdc, hbm_old);
1737 ok(hbm_old == hbm, "SelectObject failed\n");
1741 /* test an 1-bpp bitmap */
1742 planes = GetDeviceCaps(hdc, PLANES);
1745 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
1746 ok(hbm != 0, "CreateBitmap failed\n");
1748 hbm_old = SelectObject(hdc, hbm);
1749 ok(hbm_old != 0, "SelectObject failed\n");
1750 hbm_old = SelectObject(hdc, hbm_old);
1751 ok(hbm_old == hbm, "SelectObject failed\n");
1755 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
1756 /* test a color bitmap to dc bpp matching */
1757 planes = GetDeviceCaps(hdc, PLANES);
1758 bpp = GetDeviceCaps(hdc, BITSPIXEL);
1760 hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
1761 ok(hbm != 0, "CreateBitmap failed\n");
1763 hbm_old = SelectObject(hdc, hbm);
1764 if(depths[i] == bpp ||
1765 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
1767 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
1768 SelectObject(hdc, hbm_old);
1770 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
1773 memset(&bm, 0xAA, sizeof(bm));
1774 bytes = GetObject(hbm, sizeof(bm), &bm);
1775 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1776 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1777 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
1778 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
1779 ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1780 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
1781 if(depths[i] == 15) {
1782 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
1784 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1786 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1794 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
1799 ret = GetObjectType(hbmp);
1800 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
1802 ret = GetObject(hbmp, 0, 0);
1803 ok_(__FILE__, line)(ret == sizeof(BITMAP) /* XP */ ||
1804 ret == sizeof(DIBSECTION) /* Win9x */, "object size %d\n", ret);
1806 memset(&bm, 0xDA, sizeof(bm));
1807 SetLastError(0xdeadbeef);
1808 ret = GetObject(hbmp, sizeof(bm), &bm);
1809 if (!ret) /* XP, only for curObj2 */ return;
1810 ok_(__FILE__, line)(ret == sizeof(BITMAP) ||
1811 ret == sizeof(DIBSECTION) /* Win9x, only for curObj2 */,
1812 "GetObject returned %d, error %u\n", ret, GetLastError());
1813 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
1814 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
1815 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
1816 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
1817 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
1818 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
1819 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1822 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
1824 static void test_CreateBitmap(void)
1827 HDC screenDC = GetDC(0);
1828 HDC hdc = CreateCompatibleDC(screenDC);
1831 /* all of these are the stock monochrome bitmap */
1832 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
1833 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
1834 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
1835 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
1836 HBITMAP curObj1 = (HBITMAP)GetCurrentObject(hdc, OBJ_BITMAP);
1837 HBITMAP curObj2 = (HBITMAP)GetCurrentObject(screenDC, OBJ_BITMAP);
1839 /* these 2 are not the stock monochrome bitmap */
1840 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
1841 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
1843 HBITMAP old1 = (HBITMAP)SelectObject(hdc, bm2);
1844 HBITMAP old2 = (HBITMAP)SelectObject(screenDC, bm3);
1845 SelectObject(hdc, old1);
1846 SelectObject(screenDC, old2);
1848 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
1849 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
1850 bm, bm1, bm4, bm5, curObj1, old1);
1851 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
1852 ok(bm != curObj2 /* XP */ || bm == curObj2 /* Win9x */,
1853 "0: %p, curObj2 %p\n", bm, curObj2);
1854 ok(old2 == 0, "old2 %p\n", old2);
1856 test_mono_1x1_bmp(bm);
1857 test_mono_1x1_bmp(bm1);
1858 test_mono_1x1_bmp(bm2);
1859 test_mono_1x1_bmp(bm3);
1860 test_mono_1x1_bmp(bm4);
1861 test_mono_1x1_bmp(bm5);
1862 test_mono_1x1_bmp(old1);
1863 test_mono_1x1_bmp(curObj1);
1864 test_mono_1x1_bmp(curObj2);
1874 ReleaseDC(0, screenDC);
1876 /* show that Windows ignores the provided bm.bmWidthBytes */
1880 bmp.bmWidthBytes = 28;
1882 bmp.bmBitsPixel = 1;
1884 bm = CreateBitmapIndirect(&bmp);
1885 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
1886 test_mono_1x1_bmp(bm);
1889 /* Test how the bmBitsPixel field is treated */
1890 for(i = 1; i <= 33; i++) {
1894 bmp.bmWidthBytes = 28;
1896 bmp.bmBitsPixel = i;
1898 bm = CreateBitmapIndirect(&bmp);
1900 DWORD error = GetLastError();
1901 ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
1902 ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
1905 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
1906 GetObject(bm, sizeof(bmp), &bmp);
1913 } else if(i <= 16) {
1915 } else if(i <= 24) {
1917 } else if(i <= 32) {
1920 ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
1921 i, bmp.bmBitsPixel, expect);
1926 static void test_bitmapinfoheadersize(void)
1933 memset(&bmi, 0, sizeof(BITMAPINFO));
1934 bmi.bmiHeader.biHeight = 100;
1935 bmi.bmiHeader.biWidth = 512;
1936 bmi.bmiHeader.biBitCount = 24;
1937 bmi.bmiHeader.biPlanes = 1;
1939 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
1941 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1942 ok(hdib == NULL, "CreateDIBSection succeeded\n");
1944 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1946 SetLastError(0xdeadbeef);
1947 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1948 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1951 bmi.bmiHeader.biSize++;
1953 SetLastError(0xdeadbeef);
1954 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1955 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1958 bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
1960 SetLastError(0xdeadbeef);
1961 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1962 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1965 bmi.bmiHeader.biSize++;
1967 SetLastError(0xdeadbeef);
1968 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1969 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1972 bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
1974 SetLastError(0xdeadbeef);
1975 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1976 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1979 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
1981 SetLastError(0xdeadbeef);
1982 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1983 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1986 memset(&bci, 0, sizeof(BITMAPCOREINFO));
1987 bci.bmciHeader.bcHeight = 100;
1988 bci.bmciHeader.bcWidth = 512;
1989 bci.bmciHeader.bcBitCount = 24;
1990 bci.bmciHeader.bcPlanes = 1;
1992 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
1994 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
1995 ok(hdib == NULL, "CreateDIBSection succeeded\n");
1997 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
1999 SetLastError(0xdeadbeef);
2000 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2001 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2004 bci.bmciHeader.bcSize++;
2006 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2007 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2009 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2011 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2012 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2017 static void test_get16dibits(void)
2019 BYTE bits[4 * (16 / sizeof(BYTE))];
2021 HDC screen_dc = GetDC(NULL);
2024 int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2026 int overwritten_bytes = 0;
2028 memset(bits, 0, sizeof(bits));
2029 hbmp = CreateBitmap(2, 2, 1, 16, bits);
2030 ok(hbmp != NULL, "CreateBitmap failed\n");
2032 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2035 memset(info, '!', info_len);
2036 memset(info, 0, sizeof(info->bmiHeader));
2038 info->bmiHeader.biSize = sizeof(info->bmiHeader);
2039 info->bmiHeader.biWidth = 2;
2040 info->bmiHeader.biHeight = 2;
2041 info->bmiHeader.biPlanes = 1;
2042 info->bmiHeader.biCompression = BI_RGB;
2044 ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2045 ok(ret != 0, "GetDIBits failed\n");
2047 for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2049 overwritten_bytes++;
2050 ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2052 HeapFree(GetProcessHeap(), 0, info);
2054 ReleaseDC(NULL, screen_dc);
2057 void test_GdiAlphaBlend()
2059 /* test out-of-bound parameters for GdiAlphaBlend */
2072 BLENDFUNCTION blend;
2074 if (!pGdiAlphaBlend)
2076 skip("GdiAlphaBlend() is not implemented\n");
2080 hdcNull = GetDC(NULL);
2081 hdcDst = CreateCompatibleDC(hdcNull);
2082 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
2083 hdcSrc = CreateCompatibleDC(hdcNull);
2085 memset(&bmi, 0, sizeof(bmi)); /* as of Wine 0.9.44 we require the src to be a DIB section */
2086 bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
2087 bmi.bmiHeader.biHeight = 20;
2088 bmi.bmiHeader.biWidth = 20;
2089 bmi.bmiHeader.biBitCount = 32;
2090 bmi.bmiHeader.biPlanes = 1;
2091 bmi.bmiHeader.biCompression = BI_RGB;
2092 bmpSrc = CreateDIBSection(hdcDst, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
2093 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
2095 oldDst = (HBITMAP)SelectObject(hdcDst, bmpDst);
2096 oldSrc = (HBITMAP)SelectObject(hdcSrc, bmpSrc);
2098 blend.BlendOp = AC_SRC_OVER;
2099 blend.BlendFlags = 0;
2100 blend.SourceConstantAlpha = 128;
2101 blend.AlphaFormat = 0;
2103 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend), TRUE, BOOL, "%d");
2104 SetLastError(0xdeadbeef);
2105 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), FALSE, BOOL, "%d");
2106 expect_eq(GetLastError(), ERROR_INVALID_PARAMETER, int, "%d");
2107 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), FALSE, BOOL, "%d");
2108 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend), FALSE, BOOL, "%d");
2109 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
2110 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
2112 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
2113 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), TRUE, BOOL, "%d");
2114 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), TRUE, BOOL, "%d");
2115 SetMapMode(hdcSrc, MM_ANISOTROPIC);
2116 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
2117 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend), TRUE, BOOL, "%d");
2118 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend), TRUE, BOOL, "%d");
2120 SelectObject(hdcDst, oldDst);
2121 SelectObject(hdcSrc, oldSrc);
2122 DeleteObject(bmpSrc);
2123 DeleteObject(bmpDst);
2127 ReleaseDC(NULL, hdcNull);
2134 is_win9x = GetWindowLongPtrW(GetDesktopWindow(), GWLP_WNDPROC) == 0;
2136 hdll = GetModuleHandle("gdi32.dll");
2137 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
2139 test_createdibitmap();
2141 test_mono_dibsection();
2144 test_GetDIBits_selected_DIB(1);
2145 test_GetDIBits_selected_DIB(4);
2146 test_GetDIBits_selected_DIB(8);
2147 test_GetDIBits_selected_DDB(TRUE);
2148 test_GetDIBits_selected_DDB(FALSE);
2150 test_GetDIBits_BI_BITFIELDS();
2151 test_select_object();
2152 test_CreateBitmap();
2153 test_GdiAlphaBlend();
2154 test_bitmapinfoheadersize();