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);
419 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
420 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
421 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
422 ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
424 /* test the DIB memory */
425 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
426 "VirtualQuery failed\n");
427 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
428 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
429 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
430 ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
431 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
432 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
433 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
435 test_dib_info(hdib, bits, &pbmi->bmiHeader);
438 pbmi->bmiHeader.biBitCount = 8;
439 pbmi->bmiHeader.biCompression = BI_RLE8;
440 SetLastError(0xdeadbeef);
441 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
442 ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
443 ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
445 pbmi->bmiHeader.biBitCount = 16;
446 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
447 ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
448 ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
449 ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
450 SetLastError(0xdeadbeef);
451 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
452 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
454 /* test the DIB memory */
455 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
456 "VirtualQuery failed\n");
457 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
458 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
459 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
460 ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
461 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
462 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
463 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
465 test_dib_info(hdib, bits, &pbmi->bmiHeader);
468 memset(pbmi, 0, sizeof(bmibuf));
469 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
470 pbmi->bmiHeader.biHeight = 16;
471 pbmi->bmiHeader.biWidth = 16;
472 pbmi->bmiHeader.biBitCount = 1;
473 pbmi->bmiHeader.biPlanes = 1;
474 pbmi->bmiHeader.biCompression = BI_RGB;
475 pbmi->bmiColors[0].rgbRed = 0xff;
476 pbmi->bmiColors[0].rgbGreen = 0;
477 pbmi->bmiColors[0].rgbBlue = 0;
478 pbmi->bmiColors[1].rgbRed = 0;
479 pbmi->bmiColors[1].rgbGreen = 0;
480 pbmi->bmiColors[1].rgbBlue = 0xff;
482 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
483 ok(hdib != NULL, "CreateDIBSection failed\n");
484 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
485 ok(dibsec.dsBmih.biClrUsed == 2,
486 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
488 /* Test if the old BITMAPCOREINFO structure is supported */
490 pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
491 pbci->bmciHeader.bcBitCount = 0;
494 ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
495 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
496 ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
497 && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
498 "GetDIBits did't fill in the BITMAPCOREHEADER structure properly\n");
500 ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
501 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
502 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
503 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
504 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
505 "The color table has not been translated to the old BITMAPCOREINFO format\n");
507 hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
508 ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
510 ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
511 ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
512 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
513 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
514 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
515 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
516 "The color table has not been translated to the old BITMAPCOREINFO format\n");
518 DeleteObject(hcoredib);
521 hdcmem = CreateCompatibleDC(hdc);
522 oldbm = SelectObject(hdcmem, hdib);
524 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
525 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
526 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
527 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
528 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
529 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
531 c0 = RGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen, pbmi->bmiColors[0].rgbBlue);
532 c1 = RGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen, pbmi->bmiColors[1].rgbBlue);
534 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
535 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
536 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
537 test_color(hdcmem, PALETTEINDEX(0), c0, 1, 1);
538 test_color(hdcmem, PALETTEINDEX(1), c0, 1, 1);
539 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
540 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen,
541 pbmi->bmiColors[0].rgbBlue), c0, 1, 1);
542 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen,
543 pbmi->bmiColors[1].rgbBlue), c1, 1, 1);
544 test_color(hdcmem, PALETTERGB(0, 0, 0), c0, 1, 1);
545 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
546 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1, 1, 1);
548 SelectObject(hdcmem, oldbm);
551 pbmi->bmiColors[0].rgbRed = 0xff;
552 pbmi->bmiColors[0].rgbGreen = 0xff;
553 pbmi->bmiColors[0].rgbBlue = 0xff;
554 pbmi->bmiColors[1].rgbRed = 0;
555 pbmi->bmiColors[1].rgbGreen = 0;
556 pbmi->bmiColors[1].rgbBlue = 0;
558 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
559 ok(hdib != NULL, "CreateDIBSection failed\n");
561 test_dib_info(hdib, bits, &pbmi->bmiHeader);
563 oldbm = SelectObject(hdcmem, hdib);
565 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
566 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
567 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
568 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
569 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
570 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
572 SelectObject(hdcmem, oldbm);
573 test_dib_info(hdib, bits, &pbmi->bmiHeader);
576 pbmi->bmiHeader.biBitCount = 4;
577 for (i = 0; i < 16; i++) {
578 pbmi->bmiColors[i].rgbRed = i;
579 pbmi->bmiColors[i].rgbGreen = 16-i;
580 pbmi->bmiColors[i].rgbBlue = 0;
582 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
583 ok(hdib != NULL, "CreateDIBSection failed\n");
584 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
585 ok(dibsec.dsBmih.biClrUsed == 16,
586 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
587 test_dib_info(hdib, bits, &pbmi->bmiHeader);
590 pbmi->bmiHeader.biBitCount = 8;
592 for (i = 0; i < 128; i++) {
593 pbmi->bmiColors[i].rgbRed = 255 - i * 2;
594 pbmi->bmiColors[i].rgbGreen = i * 2;
595 pbmi->bmiColors[i].rgbBlue = 0;
596 pbmi->bmiColors[255 - i].rgbRed = 0;
597 pbmi->bmiColors[255 - i].rgbGreen = i * 2;
598 pbmi->bmiColors[255 - i].rgbBlue = 255 - i * 2;
600 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
601 ok(hdib != NULL, "CreateDIBSection failed\n");
602 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
603 ok(dibsec.dsBmih.biClrUsed == 256,
604 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
606 oldbm = SelectObject(hdcmem, hdib);
608 for (i = 0; i < 256; i++) {
609 test_color(hdcmem, DIBINDEX(i),
610 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
611 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue),
612 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
615 SelectObject(hdcmem, oldbm);
616 test_dib_info(hdib, bits, &pbmi->bmiHeader);
619 pbmi->bmiHeader.biBitCount = 1;
621 /* Now create a palette and a palette indexed dib section */
622 memset(plogpal, 0, sizeof(logpalbuf));
623 plogpal->palVersion = 0x300;
624 plogpal->palNumEntries = 2;
625 plogpal->palPalEntry[0].peRed = 0xff;
626 plogpal->palPalEntry[0].peBlue = 0xff;
627 plogpal->palPalEntry[1].peGreen = 0xff;
629 index = (WORD*)pbmi->bmiColors;
632 hpal = CreatePalette(plogpal);
633 ok(hpal != NULL, "CreatePalette failed\n");
634 oldpal = SelectPalette(hdc, hpal, TRUE);
635 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
636 ok(hdib != NULL, "CreateDIBSection failed\n");
637 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
638 ok(dibsec.dsBmih.biClrUsed == 2,
639 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
641 /* The colour table has already been grabbed from the dc, so we select back the
644 SelectPalette(hdc, oldpal, TRUE);
645 oldbm = SelectObject(hdcmem, hdib);
646 oldpal = SelectPalette(hdcmem, hpal, TRUE);
648 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
649 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
650 ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
651 rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
652 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
653 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
654 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
656 c0 = RGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen, plogpal->palPalEntry[0].peBlue);
657 c1 = RGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen, plogpal->palPalEntry[1].peBlue);
659 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
660 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
661 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
662 test_color(hdcmem, PALETTEINDEX(0), c0, 0, 1);
663 test_color(hdcmem, PALETTEINDEX(1), c1, 0, 1);
664 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
665 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen,
666 plogpal->palPalEntry[0].peBlue), c0, 1, 1);
667 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen,
668 plogpal->palPalEntry[1].peBlue), c1, 1, 1);
669 test_color(hdcmem, PALETTERGB(0, 0, 0), c1, 1, 1);
670 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
671 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0, 1, 1);
672 test_color(hdcmem, PALETTERGB(0, 1, 0), c1, 1, 1);
673 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1, 1, 1);
674 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0, 1, 1);
676 /* Bottom and 2nd row from top green, everything else magenta */
677 bits[0] = bits[1] = 0xff;
678 bits[13 * 4] = bits[13*4 + 1] = 0xff;
680 test_dib_info(hdib, bits, &pbmi->bmiHeader);
682 pbmi->bmiHeader.biBitCount = 32;
684 hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
685 ok(hdib2 != NULL, "CreateDIBSection failed\n");
686 hdcmem2 = CreateCompatibleDC(hdc);
687 oldbm2 = SelectObject(hdcmem2, hdib2);
689 BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
691 ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
692 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
694 SelectObject(hdcmem2, oldbm2);
695 test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
698 SelectObject(hdcmem, oldbm);
699 SelectObject(hdcmem, oldpal);
704 pbmi->bmiHeader.biBitCount = 8;
706 memset(plogpal, 0, sizeof(logpalbuf));
707 plogpal->palVersion = 0x300;
708 plogpal->palNumEntries = 256;
710 for (i = 0; i < 128; i++) {
711 plogpal->palPalEntry[i].peRed = 255 - i * 2;
712 plogpal->palPalEntry[i].peBlue = i * 2;
713 plogpal->palPalEntry[i].peGreen = 0;
714 plogpal->palPalEntry[255 - i].peRed = 0;
715 plogpal->palPalEntry[255 - i].peGreen = i * 2;
716 plogpal->palPalEntry[255 - i].peBlue = 255 - i * 2;
719 index = (WORD*)pbmi->bmiColors;
720 for (i = 0; i < 256; i++) {
724 hpal = CreatePalette(plogpal);
725 ok(hpal != NULL, "CreatePalette failed\n");
726 oldpal = SelectPalette(hdc, hpal, TRUE);
727 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
728 ok(hdib != NULL, "CreateDIBSection failed\n");
729 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
730 ok(dibsec.dsBmih.biClrUsed == 256,
731 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
733 test_dib_info(hdib, bits, &pbmi->bmiHeader);
735 SelectPalette(hdc, oldpal, TRUE);
736 oldbm = SelectObject(hdcmem, hdib);
737 oldpal = SelectPalette(hdcmem, hpal, TRUE);
739 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
740 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
741 for (i = 0; i < 256; i++) {
742 ok(rgb[i].rgbRed == plogpal->palPalEntry[i].peRed &&
743 rgb[i].rgbBlue == plogpal->palPalEntry[i].peBlue &&
744 rgb[i].rgbGreen == plogpal->palPalEntry[i].peGreen,
745 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
746 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
749 for (i = 0; i < 256; i++) {
750 test_color(hdcmem, DIBINDEX(i),
751 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
752 test_color(hdcmem, PALETTEINDEX(i),
753 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
754 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue),
755 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
758 SelectPalette(hdcmem, oldpal, TRUE);
759 SelectObject(hdcmem, oldbm);
768 static void test_mono_dibsection(void)
771 HBITMAP old_bm, mono_ds;
772 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
773 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
780 memdc = CreateCompatibleDC(hdc);
782 memset(pbmi, 0, sizeof(bmibuf));
783 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
784 pbmi->bmiHeader.biHeight = 10;
785 pbmi->bmiHeader.biWidth = 10;
786 pbmi->bmiHeader.biBitCount = 1;
787 pbmi->bmiHeader.biPlanes = 1;
788 pbmi->bmiHeader.biCompression = BI_RGB;
789 pbmi->bmiColors[0].rgbRed = 0xff;
790 pbmi->bmiColors[0].rgbGreen = 0xff;
791 pbmi->bmiColors[0].rgbBlue = 0xff;
792 pbmi->bmiColors[1].rgbRed = 0x0;
793 pbmi->bmiColors[1].rgbGreen = 0x0;
794 pbmi->bmiColors[1].rgbBlue = 0x0;
797 * First dib section is 'inverted' ie color[0] is white, color[1] is black
800 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
801 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
802 old_bm = SelectObject(memdc, mono_ds);
804 /* black border, white interior */
805 Rectangle(memdc, 0, 0, 10, 10);
806 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
807 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
809 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
811 memset(bits, 0, sizeof(bits));
814 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
815 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
817 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
819 pbmi->bmiColors[0].rgbRed = 0x0;
820 pbmi->bmiColors[0].rgbGreen = 0x0;
821 pbmi->bmiColors[0].rgbBlue = 0x0;
822 pbmi->bmiColors[1].rgbRed = 0xff;
823 pbmi->bmiColors[1].rgbGreen = 0xff;
824 pbmi->bmiColors[1].rgbBlue = 0xff;
826 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
827 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
829 SelectObject(memdc, old_bm);
830 DeleteObject(mono_ds);
833 * Next dib section is 'normal' ie color[0] is black, color[1] is white
836 pbmi->bmiColors[0].rgbRed = 0x0;
837 pbmi->bmiColors[0].rgbGreen = 0x0;
838 pbmi->bmiColors[0].rgbBlue = 0x0;
839 pbmi->bmiColors[1].rgbRed = 0xff;
840 pbmi->bmiColors[1].rgbGreen = 0xff;
841 pbmi->bmiColors[1].rgbBlue = 0xff;
843 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
844 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
845 old_bm = SelectObject(memdc, mono_ds);
847 /* black border, white interior */
848 Rectangle(memdc, 0, 0, 10, 10);
849 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
850 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
852 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
854 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
855 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
857 /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
859 pbmi->bmiColors[0].rgbRed = 0xff;
860 pbmi->bmiColors[0].rgbGreen = 0xff;
861 pbmi->bmiColors[0].rgbBlue = 0xff;
862 pbmi->bmiColors[1].rgbRed = 0x0;
863 pbmi->bmiColors[1].rgbGreen = 0x0;
864 pbmi->bmiColors[1].rgbBlue = 0x0;
866 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
867 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
870 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
873 pbmi->bmiColors[0].rgbRed = 0xff;
874 pbmi->bmiColors[0].rgbGreen = 0xff;
875 pbmi->bmiColors[0].rgbBlue = 0xff;
876 pbmi->bmiColors[1].rgbRed = 0x0;
877 pbmi->bmiColors[1].rgbGreen = 0x0;
878 pbmi->bmiColors[1].rgbBlue = 0x0;
879 num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors);
880 ok(num == 2, "num = %d\n", num);
882 /* black border, white interior */
883 Rectangle(memdc, 0, 0, 10, 10);
885 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
886 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
888 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
890 memset(bits, 0, sizeof(bits));
893 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
894 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
896 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
898 pbmi->bmiColors[0].rgbRed = 0x0;
899 pbmi->bmiColors[0].rgbGreen = 0x0;
900 pbmi->bmiColors[0].rgbBlue = 0x0;
901 pbmi->bmiColors[1].rgbRed = 0xff;
902 pbmi->bmiColors[1].rgbGreen = 0xff;
903 pbmi->bmiColors[1].rgbBlue = 0xff;
905 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
906 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
908 SelectObject(memdc, old_bm);
909 DeleteObject(mono_ds);
912 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
915 pbmi->bmiColors[0].rgbRed = 0xff;
916 pbmi->bmiColors[0].rgbGreen = 0x0;
917 pbmi->bmiColors[0].rgbBlue = 0x0;
918 pbmi->bmiColors[1].rgbRed = 0xfe;
919 pbmi->bmiColors[1].rgbGreen = 0x0;
920 pbmi->bmiColors[1].rgbBlue = 0x0;
922 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
923 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
924 old_bm = SelectObject(memdc, mono_ds);
926 /* black border, white interior */
927 Rectangle(memdc, 0, 0, 10, 10);
928 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
929 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
931 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
933 pbmi->bmiColors[0].rgbRed = 0x0;
934 pbmi->bmiColors[0].rgbGreen = 0x0;
935 pbmi->bmiColors[0].rgbBlue = 0x0;
936 pbmi->bmiColors[1].rgbRed = 0xff;
937 pbmi->bmiColors[1].rgbGreen = 0xff;
938 pbmi->bmiColors[1].rgbBlue = 0xff;
940 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
941 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
943 /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
945 pbmi->bmiColors[0].rgbRed = 0xff;
946 pbmi->bmiColors[0].rgbGreen = 0xff;
947 pbmi->bmiColors[0].rgbBlue = 0xff;
948 pbmi->bmiColors[1].rgbRed = 0x0;
949 pbmi->bmiColors[1].rgbGreen = 0x0;
950 pbmi->bmiColors[1].rgbBlue = 0x0;
952 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
953 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
955 SelectObject(memdc, old_bm);
956 DeleteObject(mono_ds);
962 static void test_bitmap(void)
964 char buf[256], buf_cmp[256];
965 HBITMAP hbmp, hbmp_old;
970 hdc = CreateCompatibleDC(0);
973 SetLastError(0xdeadbeef);
974 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
977 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY,
978 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
983 SetLastError(0xdeadbeef);
984 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
987 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
988 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
989 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
994 SetLastError(0xdeadbeef);
995 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
996 ok(!hbmp, "CreateBitmap should fail\n");
997 ok(GetLastError() == ERROR_INVALID_PARAMETER,
998 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1000 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1001 assert(hbmp != NULL);
1003 ret = GetObject(hbmp, sizeof(bm), &bm);
1004 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1006 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1007 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1008 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1009 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1010 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1011 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1012 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1014 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1015 assert(sizeof(buf) == sizeof(buf_cmp));
1017 ret = GetBitmapBits(hbmp, 0, NULL);
1018 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1020 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1021 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1023 memset(buf, 0xAA, sizeof(buf));
1024 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1025 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1026 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1028 hbmp_old = SelectObject(hdc, hbmp);
1030 ret = GetObject(hbmp, sizeof(bm), &bm);
1031 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1033 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1034 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1035 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1036 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1037 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1038 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1039 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1041 memset(buf, 0xAA, sizeof(buf));
1042 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1043 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1044 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1046 hbmp_old = SelectObject(hdc, hbmp_old);
1047 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1049 /* test various buffer sizes for GetObject */
1050 ret = GetObject(hbmp, sizeof(bm) * 2, &bm);
1051 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1053 ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1054 ok(ret == 0, "%d != 0\n", ret);
1056 ret = GetObject(hbmp, 0, &bm);
1057 ok(ret == 0, "%d != 0\n", ret);
1059 ret = GetObject(hbmp, 1, &bm);
1060 ok(ret == 0, "%d != 0\n", ret);
1066 static void test_bmBits(void)
1072 memset(bits, 0, sizeof(bits));
1073 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1074 ok(hbmp != NULL, "CreateBitmap failed\n");
1076 memset(&bmp, 0xFF, sizeof(bmp));
1077 ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1078 "GetObject failed or returned a wrong structure size\n");
1079 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1084 static void test_GetDIBits_selected_DIB(UINT bpp)
1098 /* Create a DIB section with a color table */
1100 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD));
1101 info2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD));
1105 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1107 /* Choose width and height such that the row length (in bytes)
1108 is a multiple of 4 (makes things easier) */
1109 info->bmiHeader.biWidth = 32;
1110 info->bmiHeader.biHeight = 32;
1111 info->bmiHeader.biPlanes = 1;
1112 info->bmiHeader.biBitCount = bpp;
1113 info->bmiHeader.biCompression = BI_RGB;
1115 for (i=0; i < (1u << bpp); i++)
1117 BYTE c = i * (1 << (8 - bpp));
1118 info->bmiColors[i].rgbRed = c;
1119 info->bmiColors[i].rgbGreen = c;
1120 info->bmiColors[i].rgbBlue = c;
1121 info->bmiColors[i].rgbReserved = 0;
1124 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1126 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1128 /* Set the bits of the DIB section */
1129 for (i=0; i < dib_size; i++)
1131 ((BYTE *)bits)[i] = i % 256;
1134 /* Select the DIB into a DC */
1135 dib_dc = CreateCompatibleDC(NULL);
1136 old_bmp = (HBITMAP) SelectObject(dib_dc, dib);
1137 dc = CreateCompatibleDC(NULL);
1138 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib_size);
1141 /* Copy the DIB attributes but not the color table */
1142 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1144 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1145 ok(res, "GetDIBits failed\n");
1147 /* Compare the color table and the bits */
1148 equalContents = TRUE;
1149 for (i=0; i < (1u << bpp); i++)
1151 if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed)
1152 || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen)
1153 || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue)
1154 || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved))
1156 equalContents = FALSE;
1160 ok(equalContents, "GetDIBits with DIB selected in DC: Invalid DIB color table\n");
1162 equalContents = TRUE;
1163 for (i=0; i < dib_size / sizeof(DWORD); i++)
1165 if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i])
1167 equalContents = FALSE;
1172 ok(equalContents, "GetDIBits with %d bpp DIB selected in DC: Invalid DIB bits\n",bpp);
1174 todo_wine ok(equalContents, "GetDIBits with %d bpp DIB selected in DC: Invalid DIB bits\n",bpp);
1176 HeapFree(GetProcessHeap(), 0, bits2);
1179 SelectObject(dib_dc, old_bmp);
1183 HeapFree(GetProcessHeap(), 0, info2);
1184 HeapFree(GetProcessHeap(), 0, info);
1187 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1202 width = height = 16;
1204 /* Create a DDB (device-dependent bitmap) */
1208 ddb = CreateBitmap(width, height, 1, 1, NULL);
1212 HDC screen_dc = GetDC(NULL);
1213 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1214 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1215 ReleaseDC(NULL, screen_dc);
1218 /* Set the pixels */
1219 ddb_dc = CreateCompatibleDC(NULL);
1220 old_bmp = (HBITMAP) SelectObject(ddb_dc, ddb);
1221 for (i = 0; i < width; i++)
1223 for (j=0; j < height; j++)
1225 BYTE c = (i * width + j) % 256;
1226 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1229 SelectObject(ddb_dc, old_bmp);
1231 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1232 info2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1236 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1237 info->bmiHeader.biWidth = width;
1238 info->bmiHeader.biHeight = height;
1239 info->bmiHeader.biPlanes = 1;
1240 info->bmiHeader.biBitCount = bpp;
1241 info->bmiHeader.biCompression = BI_RGB;
1243 dc = CreateCompatibleDC(NULL);
1245 /* Fill in biSizeImage */
1246 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1247 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1249 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1250 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1255 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1256 ok(res, "GetDIBits failed\n");
1258 /* Copy the DIB attributes but not the color table */
1259 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1261 /* Select the DDB into another DC */
1262 old_bmp = (HBITMAP) SelectObject(ddb_dc, ddb);
1265 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1266 ok(res, "GetDIBits failed\n");
1268 /* Compare the color table and the bits */
1271 equalContents = TRUE;
1272 for (i=0; i < (1u << bpp); i++)
1274 if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed)
1275 || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen)
1276 || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue)
1277 || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved))
1279 equalContents = FALSE;
1283 ok(equalContents, "GetDIBits with DDB selected in DC: Got a different color table\n");
1286 equalContents = TRUE;
1287 for (i=0; i < info->bmiHeader.biSizeImage / sizeof(DWORD); i++)
1289 if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i])
1291 equalContents = FALSE;
1294 ok(equalContents, "GetDIBits with DDB selected in DC: Got different DIB bits\n");
1296 HeapFree(GetProcessHeap(), 0, bits2);
1297 HeapFree(GetProcessHeap(), 0, bits);
1300 SelectObject(ddb_dc, old_bmp);
1304 HeapFree(GetProcessHeap(), 0, info2);
1305 HeapFree(GetProcessHeap(), 0, info);
1308 static void test_GetDIBits(void)
1310 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1311 static const BYTE bmp_bits_1[16 * 2] =
1313 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1314 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1315 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1316 0xff,0xff, 0,0, 0xff,0xff, 0,0
1318 /* 4-bytes aligned 1-bit DIB data: 16x16 */
1319 static const BYTE dib_bits_1[16 * 4] =
1321 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1322 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1323 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1324 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1326 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1327 static const BYTE bmp_bits_24[16 * 16*3] =
1329 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1336 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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
1362 /* 4-bytes aligned 24-bit DIB data: 16x16 */
1363 static const BYTE dib_bits_24[16 * 16*3] =
1365 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1366 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1367 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1368 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1369 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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1371 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1372 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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
1401 int i, bytes, lines;
1403 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1404 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1408 /* 1-bit source bitmap data */
1409 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1410 ok(hbmp != 0, "CreateBitmap failed\n");
1412 memset(&bm, 0xAA, sizeof(bm));
1413 bytes = GetObject(hbmp, sizeof(bm), &bm);
1414 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1415 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1416 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1417 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1418 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1419 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1420 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1421 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1423 bytes = GetBitmapBits(hbmp, 0, NULL);
1424 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1425 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1426 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1427 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1429 /* retrieve 1-bit DIB data */
1430 memset(bi, 0, sizeof(*bi));
1431 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1432 bi->bmiHeader.biWidth = bm.bmWidth;
1433 bi->bmiHeader.biHeight = bm.bmHeight;
1434 bi->bmiHeader.biPlanes = 1;
1435 bi->bmiHeader.biBitCount = 1;
1436 bi->bmiHeader.biCompression = BI_RGB;
1437 bi->bmiHeader.biSizeImage = 0;
1438 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1439 SetLastError(0xdeadbeef);
1440 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1441 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1442 ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
1443 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1445 memset(buf, 0xAA, sizeof(buf));
1446 SetLastError(0xdeadbeef);
1447 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1448 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1449 lines, bm.bmHeight, GetLastError());
1450 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1452 /* the color table consists of black and white */
1453 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1454 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1455 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1456 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1457 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1459 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1460 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1461 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1462 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1463 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1464 for (i = 2; i < 256; i++)
1466 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1467 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1468 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1469 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1470 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1473 /* returned bits are DWORD aligned and upside down */
1475 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1477 /* retrieve 24-bit DIB data */
1478 memset(bi, 0, sizeof(*bi));
1479 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1480 bi->bmiHeader.biWidth = bm.bmWidth;
1481 bi->bmiHeader.biHeight = bm.bmHeight;
1482 bi->bmiHeader.biPlanes = 1;
1483 bi->bmiHeader.biBitCount = 24;
1484 bi->bmiHeader.biCompression = BI_RGB;
1485 bi->bmiHeader.biSizeImage = 0;
1486 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1487 memset(buf, 0xAA, sizeof(buf));
1488 SetLastError(0xdeadbeef);
1489 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1490 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1491 lines, bm.bmHeight, GetLastError());
1492 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1494 /* the color table doesn't exist for 24-bit images */
1495 for (i = 0; i < 256; i++)
1497 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1498 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1499 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1500 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1501 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1504 /* returned bits are DWORD aligned and upside down */
1506 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1509 /* 24-bit source bitmap data */
1510 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1511 ok(hbmp != 0, "CreateBitmap failed\n");
1512 SetLastError(0xdeadbeef);
1513 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1514 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1515 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1516 lines, bm.bmHeight, GetLastError());
1518 memset(&bm, 0xAA, sizeof(bm));
1519 bytes = GetObject(hbmp, sizeof(bm), &bm);
1520 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1521 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1522 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1523 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1524 ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1525 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1526 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1527 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1529 bytes = GetBitmapBits(hbmp, 0, NULL);
1530 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1531 bm.bmWidthBytes * bm.bmHeight, bytes);
1532 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1533 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1534 bm.bmWidthBytes * bm.bmHeight, bytes);
1536 /* retrieve 1-bit DIB data */
1537 memset(bi, 0, sizeof(*bi));
1538 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1539 bi->bmiHeader.biWidth = bm.bmWidth;
1540 bi->bmiHeader.biHeight = bm.bmHeight;
1541 bi->bmiHeader.biPlanes = 1;
1542 bi->bmiHeader.biBitCount = 1;
1543 bi->bmiHeader.biCompression = BI_RGB;
1544 bi->bmiHeader.biSizeImage = 0;
1545 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1546 memset(buf, 0xAA, sizeof(buf));
1547 SetLastError(0xdeadbeef);
1548 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1549 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1550 lines, bm.bmHeight, GetLastError());
1551 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1553 /* the color table consists of black and white */
1554 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1555 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1556 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1557 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1558 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1559 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1560 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1561 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1562 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1563 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1564 for (i = 2; i < 256; i++)
1566 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1567 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1568 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1569 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1570 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1573 /* returned bits are DWORD aligned and upside down */
1575 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1577 /* retrieve 24-bit DIB data */
1578 memset(bi, 0, sizeof(*bi));
1579 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1580 bi->bmiHeader.biWidth = bm.bmWidth;
1581 bi->bmiHeader.biHeight = bm.bmHeight;
1582 bi->bmiHeader.biPlanes = 1;
1583 bi->bmiHeader.biBitCount = 24;
1584 bi->bmiHeader.biCompression = BI_RGB;
1585 bi->bmiHeader.biSizeImage = 0;
1586 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1587 memset(buf, 0xAA, sizeof(buf));
1588 SetLastError(0xdeadbeef);
1589 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1590 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1591 lines, bm.bmHeight, GetLastError());
1592 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1594 /* the color table doesn't exist for 24-bit images */
1595 for (i = 0; i < 256; i++)
1597 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1598 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1599 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1600 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1601 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1604 /* returned bits are DWORD aligned and upside down */
1605 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1611 static void test_GetDIBits_BI_BITFIELDS(void)
1613 /* Try a screen resolution detection technique
1614 * from the September 1999 issue of Windows Developer's Journal
1615 * which seems to be in widespread use.
1616 * http://www.lesher.ws/highcolor.html
1617 * http://www.lesher.ws/vidfmt.c
1618 * It hinges on being able to retrieve the bitmaps
1619 * for the three primary colors in non-paletted 16 bit mode.
1621 char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
1623 LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
1628 memset(dibinfo, 0, sizeof(dibinfo_buf));
1629 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1632 ok(hdc != NULL, "GetDC failed?\n");
1633 hbm = CreateCompatibleBitmap(hdc, 1, 1);
1634 ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
1636 /* Call GetDIBits to fill in bmiHeader. */
1637 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1638 ok(ret == 1, "GetDIBits failed\n");
1639 if (dibinfo->bmiHeader.biBitCount > 8)
1641 DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
1643 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
1644 "compression is %u\n", dibinfo->bmiHeader.biCompression );
1646 ok( !bitmasks[0], "red mask is set\n" );
1647 ok( !bitmasks[1], "green mask is set\n" );
1648 ok( !bitmasks[2], "blue mask is set\n" );
1650 /* test with NULL bits pointer and correct bpp */
1651 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1652 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1653 ok(ret == 1, "GetDIBits failed\n");
1655 ok( bitmasks[0] != 0, "red mask is not set\n" );
1656 ok( bitmasks[1] != 0, "green mask is not set\n" );
1657 ok( bitmasks[2] != 0, "blue mask is not set\n" );
1658 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1660 /* test with valid bits pointer */
1661 memset(dibinfo, 0, sizeof(dibinfo_buf));
1662 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1663 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1664 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1665 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1666 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
1667 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1669 ok( bitmasks[0] != 0, "red mask is not set\n" );
1670 ok( bitmasks[1] != 0, "green mask is not set\n" );
1671 ok( bitmasks[2] != 0, "blue mask is not set\n" );
1672 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1674 /* now with bits and 0 lines */
1675 memset(dibinfo, 0, sizeof(dibinfo_buf));
1676 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1677 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1678 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
1680 ok( !bitmasks[0], "red mask is set\n" );
1681 ok( !bitmasks[1], "green mask is set\n" );
1682 ok( !bitmasks[2], "blue mask is set\n" );
1683 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1685 memset(bitmasks, 0, 3*sizeof(DWORD));
1686 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1687 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
1688 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1690 ok( bitmasks[0] != 0, "red mask is not set\n" );
1691 ok( bitmasks[1] != 0, "green mask is not set\n" );
1692 ok( bitmasks[2] != 0, "blue mask is not set\n" );
1693 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1695 else skip("not in 16 bpp BI_BITFIELDS mode, skipping that test\n");
1698 ReleaseDC(NULL, hdc);
1701 static void test_select_object(void)
1704 HBITMAP hbm, hbm_old;
1706 DWORD depths[] = {8, 15, 16, 24, 32};
1711 ok(hdc != 0, "GetDC(0) failed\n");
1712 hbm = CreateCompatibleBitmap(hdc, 10, 10);
1713 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
1715 hbm_old = SelectObject(hdc, hbm);
1716 ok(hbm_old == 0, "SelectObject should fail\n");
1721 hdc = CreateCompatibleDC(0);
1722 ok(hdc != 0, "GetDC(0) failed\n");
1723 hbm = CreateCompatibleBitmap(hdc, 10, 10);
1724 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
1726 hbm_old = SelectObject(hdc, hbm);
1727 ok(hbm_old != 0, "SelectObject failed\n");
1728 hbm_old = SelectObject(hdc, hbm_old);
1729 ok(hbm_old == hbm, "SelectObject failed\n");
1733 /* test an 1-bpp bitmap */
1734 planes = GetDeviceCaps(hdc, PLANES);
1737 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
1738 ok(hbm != 0, "CreateBitmap failed\n");
1740 hbm_old = SelectObject(hdc, hbm);
1741 ok(hbm_old != 0, "SelectObject failed\n");
1742 hbm_old = SelectObject(hdc, hbm_old);
1743 ok(hbm_old == hbm, "SelectObject failed\n");
1747 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
1748 /* test a color bitmap to dc bpp matching */
1749 planes = GetDeviceCaps(hdc, PLANES);
1750 bpp = GetDeviceCaps(hdc, BITSPIXEL);
1752 hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
1753 ok(hbm != 0, "CreateBitmap failed\n");
1755 hbm_old = SelectObject(hdc, hbm);
1756 if(depths[i] == bpp ||
1757 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
1759 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
1760 SelectObject(hdc, hbm_old);
1762 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
1765 memset(&bm, 0xAA, sizeof(bm));
1766 bytes = GetObject(hbm, sizeof(bm), &bm);
1767 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1768 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1769 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
1770 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
1771 ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1772 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
1773 if(depths[i] == 15) {
1774 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
1776 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1778 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1786 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
1791 ret = GetObjectType(hbmp);
1792 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
1794 ret = GetObject(hbmp, 0, 0);
1795 ok_(__FILE__, line)(ret == sizeof(BITMAP) /* XP */ ||
1796 ret == sizeof(DIBSECTION) /* Win9x */, "object size %d\n", ret);
1798 memset(&bm, 0xDA, sizeof(bm));
1799 SetLastError(0xdeadbeef);
1800 ret = GetObject(hbmp, sizeof(bm), &bm);
1801 if (!ret) /* XP, only for curObj2 */ return;
1802 ok_(__FILE__, line)(ret == sizeof(BITMAP) ||
1803 ret == sizeof(DIBSECTION) /* Win9x, only for curObj2 */,
1804 "GetObject returned %d, error %u\n", ret, GetLastError());
1805 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
1806 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
1807 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
1808 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
1809 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
1810 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
1811 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1814 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
1816 static void test_CreateBitmap(void)
1819 HDC screenDC = GetDC(0);
1820 HDC hdc = CreateCompatibleDC(screenDC);
1823 /* all of these are the stock monochrome bitmap */
1824 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
1825 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
1826 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
1827 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
1828 HBITMAP curObj1 = (HBITMAP)GetCurrentObject(hdc, OBJ_BITMAP);
1829 HBITMAP curObj2 = (HBITMAP)GetCurrentObject(screenDC, OBJ_BITMAP);
1831 /* these 2 are not the stock monochrome bitmap */
1832 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
1833 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
1835 HBITMAP old1 = (HBITMAP)SelectObject(hdc, bm2);
1836 HBITMAP old2 = (HBITMAP)SelectObject(screenDC, bm3);
1837 SelectObject(hdc, old1);
1838 SelectObject(screenDC, old2);
1840 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
1841 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
1842 bm, bm1, bm4, bm5, curObj1, old1);
1843 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
1844 ok(bm != curObj2 /* XP */ || bm == curObj2 /* Win9x */,
1845 "0: %p, curObj2 %p\n", bm, curObj2);
1846 ok(old2 == 0, "old2 %p\n", old2);
1848 test_mono_1x1_bmp(bm);
1849 test_mono_1x1_bmp(bm1);
1850 test_mono_1x1_bmp(bm2);
1851 test_mono_1x1_bmp(bm3);
1852 test_mono_1x1_bmp(bm4);
1853 test_mono_1x1_bmp(bm5);
1854 test_mono_1x1_bmp(old1);
1855 test_mono_1x1_bmp(curObj1);
1856 test_mono_1x1_bmp(curObj2);
1866 ReleaseDC(0, screenDC);
1868 /* show that Windows ignores the provided bm.bmWidthBytes */
1872 bmp.bmWidthBytes = 28;
1874 bmp.bmBitsPixel = 1;
1876 bm = CreateBitmapIndirect(&bmp);
1877 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
1878 test_mono_1x1_bmp(bm);
1881 /* Test how the bmBitsPixel field is treated */
1882 for(i = 1; i <= 33; i++) {
1886 bmp.bmWidthBytes = 28;
1888 bmp.bmBitsPixel = i;
1890 bm = CreateBitmapIndirect(&bmp);
1892 DWORD error = GetLastError();
1893 ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
1894 ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
1897 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
1898 GetObject(bm, sizeof(bmp), &bmp);
1905 } else if(i <= 16) {
1907 } else if(i <= 24) {
1909 } else if(i <= 32) {
1912 ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
1913 i, bmp.bmBitsPixel, expect);
1918 static void test_bitmapinfoheadersize(void)
1925 memset(&bmi, 0, sizeof(BITMAPINFO));
1926 bmi.bmiHeader.biHeight = 100;
1927 bmi.bmiHeader.biWidth = 512;
1928 bmi.bmiHeader.biBitCount = 24;
1929 bmi.bmiHeader.biPlanes = 1;
1931 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
1933 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1934 ok(hdib == NULL, "CreateDIBSection succeeded\n");
1936 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1938 SetLastError(0xdeadbeef);
1939 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1940 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1943 bmi.bmiHeader.biSize++;
1945 SetLastError(0xdeadbeef);
1946 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1947 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1950 bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
1952 SetLastError(0xdeadbeef);
1953 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1954 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1957 bmi.bmiHeader.biSize++;
1959 SetLastError(0xdeadbeef);
1960 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1961 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1964 bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
1966 SetLastError(0xdeadbeef);
1967 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1968 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1971 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
1973 SetLastError(0xdeadbeef);
1974 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1975 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1978 memset(&bci, 0, sizeof(BITMAPCOREINFO));
1979 bci.bmciHeader.bcHeight = 100;
1980 bci.bmciHeader.bcWidth = 512;
1981 bci.bmciHeader.bcBitCount = 24;
1982 bci.bmciHeader.bcPlanes = 1;
1984 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
1986 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
1987 ok(hdib == NULL, "CreateDIBSection succeeded\n");
1989 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
1991 SetLastError(0xdeadbeef);
1992 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
1993 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1996 bci.bmciHeader.bcSize++;
1998 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
1999 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2001 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2003 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2004 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2009 static void test_get16dibits(void)
2011 BYTE bits[4 * (16 / sizeof(BYTE))];
2013 HDC screen_dc = GetDC(NULL);
2016 int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2018 int overwritten_bytes = 0;
2020 memset(bits, 0, sizeof(bits));
2021 hbmp = CreateBitmap(2, 2, 1, 16, bits);
2022 ok(hbmp != NULL, "CreateBitmap failed\n");
2024 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2027 memset(info, '!', info_len);
2028 memset(info, 0, sizeof(info->bmiHeader));
2030 info->bmiHeader.biSize = sizeof(info->bmiHeader);
2031 info->bmiHeader.biWidth = 2;
2032 info->bmiHeader.biHeight = 2;
2033 info->bmiHeader.biPlanes = 1;
2034 info->bmiHeader.biCompression = BI_RGB;
2036 ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2037 ok(ret != 0, "GetDIBits failed\n");
2039 for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2041 overwritten_bytes++;
2042 ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2044 HeapFree(GetProcessHeap(), 0, info);
2046 ReleaseDC(NULL, screen_dc);
2049 void test_GdiAlphaBlend()
2051 /* test out-of-bound parameters for GdiAlphaBlend */
2064 BLENDFUNCTION blend;
2066 if (!pGdiAlphaBlend)
2068 skip("GdiAlphaBlend() is not implemented\n");
2072 hdcNull = GetDC(NULL);
2073 hdcDst = CreateCompatibleDC(hdcNull);
2074 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
2075 hdcSrc = CreateCompatibleDC(hdcNull);
2077 memset(&bmi, 0, sizeof(bmi)); /* as of Wine 0.9.44 we require the src to be a DIB section */
2078 bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
2079 bmi.bmiHeader.biHeight = 20;
2080 bmi.bmiHeader.biWidth = 20;
2081 bmi.bmiHeader.biBitCount = 32;
2082 bmi.bmiHeader.biPlanes = 1;
2083 bmi.bmiHeader.biCompression = BI_RGB;
2084 bmpSrc = CreateDIBSection(hdcDst, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
2085 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
2087 oldDst = (HBITMAP)SelectObject(hdcDst, bmpDst);
2088 oldSrc = (HBITMAP)SelectObject(hdcSrc, bmpSrc);
2090 blend.BlendOp = AC_SRC_OVER;
2091 blend.BlendFlags = 0;
2092 blend.SourceConstantAlpha = 128;
2093 blend.AlphaFormat = 0;
2095 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend), TRUE, BOOL, "%d");
2096 SetLastError(0xdeadbeef);
2097 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), FALSE, BOOL, "%d");
2098 expect_eq(GetLastError(), ERROR_INVALID_PARAMETER, int, "%d");
2099 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), FALSE, BOOL, "%d");
2100 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend), FALSE, BOOL, "%d");
2101 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
2102 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
2104 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
2105 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), TRUE, BOOL, "%d");
2106 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), TRUE, BOOL, "%d");
2107 SetMapMode(hdcSrc, MM_ANISOTROPIC);
2108 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
2109 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend), TRUE, BOOL, "%d");
2110 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend), TRUE, BOOL, "%d");
2112 SelectObject(hdcDst, oldDst);
2113 SelectObject(hdcSrc, oldSrc);
2114 DeleteObject(bmpSrc);
2115 DeleteObject(bmpDst);
2119 ReleaseDC(NULL, hdcNull);
2126 is_win9x = GetWindowLongPtrW(GetDesktopWindow(), GWLP_WNDPROC) == 0;
2128 hdll = GetModuleHandle("gdi32.dll");
2129 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
2131 test_createdibitmap();
2133 test_mono_dibsection();
2136 test_GetDIBits_selected_DIB(1);
2137 test_GetDIBits_selected_DIB(4);
2138 test_GetDIBits_selected_DIB(8);
2139 test_GetDIBits_selected_DDB(TRUE);
2140 test_GetDIBits_selected_DDB(FALSE);
2142 test_GetDIBits_BI_BITFIELDS();
2143 test_select_object();
2144 test_CreateBitmap();
2145 test_GdiAlphaBlend();
2146 test_bitmapinfoheadersize();