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, 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 width_bytes = DIB_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
289 ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
290 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
291 ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount);
292 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
294 buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);
296 width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
298 /* GetBitmapBits returns not 32-bit aligned data */
299 ret = GetBitmapBits(hbm, 0, NULL);
300 ok(ret == width_bytes * bm.bmHeight, "%d != %d\n", ret, width_bytes * bm.bmHeight);
302 memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
303 ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
304 ok(ret == width_bytes * bm.bmHeight, "%d != %d\n", ret, width_bytes * bm.bmHeight);
306 HeapFree(GetProcessHeap(), 0, buf);
308 /* test various buffer sizes for GetObject */
309 memset(&ds, 0xAA, sizeof(ds));
310 ret = GetObject(hbm, sizeof(bm) * 2, &bm);
311 ok(ret == sizeof(bm), "wrong size %d\n", ret);
312 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
313 ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
314 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
316 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
317 ok(ret == 0, "%d != 0\n", ret);
319 ret = GetObject(hbm, 0, &bm);
320 ok(ret == 0, "%d != 0\n", ret);
322 ret = GetObject(hbm, 1, &bm);
323 ok(ret == 0, "%d != 0\n", ret);
325 /* test various buffer sizes for GetObject */
326 ret = GetObject(hbm, 0, NULL);
327 ok(ret == sizeof(bm), "wrong size %d\n", ret);
329 memset(&ds, 0xAA, sizeof(ds));
330 ret = GetObject(hbm, sizeof(ds) * 2, &ds);
331 ok(ret == sizeof(ds), "wrong size %d\n", ret);
333 ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
334 ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%u != %u\n",
335 ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
336 ok(bmih->biSizeImage == 0, "%u != 0\n", bmih->biSizeImage);
337 ds.dsBmih.biSizeImage = 0;
339 ok(ds.dsBmih.biSize == bmih->biSize, "%u != %u\n", ds.dsBmih.biSize, bmih->biSize);
340 ok(ds.dsBmih.biWidth == bmih->biWidth, "%u != %u\n", ds.dsBmih.biWidth, bmih->biWidth);
341 ok(ds.dsBmih.biHeight == bmih->biHeight, "%u != %u\n", ds.dsBmih.biHeight, bmih->biHeight);
342 ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes);
343 ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount);
344 ok(ds.dsBmih.biCompression == bmih->biCompression, "%u != %u\n", ds.dsBmih.biCompression, bmih->biCompression);
345 ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%u != %u\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
346 ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%u != %u\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
347 ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%u != %u\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);
349 memset(&ds, 0xAA, sizeof(ds));
350 ret = GetObject(hbm, sizeof(ds) - 4, &ds);
351 ok(ret == sizeof(ds.dsBm), "wrong size %d\n", ret);
352 ok(ds.dsBm.bmWidth == bmih->biWidth, "%u != %u\n", ds.dsBmih.biWidth, bmih->biWidth);
353 ok(ds.dsBm.bmHeight == bmih->biHeight, "%u != %u\n", ds.dsBmih.biHeight, bmih->biHeight);
354 ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);
356 ret = GetObject(hbm, 0, &ds);
357 ok(ret == 0, "%d != 0\n", ret);
359 ret = GetObject(hbm, 1, &ds);
360 ok(ret == 0, "%d != 0\n", ret);
363 #define test_color_todo(got, exp, txt, todo) \
364 if (!todo && got != exp && screen_depth < 24) { \
365 todo_wine ok(0, #txt " failed at %d-bit screen depth: got 0x%06x expected 0x%06x - skipping DIB tests\n", \
366 screen_depth, (UINT)got, (UINT)exp); \
368 } else if (todo) todo_wine { ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp); } \
369 else ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp) \
371 #define test_color(hdc, color, exp, todo_setp, todo_getp) \
374 c = SetPixel(hdc, 0, 0, color); \
375 if (!is_win9x) { test_color_todo(c, exp, SetPixel, todo_setp); } \
376 c = GetPixel(hdc, 0, 0); \
377 test_color_todo(c, exp, GetPixel, todo_getp); \
380 static void test_dibsections(void)
382 HDC hdc, hdcmem, hdcmem2;
383 HBITMAP hdib, oldbm, hdib2, oldbm2;
384 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
385 char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
386 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
387 BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
393 char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
394 LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
397 HPALETTE hpal, oldpal;
402 MEMORY_BASIC_INFORMATION info;
405 screen_depth = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
407 memset(pbmi, 0, sizeof(bmibuf));
408 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
409 pbmi->bmiHeader.biHeight = 100;
410 pbmi->bmiHeader.biWidth = 512;
411 pbmi->bmiHeader.biBitCount = 24;
412 pbmi->bmiHeader.biPlanes = 1;
413 pbmi->bmiHeader.biCompression = BI_RGB;
415 SetLastError(0xdeadbeef);
416 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
417 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
418 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
419 ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
421 /* test the DIB memory */
422 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
423 "VirtualQuery failed\n");
424 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
425 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
426 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
427 ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
428 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
429 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
430 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
432 test_dib_info(hdib, bits, &pbmi->bmiHeader);
435 pbmi->bmiHeader.biBitCount = 8;
436 pbmi->bmiHeader.biCompression = BI_RLE8;
437 SetLastError(0xdeadbeef);
438 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
439 ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
440 ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
442 pbmi->bmiHeader.biBitCount = 16;
443 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
444 ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
445 ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
446 ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
447 SetLastError(0xdeadbeef);
448 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
449 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
451 /* test the DIB memory */
452 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
453 "VirtualQuery failed\n");
454 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
455 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
456 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
457 ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
458 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
459 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
460 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
462 test_dib_info(hdib, bits, &pbmi->bmiHeader);
465 memset(pbmi, 0, sizeof(bmibuf));
466 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
467 pbmi->bmiHeader.biHeight = 16;
468 pbmi->bmiHeader.biWidth = 16;
469 pbmi->bmiHeader.biBitCount = 1;
470 pbmi->bmiHeader.biPlanes = 1;
471 pbmi->bmiHeader.biCompression = BI_RGB;
472 pbmi->bmiColors[0].rgbRed = 0xff;
473 pbmi->bmiColors[0].rgbGreen = 0;
474 pbmi->bmiColors[0].rgbBlue = 0;
475 pbmi->bmiColors[1].rgbRed = 0;
476 pbmi->bmiColors[1].rgbGreen = 0;
477 pbmi->bmiColors[1].rgbBlue = 0xff;
479 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
480 ok(hdib != NULL, "CreateDIBSection failed\n");
481 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
482 ok(dibsec.dsBmih.biClrUsed == 2,
483 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
485 /* Test if the old BITMAPCOREINFO structure is supported */
487 pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
488 pbci->bmciHeader.bcBitCount = 0;
491 ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
492 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
493 ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
494 && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
495 "GetDIBits did't fill in the BITMAPCOREHEADER structure properly\n");
497 ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
498 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
499 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
500 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
501 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
502 "The color table has not been translated to the old BITMAPCOREINFO format\n");
504 hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
505 ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
507 ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
508 ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
509 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
510 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
511 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
512 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
513 "The color table has not been translated to the old BITMAPCOREINFO format\n");
515 DeleteObject(hcoredib);
518 hdcmem = CreateCompatibleDC(hdc);
519 oldbm = SelectObject(hdcmem, hdib);
521 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
522 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
523 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
524 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
525 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
526 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
528 c0 = RGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen, pbmi->bmiColors[0].rgbBlue);
529 c1 = RGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen, pbmi->bmiColors[1].rgbBlue);
531 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
532 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
533 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
534 test_color(hdcmem, PALETTEINDEX(0), c0, 1, 1);
535 test_color(hdcmem, PALETTEINDEX(1), c0, 1, 1);
536 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
537 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen,
538 pbmi->bmiColors[0].rgbBlue), c0, 1, 1);
539 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen,
540 pbmi->bmiColors[1].rgbBlue), c1, 1, 1);
541 test_color(hdcmem, PALETTERGB(0, 0, 0), c0, 1, 1);
542 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
543 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1, 1, 1);
545 SelectObject(hdcmem, oldbm);
548 pbmi->bmiColors[0].rgbRed = 0xff;
549 pbmi->bmiColors[0].rgbGreen = 0xff;
550 pbmi->bmiColors[0].rgbBlue = 0xff;
551 pbmi->bmiColors[1].rgbRed = 0;
552 pbmi->bmiColors[1].rgbGreen = 0;
553 pbmi->bmiColors[1].rgbBlue = 0;
555 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
556 ok(hdib != NULL, "CreateDIBSection failed\n");
558 test_dib_info(hdib, bits, &pbmi->bmiHeader);
560 oldbm = SelectObject(hdcmem, hdib);
562 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
563 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
564 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
565 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
566 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
567 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
569 SelectObject(hdcmem, oldbm);
570 test_dib_info(hdib, bits, &pbmi->bmiHeader);
573 pbmi->bmiHeader.biBitCount = 4;
574 for (i = 0; i < 16; i++) {
575 pbmi->bmiColors[i].rgbRed = i;
576 pbmi->bmiColors[i].rgbGreen = 16-i;
577 pbmi->bmiColors[i].rgbBlue = 0;
579 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
580 ok(hdib != NULL, "CreateDIBSection failed\n");
581 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
582 ok(dibsec.dsBmih.biClrUsed == 16,
583 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
584 test_dib_info(hdib, bits, &pbmi->bmiHeader);
587 pbmi->bmiHeader.biBitCount = 8;
589 for (i = 0; i < 128; i++) {
590 pbmi->bmiColors[i].rgbRed = 255 - i * 2;
591 pbmi->bmiColors[i].rgbGreen = i * 2;
592 pbmi->bmiColors[i].rgbBlue = 0;
593 pbmi->bmiColors[255 - i].rgbRed = 0;
594 pbmi->bmiColors[255 - i].rgbGreen = i * 2;
595 pbmi->bmiColors[255 - i].rgbBlue = 255 - i * 2;
597 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
598 ok(hdib != NULL, "CreateDIBSection failed\n");
599 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
600 ok(dibsec.dsBmih.biClrUsed == 256,
601 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
603 oldbm = SelectObject(hdcmem, hdib);
605 for (i = 0; i < 256; i++) {
606 test_color(hdcmem, DIBINDEX(i),
607 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
608 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue),
609 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
612 SelectObject(hdcmem, oldbm);
613 test_dib_info(hdib, bits, &pbmi->bmiHeader);
616 pbmi->bmiHeader.biBitCount = 1;
618 /* Now create a palette and a palette indexed dib section */
619 memset(plogpal, 0, sizeof(logpalbuf));
620 plogpal->palVersion = 0x300;
621 plogpal->palNumEntries = 2;
622 plogpal->palPalEntry[0].peRed = 0xff;
623 plogpal->palPalEntry[0].peBlue = 0xff;
624 plogpal->palPalEntry[1].peGreen = 0xff;
626 index = (WORD*)pbmi->bmiColors;
629 hpal = CreatePalette(plogpal);
630 ok(hpal != NULL, "CreatePalette failed\n");
631 oldpal = SelectPalette(hdc, hpal, TRUE);
632 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
633 ok(hdib != NULL, "CreateDIBSection failed\n");
634 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
635 ok(dibsec.dsBmih.biClrUsed == 2,
636 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
638 /* The colour table has already been grabbed from the dc, so we select back the
641 SelectPalette(hdc, oldpal, TRUE);
642 oldbm = SelectObject(hdcmem, hdib);
643 oldpal = SelectPalette(hdcmem, hpal, TRUE);
645 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
646 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
647 ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
648 rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
649 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
650 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
651 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
653 c0 = RGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen, plogpal->palPalEntry[0].peBlue);
654 c1 = RGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen, plogpal->palPalEntry[1].peBlue);
656 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
657 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
658 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
659 test_color(hdcmem, PALETTEINDEX(0), c0, 0, 1);
660 test_color(hdcmem, PALETTEINDEX(1), c1, 0, 1);
661 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
662 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen,
663 plogpal->palPalEntry[0].peBlue), c0, 1, 1);
664 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen,
665 plogpal->palPalEntry[1].peBlue), c1, 1, 1);
666 test_color(hdcmem, PALETTERGB(0, 0, 0), c1, 1, 1);
667 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
668 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0, 1, 1);
669 test_color(hdcmem, PALETTERGB(0, 1, 0), c1, 1, 1);
670 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1, 1, 1);
671 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0, 1, 1);
673 /* Bottom and 2nd row from top green, everything else magenta */
674 bits[0] = bits[1] = 0xff;
675 bits[13 * 4] = bits[13*4 + 1] = 0xff;
677 test_dib_info(hdib, bits, &pbmi->bmiHeader);
679 pbmi->bmiHeader.biBitCount = 32;
681 hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
682 ok(hdib2 != NULL, "CreateDIBSection failed\n");
683 hdcmem2 = CreateCompatibleDC(hdc);
684 oldbm2 = SelectObject(hdcmem2, hdib2);
686 BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
688 ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
689 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
691 SelectObject(hdcmem2, oldbm2);
692 test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
695 SelectObject(hdcmem, oldbm);
696 SelectObject(hdcmem, oldpal);
701 pbmi->bmiHeader.biBitCount = 8;
703 memset(plogpal, 0, sizeof(logpalbuf));
704 plogpal->palVersion = 0x300;
705 plogpal->palNumEntries = 256;
707 for (i = 0; i < 128; i++) {
708 plogpal->palPalEntry[i].peRed = 255 - i * 2;
709 plogpal->palPalEntry[i].peBlue = i * 2;
710 plogpal->palPalEntry[i].peGreen = 0;
711 plogpal->palPalEntry[255 - i].peRed = 0;
712 plogpal->palPalEntry[255 - i].peGreen = i * 2;
713 plogpal->palPalEntry[255 - i].peBlue = 255 - i * 2;
716 index = (WORD*)pbmi->bmiColors;
717 for (i = 0; i < 256; i++) {
721 hpal = CreatePalette(plogpal);
722 ok(hpal != NULL, "CreatePalette failed\n");
723 oldpal = SelectPalette(hdc, hpal, TRUE);
724 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
725 ok(hdib != NULL, "CreateDIBSection failed\n");
726 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
727 ok(dibsec.dsBmih.biClrUsed == 256,
728 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
730 test_dib_info(hdib, bits, &pbmi->bmiHeader);
732 SelectPalette(hdc, oldpal, TRUE);
733 oldbm = SelectObject(hdcmem, hdib);
734 oldpal = SelectPalette(hdcmem, hpal, TRUE);
736 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
737 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
738 for (i = 0; i < 256; i++) {
739 ok(rgb[i].rgbRed == plogpal->palPalEntry[i].peRed &&
740 rgb[i].rgbBlue == plogpal->palPalEntry[i].peBlue &&
741 rgb[i].rgbGreen == plogpal->palPalEntry[i].peGreen,
742 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
743 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
746 for (i = 0; i < 256; i++) {
747 test_color(hdcmem, DIBINDEX(i),
748 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
749 test_color(hdcmem, PALETTEINDEX(i),
750 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
751 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue),
752 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
755 SelectPalette(hdcmem, oldpal, TRUE);
756 SelectObject(hdcmem, oldbm);
765 static void test_mono_dibsection(void)
768 HBITMAP old_bm, mono_ds;
769 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
770 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
777 memdc = CreateCompatibleDC(hdc);
779 memset(pbmi, 0, sizeof(bmibuf));
780 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
781 pbmi->bmiHeader.biHeight = 10;
782 pbmi->bmiHeader.biWidth = 10;
783 pbmi->bmiHeader.biBitCount = 1;
784 pbmi->bmiHeader.biPlanes = 1;
785 pbmi->bmiHeader.biCompression = BI_RGB;
786 pbmi->bmiColors[0].rgbRed = 0xff;
787 pbmi->bmiColors[0].rgbGreen = 0xff;
788 pbmi->bmiColors[0].rgbBlue = 0xff;
789 pbmi->bmiColors[1].rgbRed = 0x0;
790 pbmi->bmiColors[1].rgbGreen = 0x0;
791 pbmi->bmiColors[1].rgbBlue = 0x0;
794 * First dib section is 'inverted' ie color[0] is white, color[1] is black
797 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
798 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
799 old_bm = SelectObject(memdc, mono_ds);
801 /* black border, white interior */
802 Rectangle(memdc, 0, 0, 10, 10);
803 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
804 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
806 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
808 memset(bits, 0, sizeof(bits));
811 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
812 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
814 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
816 pbmi->bmiColors[0].rgbRed = 0x0;
817 pbmi->bmiColors[0].rgbGreen = 0x0;
818 pbmi->bmiColors[0].rgbBlue = 0x0;
819 pbmi->bmiColors[1].rgbRed = 0xff;
820 pbmi->bmiColors[1].rgbGreen = 0xff;
821 pbmi->bmiColors[1].rgbBlue = 0xff;
823 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
824 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
826 SelectObject(memdc, old_bm);
827 DeleteObject(mono_ds);
830 * Next dib section is 'normal' ie color[0] is black, color[1] is white
833 pbmi->bmiColors[0].rgbRed = 0x0;
834 pbmi->bmiColors[0].rgbGreen = 0x0;
835 pbmi->bmiColors[0].rgbBlue = 0x0;
836 pbmi->bmiColors[1].rgbRed = 0xff;
837 pbmi->bmiColors[1].rgbGreen = 0xff;
838 pbmi->bmiColors[1].rgbBlue = 0xff;
840 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
841 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
842 old_bm = SelectObject(memdc, mono_ds);
844 /* black border, white interior */
845 Rectangle(memdc, 0, 0, 10, 10);
846 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
847 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
849 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
851 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
852 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
854 /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
856 pbmi->bmiColors[0].rgbRed = 0xff;
857 pbmi->bmiColors[0].rgbGreen = 0xff;
858 pbmi->bmiColors[0].rgbBlue = 0xff;
859 pbmi->bmiColors[1].rgbRed = 0x0;
860 pbmi->bmiColors[1].rgbGreen = 0x0;
861 pbmi->bmiColors[1].rgbBlue = 0x0;
863 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
864 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
867 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
870 pbmi->bmiColors[0].rgbRed = 0xff;
871 pbmi->bmiColors[0].rgbGreen = 0xff;
872 pbmi->bmiColors[0].rgbBlue = 0xff;
873 pbmi->bmiColors[1].rgbRed = 0x0;
874 pbmi->bmiColors[1].rgbGreen = 0x0;
875 pbmi->bmiColors[1].rgbBlue = 0x0;
876 num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors);
877 ok(num == 2, "num = %d\n", num);
879 /* black border, white interior */
880 Rectangle(memdc, 0, 0, 10, 10);
882 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
883 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
885 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
887 memset(bits, 0, sizeof(bits));
890 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
891 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
893 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
895 pbmi->bmiColors[0].rgbRed = 0x0;
896 pbmi->bmiColors[0].rgbGreen = 0x0;
897 pbmi->bmiColors[0].rgbBlue = 0x0;
898 pbmi->bmiColors[1].rgbRed = 0xff;
899 pbmi->bmiColors[1].rgbGreen = 0xff;
900 pbmi->bmiColors[1].rgbBlue = 0xff;
902 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
903 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
905 SelectObject(memdc, old_bm);
906 DeleteObject(mono_ds);
909 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
912 pbmi->bmiColors[0].rgbRed = 0xff;
913 pbmi->bmiColors[0].rgbGreen = 0x0;
914 pbmi->bmiColors[0].rgbBlue = 0x0;
915 pbmi->bmiColors[1].rgbRed = 0xfe;
916 pbmi->bmiColors[1].rgbGreen = 0x0;
917 pbmi->bmiColors[1].rgbBlue = 0x0;
919 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
920 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
921 old_bm = SelectObject(memdc, mono_ds);
923 /* black border, white interior */
924 Rectangle(memdc, 0, 0, 10, 10);
925 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
926 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
928 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
930 pbmi->bmiColors[0].rgbRed = 0x0;
931 pbmi->bmiColors[0].rgbGreen = 0x0;
932 pbmi->bmiColors[0].rgbBlue = 0x0;
933 pbmi->bmiColors[1].rgbRed = 0xff;
934 pbmi->bmiColors[1].rgbGreen = 0xff;
935 pbmi->bmiColors[1].rgbBlue = 0xff;
937 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
938 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
940 /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
942 pbmi->bmiColors[0].rgbRed = 0xff;
943 pbmi->bmiColors[0].rgbGreen = 0xff;
944 pbmi->bmiColors[0].rgbBlue = 0xff;
945 pbmi->bmiColors[1].rgbRed = 0x0;
946 pbmi->bmiColors[1].rgbGreen = 0x0;
947 pbmi->bmiColors[1].rgbBlue = 0x0;
949 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
950 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
952 SelectObject(memdc, old_bm);
953 DeleteObject(mono_ds);
959 static void test_bitmap(void)
961 char buf[256], buf_cmp[256];
962 HBITMAP hbmp, hbmp_old;
967 hdc = CreateCompatibleDC(0);
970 SetLastError(0xdeadbeef);
971 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
972 ok(hbmp != 0, "CreateBitmap should not fail\n");
975 SetLastError(0xdeadbeef);
976 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
979 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY,
980 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
985 SetLastError(0xdeadbeef);
986 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
987 ok(!hbmp, "CreateBitmap should fail\n");
988 ok(GetLastError() == ERROR_INVALID_PARAMETER,
989 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
991 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
992 assert(hbmp != NULL);
994 ret = GetObject(hbmp, sizeof(bm), &bm);
995 ok(ret == sizeof(bm), "wrong size %d\n", ret);
997 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
998 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
999 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1000 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1001 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1002 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1003 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1005 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1006 assert(sizeof(buf) == sizeof(buf_cmp));
1008 ret = GetBitmapBits(hbmp, 0, NULL);
1009 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1011 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1012 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1014 memset(buf, 0xAA, sizeof(buf));
1015 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1016 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1017 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1019 hbmp_old = SelectObject(hdc, hbmp);
1021 ret = GetObject(hbmp, sizeof(bm), &bm);
1022 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1024 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1025 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1026 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1027 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1028 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1029 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1030 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1032 memset(buf, 0xAA, sizeof(buf));
1033 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1034 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1035 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1037 hbmp_old = SelectObject(hdc, hbmp_old);
1038 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1040 /* test various buffer sizes for GetObject */
1041 ret = GetObject(hbmp, sizeof(bm) * 2, &bm);
1042 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1044 ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1045 ok(ret == 0, "%d != 0\n", ret);
1047 ret = GetObject(hbmp, 0, &bm);
1048 ok(ret == 0, "%d != 0\n", ret);
1050 ret = GetObject(hbmp, 1, &bm);
1051 ok(ret == 0, "%d != 0\n", ret);
1057 static void test_bmBits(void)
1063 memset(bits, 0, sizeof(bits));
1064 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1065 ok(hbmp != NULL, "CreateBitmap failed\n");
1067 memset(&bmp, 0xFF, sizeof(bmp));
1068 ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1069 "GetObject failed or returned a wrong structure size\n");
1070 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1075 static void test_GetDIBits_selected_DIB(UINT bpp)
1089 /* Create a DIB section with a color table */
1091 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD));
1092 info2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD));
1096 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1098 /* Choose width and height such that the row length (in bytes)
1099 is a multiple of 4 (makes things easier) */
1100 info->bmiHeader.biWidth = 32;
1101 info->bmiHeader.biHeight = 32;
1102 info->bmiHeader.biPlanes = 1;
1103 info->bmiHeader.biBitCount = bpp;
1104 info->bmiHeader.biCompression = BI_RGB;
1106 for (i=0; i < (1u << bpp); i++)
1108 BYTE c = i * (1 << (8 - bpp));
1109 info->bmiColors[i].rgbRed = c;
1110 info->bmiColors[i].rgbGreen = c;
1111 info->bmiColors[i].rgbBlue = c;
1112 info->bmiColors[i].rgbReserved = 0;
1115 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1117 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1119 /* Set the bits of the DIB section */
1120 for (i=0; i < dib_size; i++)
1122 ((BYTE *)bits)[i] = i % 256;
1125 /* Select the DIB into a DC */
1126 dib_dc = CreateCompatibleDC(NULL);
1127 old_bmp = (HBITMAP) SelectObject(dib_dc, dib);
1128 dc = CreateCompatibleDC(NULL);
1129 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib_size);
1132 /* Copy the DIB attributes but not the color table */
1133 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1135 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1136 ok(res, "GetDIBits failed\n");
1138 /* Compare the color table and the bits */
1139 equalContents = TRUE;
1140 for (i=0; i < (1u << bpp); i++)
1142 if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed)
1143 || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen)
1144 || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue)
1145 || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved))
1147 equalContents = FALSE;
1151 ok(equalContents, "GetDIBits with DIB selected in DC: Invalid DIB color table\n");
1153 equalContents = TRUE;
1154 for (i=0; i < dib_size / sizeof(DWORD); i++)
1156 if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i])
1158 equalContents = FALSE;
1163 ok(equalContents, "GetDIBits with %d bpp DIB selected in DC: Invalid DIB bits\n",bpp);
1165 todo_wine ok(equalContents, "GetDIBits with %d bpp DIB selected in DC: Invalid DIB bits\n",bpp);
1167 HeapFree(GetProcessHeap(), 0, bits2);
1170 SelectObject(dib_dc, old_bmp);
1174 HeapFree(GetProcessHeap(), 0, info2);
1175 HeapFree(GetProcessHeap(), 0, info);
1178 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1193 width = height = 16;
1195 /* Create a DDB (device-dependent bitmap) */
1199 ddb = CreateBitmap(width, height, 1, 1, NULL);
1203 HDC screen_dc = GetDC(NULL);
1204 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1205 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1206 ReleaseDC(NULL, screen_dc);
1209 /* Set the pixels */
1210 ddb_dc = CreateCompatibleDC(NULL);
1211 old_bmp = (HBITMAP) SelectObject(ddb_dc, ddb);
1212 for (i = 0; i < width; i++)
1214 for (j=0; j < height; j++)
1216 BYTE c = (i * width + j) % 256;
1217 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1220 SelectObject(ddb_dc, old_bmp);
1222 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1223 info2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1227 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1228 info->bmiHeader.biWidth = width;
1229 info->bmiHeader.biHeight = height;
1230 info->bmiHeader.biPlanes = 1;
1231 info->bmiHeader.biBitCount = bpp;
1232 info->bmiHeader.biCompression = BI_RGB;
1234 dc = CreateCompatibleDC(NULL);
1236 /* Fill in biSizeImage */
1237 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1238 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1240 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1241 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1246 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1247 ok(res, "GetDIBits failed\n");
1249 /* Copy the DIB attributes but not the color table */
1250 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1252 /* Select the DDB into another DC */
1253 old_bmp = (HBITMAP) SelectObject(ddb_dc, ddb);
1256 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1257 ok(res, "GetDIBits failed\n");
1259 /* Compare the color table and the bits */
1262 equalContents = TRUE;
1263 for (i=0; i < (1u << bpp); i++)
1265 if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed)
1266 || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen)
1267 || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue)
1268 || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved))
1270 equalContents = FALSE;
1274 ok(equalContents, "GetDIBits with DDB selected in DC: Got a different color table\n");
1277 equalContents = TRUE;
1278 for (i=0; i < info->bmiHeader.biSizeImage / sizeof(DWORD); i++)
1280 if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i])
1282 equalContents = FALSE;
1285 ok(equalContents, "GetDIBits with DDB selected in DC: Got different DIB bits\n");
1287 HeapFree(GetProcessHeap(), 0, bits2);
1288 HeapFree(GetProcessHeap(), 0, bits);
1291 SelectObject(ddb_dc, old_bmp);
1295 HeapFree(GetProcessHeap(), 0, info2);
1296 HeapFree(GetProcessHeap(), 0, info);
1299 static void test_GetDIBits(void)
1301 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1302 static const BYTE bmp_bits_1[16 * 2] =
1304 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1305 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1306 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1307 0xff,0xff, 0,0, 0xff,0xff, 0,0
1309 /* 4-bytes aligned 1-bit DIB data: 16x16 */
1310 static const BYTE dib_bits_1[16 * 4] =
1312 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1313 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1314 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1315 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1317 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1318 static const BYTE bmp_bits_24[16 * 16*3] =
1320 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1321 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1322 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1323 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1324 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1325 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1326 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1327 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1328 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1337 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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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
1353 /* 4-bytes aligned 24-bit DIB data: 16x16 */
1354 static const BYTE dib_bits_24[16 * 16*3] =
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 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 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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 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 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 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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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
1392 int i, bytes, lines;
1394 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1395 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1399 /* 1-bit source bitmap data */
1400 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1401 ok(hbmp != 0, "CreateBitmap failed\n");
1403 memset(&bm, 0xAA, sizeof(bm));
1404 bytes = GetObject(hbmp, sizeof(bm), &bm);
1405 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1406 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1407 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1408 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1409 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1410 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1411 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1412 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1414 bytes = GetBitmapBits(hbmp, 0, NULL);
1415 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1416 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1417 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1418 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1420 /* retrieve 1-bit DIB data */
1421 memset(bi, 0, sizeof(*bi));
1422 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1423 bi->bmiHeader.biWidth = bm.bmWidth;
1424 bi->bmiHeader.biHeight = bm.bmHeight;
1425 bi->bmiHeader.biPlanes = 1;
1426 bi->bmiHeader.biBitCount = 1;
1427 bi->bmiHeader.biCompression = BI_RGB;
1428 bi->bmiHeader.biSizeImage = 0;
1429 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1430 SetLastError(0xdeadbeef);
1431 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1432 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1433 ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
1434 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1436 memset(buf, 0xAA, sizeof(buf));
1437 SetLastError(0xdeadbeef);
1438 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1439 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1440 lines, bm.bmHeight, GetLastError());
1441 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1443 /* the color table consists of black and white */
1444 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1445 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1446 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1447 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1448 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1450 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1451 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1452 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1453 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1454 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1455 for (i = 2; i < 256; i++)
1457 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1458 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1459 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1460 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1461 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1464 /* returned bits are DWORD aligned and upside down */
1466 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1468 /* retrieve 24-bit DIB data */
1469 memset(bi, 0, sizeof(*bi));
1470 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1471 bi->bmiHeader.biWidth = bm.bmWidth;
1472 bi->bmiHeader.biHeight = bm.bmHeight;
1473 bi->bmiHeader.biPlanes = 1;
1474 bi->bmiHeader.biBitCount = 24;
1475 bi->bmiHeader.biCompression = BI_RGB;
1476 bi->bmiHeader.biSizeImage = 0;
1477 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1478 memset(buf, 0xAA, sizeof(buf));
1479 SetLastError(0xdeadbeef);
1480 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1481 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1482 lines, bm.bmHeight, GetLastError());
1483 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1485 /* the color table doesn't exist for 24-bit images */
1486 for (i = 0; i < 256; i++)
1488 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1489 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1490 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1491 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1492 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1495 /* returned bits are DWORD aligned and upside down */
1497 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1500 /* 24-bit source bitmap data */
1501 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1502 ok(hbmp != 0, "CreateBitmap failed\n");
1503 SetLastError(0xdeadbeef);
1504 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1505 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1506 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1507 lines, bm.bmHeight, GetLastError());
1509 memset(&bm, 0xAA, sizeof(bm));
1510 bytes = GetObject(hbmp, sizeof(bm), &bm);
1511 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1512 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1513 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1514 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1515 ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1516 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1517 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1518 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1520 bytes = GetBitmapBits(hbmp, 0, NULL);
1521 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1522 bm.bmWidthBytes * bm.bmHeight, bytes);
1523 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1524 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1525 bm.bmWidthBytes * bm.bmHeight, bytes);
1527 /* retrieve 1-bit DIB data */
1528 memset(bi, 0, sizeof(*bi));
1529 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1530 bi->bmiHeader.biWidth = bm.bmWidth;
1531 bi->bmiHeader.biHeight = bm.bmHeight;
1532 bi->bmiHeader.biPlanes = 1;
1533 bi->bmiHeader.biBitCount = 1;
1534 bi->bmiHeader.biCompression = BI_RGB;
1535 bi->bmiHeader.biSizeImage = 0;
1536 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1537 memset(buf, 0xAA, sizeof(buf));
1538 SetLastError(0xdeadbeef);
1539 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1540 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1541 lines, bm.bmHeight, GetLastError());
1542 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1544 /* the color table consists of black and white */
1545 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1546 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1547 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1548 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1549 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1550 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1551 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1552 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1553 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1554 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1555 for (i = 2; i < 256; i++)
1557 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1558 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1559 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1560 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1561 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1564 /* returned bits are DWORD aligned and upside down */
1566 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1568 /* retrieve 24-bit DIB data */
1569 memset(bi, 0, sizeof(*bi));
1570 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1571 bi->bmiHeader.biWidth = bm.bmWidth;
1572 bi->bmiHeader.biHeight = bm.bmHeight;
1573 bi->bmiHeader.biPlanes = 1;
1574 bi->bmiHeader.biBitCount = 24;
1575 bi->bmiHeader.biCompression = BI_RGB;
1576 bi->bmiHeader.biSizeImage = 0;
1577 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1578 memset(buf, 0xAA, sizeof(buf));
1579 SetLastError(0xdeadbeef);
1580 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1581 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1582 lines, bm.bmHeight, GetLastError());
1583 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1585 /* the color table doesn't exist for 24-bit images */
1586 for (i = 0; i < 256; i++)
1588 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1589 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1590 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1591 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1592 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1595 /* returned bits are DWORD aligned and upside down */
1596 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1602 static void test_GetDIBits_BI_BITFIELDS(void)
1604 /* Try a screen resolution detection technique
1605 * from the September 1999 issue of Windows Developer's Journal
1606 * which seems to be in widespread use.
1607 * http://www.lesher.ws/highcolor.html
1608 * http://www.lesher.ws/vidfmt.c
1609 * It hinges on being able to retrieve the bitmaps
1610 * for the three primary colors in non-paletted 16 bit mode.
1612 char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
1614 LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
1619 memset(dibinfo, 0, sizeof(dibinfo_buf));
1620 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1623 ok(hdc != NULL, "GetDC failed?\n");
1624 hbm = CreateCompatibleBitmap(hdc, 1, 1);
1625 ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
1627 /* Call GetDIBits to fill in bmiHeader. */
1628 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1629 ok(ret == 1, "GetDIBits failed\n");
1630 if (dibinfo->bmiHeader.biBitCount > 8)
1632 DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
1634 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
1635 "compression is %u\n", dibinfo->bmiHeader.biCompression );
1637 ok( !bitmasks[0], "red mask is set\n" );
1638 ok( !bitmasks[1], "green mask is set\n" );
1639 ok( !bitmasks[2], "blue mask is set\n" );
1641 /* test with NULL bits pointer and correct bpp */
1642 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1643 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1644 ok(ret == 1, "GetDIBits failed\n");
1646 ok( bitmasks[0] != 0, "red mask is not set\n" );
1647 ok( bitmasks[1] != 0, "green mask is not set\n" );
1648 ok( bitmasks[2] != 0, "blue mask is not set\n" );
1649 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1651 /* test with valid bits pointer */
1652 memset(dibinfo, 0, sizeof(dibinfo_buf));
1653 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1654 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1655 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1656 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1657 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
1658 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1660 ok( bitmasks[0] != 0, "red mask is not set\n" );
1661 ok( bitmasks[1] != 0, "green mask is not set\n" );
1662 ok( bitmasks[2] != 0, "blue mask is not set\n" );
1663 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1665 /* now with bits and 0 lines */
1666 memset(dibinfo, 0, sizeof(dibinfo_buf));
1667 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1668 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1669 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
1671 ok( !bitmasks[0], "red mask is set\n" );
1672 ok( !bitmasks[1], "green mask is set\n" );
1673 ok( !bitmasks[2], "blue mask is set\n" );
1674 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1676 memset(bitmasks, 0, 3*sizeof(DWORD));
1677 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1678 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
1679 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1681 ok( bitmasks[0] != 0, "red mask is not set\n" );
1682 ok( bitmasks[1] != 0, "green mask is not set\n" );
1683 ok( bitmasks[2] != 0, "blue mask is not set\n" );
1684 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1686 else skip("not in 16 bpp BI_BITFIELDS mode, skipping that test\n");
1689 ReleaseDC(NULL, hdc);
1692 static void test_select_object(void)
1695 HBITMAP hbm, hbm_old;
1697 DWORD depths[] = {8, 15, 16, 24, 32};
1702 ok(hdc != 0, "GetDC(0) failed\n");
1703 hbm = CreateCompatibleBitmap(hdc, 10, 10);
1704 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
1706 hbm_old = SelectObject(hdc, hbm);
1707 ok(hbm_old == 0, "SelectObject should fail\n");
1712 hdc = CreateCompatibleDC(0);
1713 ok(hdc != 0, "GetDC(0) failed\n");
1714 hbm = CreateCompatibleBitmap(hdc, 10, 10);
1715 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
1717 hbm_old = SelectObject(hdc, hbm);
1718 ok(hbm_old != 0, "SelectObject failed\n");
1719 hbm_old = SelectObject(hdc, hbm_old);
1720 ok(hbm_old == hbm, "SelectObject failed\n");
1724 /* test an 1-bpp bitmap */
1725 planes = GetDeviceCaps(hdc, PLANES);
1728 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
1729 ok(hbm != 0, "CreateBitmap failed\n");
1731 hbm_old = SelectObject(hdc, hbm);
1732 ok(hbm_old != 0, "SelectObject failed\n");
1733 hbm_old = SelectObject(hdc, hbm_old);
1734 ok(hbm_old == hbm, "SelectObject failed\n");
1738 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
1739 /* test a color bitmap to dc bpp matching */
1740 planes = GetDeviceCaps(hdc, PLANES);
1741 bpp = GetDeviceCaps(hdc, BITSPIXEL);
1743 hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
1744 ok(hbm != 0, "CreateBitmap failed\n");
1746 hbm_old = SelectObject(hdc, hbm);
1747 if(depths[i] == bpp ||
1748 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
1750 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
1751 SelectObject(hdc, hbm_old);
1753 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
1756 memset(&bm, 0xAA, sizeof(bm));
1757 bytes = GetObject(hbm, sizeof(bm), &bm);
1758 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1759 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1760 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
1761 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
1762 ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1763 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
1764 if(depths[i] == 15) {
1765 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
1767 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1769 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1777 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
1782 ret = GetObjectType(hbmp);
1783 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
1785 ret = GetObject(hbmp, 0, 0);
1786 ok_(__FILE__, line)(ret == sizeof(BITMAP) /* XP */ ||
1787 ret == sizeof(DIBSECTION) /* Win9x */, "object size %d\n", ret);
1789 memset(&bm, 0xDA, sizeof(bm));
1790 SetLastError(0xdeadbeef);
1791 ret = GetObject(hbmp, sizeof(bm), &bm);
1792 if (!ret) /* XP, only for curObj2 */ return;
1793 ok_(__FILE__, line)(ret == sizeof(BITMAP) ||
1794 ret == sizeof(DIBSECTION) /* Win9x, only for curObj2 */,
1795 "GetObject returned %d, error %u\n", ret, GetLastError());
1796 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
1797 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
1798 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
1799 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
1800 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
1801 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
1802 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1805 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
1807 static void test_CreateBitmap(void)
1810 HDC screenDC = GetDC(0);
1811 HDC hdc = CreateCompatibleDC(screenDC);
1814 /* all of these are the stock monochrome bitmap */
1815 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
1816 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
1817 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
1818 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
1819 HBITMAP curObj1 = (HBITMAP)GetCurrentObject(hdc, OBJ_BITMAP);
1820 HBITMAP curObj2 = (HBITMAP)GetCurrentObject(screenDC, OBJ_BITMAP);
1822 /* these 2 are not the stock monochrome bitmap */
1823 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
1824 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
1826 HBITMAP old1 = (HBITMAP)SelectObject(hdc, bm2);
1827 HBITMAP old2 = (HBITMAP)SelectObject(screenDC, bm3);
1828 SelectObject(hdc, old1);
1829 SelectObject(screenDC, old2);
1831 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
1832 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
1833 bm, bm1, bm4, bm5, curObj1, old1);
1834 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
1835 ok(bm != curObj2 /* XP */ || bm == curObj2 /* Win9x */,
1836 "0: %p, curObj2 %p\n", bm, curObj2);
1837 ok(old2 == 0, "old2 %p\n", old2);
1839 test_mono_1x1_bmp(bm);
1840 test_mono_1x1_bmp(bm1);
1841 test_mono_1x1_bmp(bm2);
1842 test_mono_1x1_bmp(bm3);
1843 test_mono_1x1_bmp(bm4);
1844 test_mono_1x1_bmp(bm5);
1845 test_mono_1x1_bmp(old1);
1846 test_mono_1x1_bmp(curObj1);
1847 test_mono_1x1_bmp(curObj2);
1857 ReleaseDC(0, screenDC);
1859 /* show that Windows ignores the provided bm.bmWidthBytes */
1863 bmp.bmWidthBytes = 28;
1865 bmp.bmBitsPixel = 1;
1867 bm = CreateBitmapIndirect(&bmp);
1868 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
1869 test_mono_1x1_bmp(bm);
1872 /* Test how the bmBitsPixel field is treated */
1873 for(i = 1; i <= 33; i++) {
1877 bmp.bmWidthBytes = 28;
1879 bmp.bmBitsPixel = i;
1881 bm = CreateBitmapIndirect(&bmp);
1883 DWORD error = GetLastError();
1884 ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
1885 ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
1888 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
1889 GetObject(bm, sizeof(bmp), &bmp);
1896 } else if(i <= 16) {
1898 } else if(i <= 24) {
1900 } else if(i <= 32) {
1903 ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
1904 i, bmp.bmBitsPixel, expect);
1909 static void test_bitmapinfoheadersize(void)
1916 memset(&bmi, 0, sizeof(BITMAPINFO));
1917 bmi.bmiHeader.biHeight = 100;
1918 bmi.bmiHeader.biWidth = 512;
1919 bmi.bmiHeader.biBitCount = 24;
1920 bmi.bmiHeader.biPlanes = 1;
1922 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
1924 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1925 ok(hdib == NULL, "CreateDIBSection succeeded\n");
1927 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1929 SetLastError(0xdeadbeef);
1930 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1931 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1934 bmi.bmiHeader.biSize++;
1936 SetLastError(0xdeadbeef);
1937 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1938 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1941 bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
1943 SetLastError(0xdeadbeef);
1944 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1945 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1948 bmi.bmiHeader.biSize++;
1950 SetLastError(0xdeadbeef);
1951 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1952 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1955 bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
1957 SetLastError(0xdeadbeef);
1958 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1959 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1962 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
1964 SetLastError(0xdeadbeef);
1965 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1966 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1969 memset(&bci, 0, sizeof(BITMAPCOREINFO));
1970 bci.bmciHeader.bcHeight = 100;
1971 bci.bmciHeader.bcWidth = 512;
1972 bci.bmciHeader.bcBitCount = 24;
1973 bci.bmciHeader.bcPlanes = 1;
1975 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
1977 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
1978 ok(hdib == NULL, "CreateDIBSection succeeded\n");
1980 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
1982 SetLastError(0xdeadbeef);
1983 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
1984 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1987 bci.bmciHeader.bcSize++;
1989 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
1990 ok(hdib == NULL, "CreateDIBSection succeeded\n");
1992 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
1994 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
1995 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2000 static void test_get16dibits(void)
2002 BYTE bits[4 * (16 / sizeof(BYTE))];
2004 HDC screen_dc = GetDC(NULL);
2007 int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2009 int overwritten_bytes = 0;
2011 memset(bits, 0, sizeof(bits));
2012 hbmp = CreateBitmap(2, 2, 1, 16, bits);
2013 ok(hbmp != NULL, "CreateBitmap failed\n");
2015 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2018 memset(info, '!', info_len);
2019 memset(info, 0, sizeof(info->bmiHeader));
2021 info->bmiHeader.biSize = sizeof(info->bmiHeader);
2022 info->bmiHeader.biWidth = 2;
2023 info->bmiHeader.biHeight = 2;
2024 info->bmiHeader.biPlanes = 1;
2025 info->bmiHeader.biCompression = BI_RGB;
2027 ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2028 ok(ret != 0, "GetDIBits failed\n");
2030 for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2032 overwritten_bytes++;
2033 ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2035 HeapFree(GetProcessHeap(), 0, info);
2037 ReleaseDC(NULL, screen_dc);
2040 void test_GdiAlphaBlend()
2042 /* test out-of-bound parameters for GdiAlphaBlend */
2055 BLENDFUNCTION blend;
2057 if (!pGdiAlphaBlend)
2059 skip("GdiAlphaBlend() is not implemented\n");
2063 hdcNull = GetDC(NULL);
2064 hdcDst = CreateCompatibleDC(hdcNull);
2065 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
2066 hdcSrc = CreateCompatibleDC(hdcNull);
2068 memset(&bmi, 0, sizeof(bmi)); /* as of Wine 0.9.44 we require the src to be a DIB section */
2069 bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
2070 bmi.bmiHeader.biHeight = 20;
2071 bmi.bmiHeader.biWidth = 20;
2072 bmi.bmiHeader.biBitCount = 32;
2073 bmi.bmiHeader.biPlanes = 1;
2074 bmi.bmiHeader.biCompression = BI_RGB;
2075 bmpSrc = CreateDIBSection(hdcDst, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
2076 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
2078 oldDst = (HBITMAP)SelectObject(hdcDst, bmpDst);
2079 oldSrc = (HBITMAP)SelectObject(hdcSrc, bmpSrc);
2081 blend.BlendOp = AC_SRC_OVER;
2082 blend.BlendFlags = 0;
2083 blend.SourceConstantAlpha = 128;
2084 blend.AlphaFormat = 0;
2086 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend), TRUE, BOOL, "%d");
2087 SetLastError(0xdeadbeef);
2088 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), FALSE, BOOL, "%d");
2089 expect_eq(GetLastError(), ERROR_INVALID_PARAMETER, int, "%d");
2090 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), FALSE, BOOL, "%d");
2091 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend), FALSE, BOOL, "%d");
2092 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
2093 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
2095 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
2096 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), TRUE, BOOL, "%d");
2097 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), TRUE, BOOL, "%d");
2098 SetMapMode(hdcSrc, MM_ANISOTROPIC);
2099 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
2100 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend), TRUE, BOOL, "%d");
2101 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend), TRUE, BOOL, "%d");
2103 SelectObject(hdcDst, oldDst);
2104 SelectObject(hdcSrc, oldSrc);
2105 DeleteObject(bmpSrc);
2106 DeleteObject(bmpDst);
2110 ReleaseDC(NULL, hdcNull);
2117 is_win9x = GetWindowLongPtrW(GetDesktopWindow(), GWLP_WNDPROC) == 0;
2119 hdll = GetModuleHandle("gdi32.dll");
2120 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
2122 test_createdibitmap();
2124 test_mono_dibsection();
2127 test_GetDIBits_selected_DIB(1);
2128 test_GetDIBits_selected_DIB(4);
2129 test_GetDIBits_selected_DIB(8);
2130 test_GetDIBits_selected_DDB(TRUE);
2131 test_GetDIBits_selected_DDB(FALSE);
2133 test_GetDIBits_BI_BITFIELDS();
2134 test_select_object();
2135 test_CreateBitmap();
2136 test_GdiAlphaBlend();
2137 test_bitmapinfoheadersize();