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)
75 BYTE buf[512], buf_cmp[512];
78 ret = GetObject(hbm, sizeof(bm), &bm);
79 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
81 ok(bm.bmType == 0 || broken(bm.bmType == 21072 /* Win9x */), "wrong bm.bmType %d\n", bm.bmType);
82 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
83 ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
84 width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
85 ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
86 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
87 ok(bm.bmBitsPixel == expected_depth, "wrong bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, expected_depth);
88 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
90 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
91 assert(sizeof(buf) == sizeof(buf_cmp));
93 SetLastError(0xdeadbeef);
94 ret = GetBitmapBits(hbm, 0, NULL);
96 ok(ret == bm.bmWidthBytes * bm.bmHeight || (ret == 0 && gle == ERROR_INVALID_PARAMETER /* Win9x */), "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
98 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
99 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
101 memset(buf, 0xAA, sizeof(buf));
102 ret = GetBitmapBits(hbm, sizeof(buf), buf);
103 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
104 ok(!memcmp(buf, buf_cmp, sizeof(buf)) ||
105 broken(memcmp(buf, buf_cmp, sizeof(buf))), /* win9x doesn't init the bitmap bits */
106 "buffers do not match, depth %d\n", bmih->biBitCount);
108 /* test various buffer sizes for GetObject */
109 ret = GetObject(hbm, sizeof(*bma) * 2, bma);
110 ok(ret == sizeof(*bma) || broken(ret == sizeof(*bma) * 2 /* Win9x */), "wrong size %d\n", ret);
112 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
113 ok(ret == 0 || broken(ret == sizeof(bm) / 2 /* Win9x */), "%d != 0\n", ret);
115 ret = GetObject(hbm, 0, &bm);
116 ok(ret == 0, "%d != 0\n", ret);
118 ret = GetObject(hbm, 1, &bm);
119 ok(ret == 0 || broken(ret == 1 /* Win9x */), "%d != 0\n", ret);
121 /* Don't trust Win9x not to try to write to NULL */
124 ret = GetObject(hbm, 0, NULL);
125 ok(ret == sizeof(bm), "wrong size %d\n", ret);
129 static void test_createdibitmap(void)
132 BITMAPINFOHEADER bmih;
134 HBITMAP hbm, hbm_colour, hbm_old;
139 screen_depth = GetDeviceCaps(hdc, BITSPIXEL);
140 memset(&bmih, 0, sizeof(bmih));
141 bmih.biSize = sizeof(bmih);
145 bmih.biBitCount = 32;
146 bmih.biCompression = BI_RGB;
148 /* First create an un-initialised bitmap. The depth of the bitmap
149 should match that of the hdc and not that supplied in bmih.
152 /* First try 32 bits */
153 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
154 ok(hbm != NULL, "CreateDIBitmap failed\n");
155 test_bitmap_info(hbm, screen_depth, &bmih);
159 bmih.biBitCount = 16;
160 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
161 ok(hbm != NULL, "CreateDIBitmap failed\n");
162 test_bitmap_info(hbm, screen_depth, &bmih);
167 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
168 ok(hbm != NULL, "CreateDIBitmap failed\n");
169 test_bitmap_info(hbm, screen_depth, &bmih);
172 /* Now with a monochrome dc we expect a monochrome bitmap */
173 hdcmem = CreateCompatibleDC(hdc);
175 /* First try 32 bits */
176 bmih.biBitCount = 32;
177 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
178 ok(hbm != NULL, "CreateDIBitmap failed\n");
179 test_bitmap_info(hbm, 1, &bmih);
183 bmih.biBitCount = 16;
184 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
185 ok(hbm != NULL, "CreateDIBitmap failed\n");
186 test_bitmap_info(hbm, 1, &bmih);
191 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
192 ok(hbm != NULL, "CreateDIBitmap failed\n");
193 test_bitmap_info(hbm, 1, &bmih);
196 /* Now select a polychrome bitmap into the dc and we expect
197 screen_depth bitmaps again */
198 hbm_colour = CreateCompatibleBitmap(hdc, bmih.biWidth, bmih.biHeight);
199 test_bitmap_info(hbm_colour, screen_depth, &bmih);
200 hbm_old = SelectObject(hdcmem, hbm_colour);
202 /* First try 32 bits */
203 bmih.biBitCount = 32;
204 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
205 ok(hbm != NULL, "CreateDIBitmap failed\n");
206 test_bitmap_info(hbm, screen_depth, &bmih);
210 bmih.biBitCount = 16;
211 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
212 ok(hbm != NULL, "CreateDIBitmap failed\n");
213 test_bitmap_info(hbm, screen_depth, &bmih);
218 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
219 ok(hbm != NULL, "CreateDIBitmap failed\n");
220 test_bitmap_info(hbm, screen_depth, &bmih);
223 SelectObject(hdcmem, hbm_old);
224 DeleteObject(hbm_colour);
227 /* If hdc == 0 then we get a 1 bpp bitmap */
229 bmih.biBitCount = 32;
230 hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0);
231 ok(hbm != NULL, "CreateDIBitmap failed\n");
232 test_bitmap_info(hbm, 1, &bmih);
236 /* Test how formats are converted */
242 memset(&bm, 0, sizeof(bm));
243 bm.bmiHeader.biSize = sizeof(bm.bmiHeader);
244 bm.bmiHeader.biWidth = 1;
245 bm.bmiHeader.biHeight = 1;
246 bm.bmiHeader.biPlanes = 1;
247 bm.bmiHeader.biBitCount= 24;
248 bm.bmiHeader.biCompression= BI_RGB;
249 bm.bmiHeader.biSizeImage = 0;
250 hbm = CreateDIBitmap(hdc, &bmih, CBM_INIT, &pixel, &bm, DIB_RGB_COLORS);
251 ok(hbm != NULL, "CreateDIBitmap failed\n");
254 bm.bmiHeader.biBitCount= 32;
255 GetDIBits(hdc, hbm, 0, 1, &pixel, &bm, DIB_RGB_COLORS);
256 ok(pixel == 0x00ffffff, "Reading a 32 bit pixel from a DDB returned %08x\n", pixel);
262 static INT DIB_GetWidthBytes( int width, int bpp )
268 case 1: words = (width + 31) / 32; break;
269 case 4: words = (width + 7) / 8; break;
270 case 8: words = (width + 3) / 4; break;
272 case 16: words = (width + 1) / 2; break;
273 case 24: words = (width * 3 + 3)/4; break;
274 case 32: words = width; break;
278 trace("Unknown depth %d, please report.\n", bpp );
285 static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
291 INT ret, bm_width_bytes, dib_width_bytes;
294 ret = GetObject(hbm, sizeof(bm), &bm);
295 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
297 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
298 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
299 ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
300 dib_width_bytes = DIB_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
301 bm_width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
302 if (bm.bmWidthBytes != dib_width_bytes) /* Win2k bug */
303 ok(bm.bmWidthBytes == bm_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, bm_width_bytes);
305 ok(bm.bmWidthBytes == dib_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, dib_width_bytes);
306 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
307 ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount);
308 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
310 buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);
312 /* GetBitmapBits returns not 32-bit aligned data */
313 SetLastError(0xdeadbeef);
314 ret = GetBitmapBits(hbm, 0, NULL);
315 ok(ret == bm_width_bytes * bm.bmHeight ||
316 broken(ret == 0 && GetLastError() == ERROR_INVALID_PARAMETER), /* Win9x */
317 "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
319 memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
320 ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
321 ok(ret == bm_width_bytes * bm.bmHeight, "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
323 HeapFree(GetProcessHeap(), 0, buf);
325 /* test various buffer sizes for GetObject */
326 memset(&ds, 0xAA, sizeof(ds));
327 ret = GetObject(hbm, sizeof(*bma) * 2, bma);
328 ok(ret == sizeof(*bma) || broken(ret == sizeof(*bma) * 2 /* Win9x */), "wrong size %d\n", ret);
329 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
330 ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
331 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
333 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
334 ok(ret == 0 || broken(ret == sizeof(bm) / 2 /* Win9x */), "%d != 0\n", ret);
336 ret = GetObject(hbm, 0, &bm);
337 ok(ret == 0, "%d != 0\n", ret);
339 ret = GetObject(hbm, 1, &bm);
340 ok(ret == 0 || broken(ret == 1 /* Win9x */), "%d != 0\n", ret);
342 /* test various buffer sizes for GetObject */
343 ret = GetObject(hbm, 0, NULL);
344 ok(ret == sizeof(bm) || broken(ret == sizeof(DIBSECTION) /* Win9x */), "wrong size %d\n", ret);
346 ret = GetObject(hbm, sizeof(*dsa) * 2, dsa);
347 ok(ret == sizeof(*dsa) || broken(ret == sizeof(*dsa) * 2 /* Win9x */), "wrong size %d\n", ret);
349 memset(&ds, 0xAA, sizeof(ds));
350 ret = GetObject(hbm, sizeof(ds), &ds);
351 ok(ret == sizeof(ds), "wrong size %d\n", ret);
353 ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
354 if (ds.dsBm.bmWidthBytes != bm_width_bytes) /* Win2k bug */
355 ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%u != %u\n",
356 ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
357 ok(bmih->biSizeImage == 0, "%u != 0\n", bmih->biSizeImage);
358 ds.dsBmih.biSizeImage = 0;
360 ok(ds.dsBmih.biSize == bmih->biSize, "%u != %u\n", ds.dsBmih.biSize, bmih->biSize);
361 ok(ds.dsBmih.biWidth == bmih->biWidth, "%u != %u\n", ds.dsBmih.biWidth, bmih->biWidth);
362 ok(ds.dsBmih.biHeight == bmih->biHeight, "%u != %u\n", ds.dsBmih.biHeight, bmih->biHeight);
363 ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes);
364 ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount);
365 ok(ds.dsBmih.biCompression == bmih->biCompression, "%u != %u\n", ds.dsBmih.biCompression, bmih->biCompression);
366 ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%u != %u\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
367 ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%u != %u\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
368 ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%u != %u\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);
370 memset(&ds, 0xAA, sizeof(ds));
371 ret = GetObject(hbm, sizeof(ds) - 4, &ds);
372 ok(ret == sizeof(ds.dsBm) || broken(ret == (sizeof(ds) - 4) /* Win9x */), "wrong size %d\n", ret);
373 ok(ds.dsBm.bmWidth == bmih->biWidth, "%u != %u\n", ds.dsBmih.biWidth, bmih->biWidth);
374 ok(ds.dsBm.bmHeight == bmih->biHeight, "%u != %u\n", ds.dsBmih.biHeight, bmih->biHeight);
375 ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);
377 ret = GetObject(hbm, 0, &ds);
378 ok(ret == 0, "%d != 0\n", ret);
380 ret = GetObject(hbm, 1, &ds);
381 ok(ret == 0 || broken(ret == 1 /* Win9x */), "%d != 0\n", ret);
384 #define test_color_todo(got, exp, txt, todo) \
385 if (!todo && got != exp && screen_depth < 24) { \
386 todo_wine ok(0, #txt " failed at %d-bit screen depth: got 0x%06x expected 0x%06x - skipping DIB tests\n", \
387 screen_depth, (UINT)got, (UINT)exp); \
389 } else if (todo) todo_wine { ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp); } \
390 else ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp) \
392 #define test_color(hdc, color, exp, todo_setp, todo_getp) \
395 c = SetPixel(hdc, 0, 0, color); \
396 if (!is_win9x) { test_color_todo(c, exp, SetPixel, todo_setp); } \
397 c = GetPixel(hdc, 0, 0); \
398 test_color_todo(c, exp, GetPixel, todo_getp); \
401 static void test_dib_bits_access( HBITMAP hdib, void *bits )
403 MEMORY_BASIC_INFORMATION info;
404 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
406 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
408 char filename[MAX_PATH];
413 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
414 "VirtualQuery failed\n");
415 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
416 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
417 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
418 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
419 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
420 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
422 memset( pbmi, 0, sizeof(bmibuf) );
423 memset( data, 0xcc, sizeof(data) );
424 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
425 pbmi->bmiHeader.biHeight = 16;
426 pbmi->bmiHeader.biWidth = 16;
427 pbmi->bmiHeader.biBitCount = 32;
428 pbmi->bmiHeader.biPlanes = 1;
429 pbmi->bmiHeader.biCompression = BI_RGB;
431 ret = SetDIBits( hdc, hdib, 0, 16, data, pbmi, DIB_RGB_COLORS );
433 broken(ret == 0), /* win9x */
434 "SetDIBits failed: expected 16 got %d\n", ret);
436 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
437 "VirtualQuery failed\n");
438 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
439 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
440 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
441 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
442 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
443 /* it has been protected now */
444 todo_wine ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
446 /* try writing protected bits to a file */
448 GetTempFileNameA( ".", "dib", 0, filename );
449 file = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
450 CREATE_ALWAYS, 0, 0 );
451 ok( file != INVALID_HANDLE_VALUE, "failed to open %s error %u\n", filename, GetLastError() );
452 ret = WriteFile( file, bits, 8192, &written, NULL );
453 ok( ret, "WriteFile failed error %u\n", GetLastError() );
454 if (ret) ok( written == 8192, "only wrote %u bytes\n", written );
456 DeleteFileA( filename );
459 static void test_dibsections(void)
461 HDC hdc, hdcmem, hdcmem2;
462 HBITMAP hdib, oldbm, hdib2, oldbm2;
463 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
464 char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
465 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
466 BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
472 char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
473 LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
476 HPALETTE hpal, oldpal;
481 MEMORY_BASIC_INFORMATION info;
484 screen_depth = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
486 memset(pbmi, 0, sizeof(bmibuf));
487 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
488 pbmi->bmiHeader.biHeight = 100;
489 pbmi->bmiHeader.biWidth = 512;
490 pbmi->bmiHeader.biBitCount = 24;
491 pbmi->bmiHeader.biPlanes = 1;
492 pbmi->bmiHeader.biCompression = BI_RGB;
494 SetLastError(0xdeadbeef);
496 /* invalid pointer for BITMAPINFO
497 (*bits should be NULL on error) */
498 bits = (BYTE*)0xdeadbeef;
499 hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
500 ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n");
502 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
503 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
504 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
505 ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
507 /* test the DIB memory */
508 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
509 "VirtualQuery failed\n");
510 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
511 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
512 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
513 ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
514 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
515 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
516 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
518 test_dib_bits_access( hdib, bits );
520 test_dib_info(hdib, bits, &pbmi->bmiHeader);
523 pbmi->bmiHeader.biBitCount = 8;
524 pbmi->bmiHeader.biCompression = BI_RLE8;
525 SetLastError(0xdeadbeef);
526 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
527 ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
528 ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
530 pbmi->bmiHeader.biBitCount = 16;
531 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
532 ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
533 ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
534 ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
535 SetLastError(0xdeadbeef);
536 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
537 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
539 /* test the DIB memory */
540 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
541 "VirtualQuery failed\n");
542 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
543 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
544 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
545 ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
546 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
547 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
548 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
550 test_dib_info(hdib, bits, &pbmi->bmiHeader);
553 memset(pbmi, 0, sizeof(bmibuf));
554 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
555 pbmi->bmiHeader.biHeight = 16;
556 pbmi->bmiHeader.biWidth = 16;
557 pbmi->bmiHeader.biBitCount = 1;
558 pbmi->bmiHeader.biPlanes = 1;
559 pbmi->bmiHeader.biCompression = BI_RGB;
560 pbmi->bmiColors[0].rgbRed = 0xff;
561 pbmi->bmiColors[0].rgbGreen = 0;
562 pbmi->bmiColors[0].rgbBlue = 0;
563 pbmi->bmiColors[1].rgbRed = 0;
564 pbmi->bmiColors[1].rgbGreen = 0;
565 pbmi->bmiColors[1].rgbBlue = 0xff;
567 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
568 ok(hdib != NULL, "CreateDIBSection failed\n");
569 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
570 ok(dibsec.dsBmih.biClrUsed == 2,
571 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
573 /* Test if the old BITMAPCOREINFO structure is supported */
575 pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
576 pbci->bmciHeader.bcBitCount = 0;
579 ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
580 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
581 ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
582 && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
583 "GetDIBits did't fill in the BITMAPCOREHEADER structure properly\n");
585 ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
586 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
587 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
588 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
589 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
590 "The color table has not been translated to the old BITMAPCOREINFO format\n");
592 hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
593 ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
595 ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
596 ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
597 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
598 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
599 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
600 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
601 "The color table has not been translated to the old BITMAPCOREINFO format\n");
603 DeleteObject(hcoredib);
606 hdcmem = CreateCompatibleDC(hdc);
607 oldbm = SelectObject(hdcmem, hdib);
609 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
610 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
611 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
612 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
613 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
614 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
616 c0 = RGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen, pbmi->bmiColors[0].rgbBlue);
617 c1 = RGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen, pbmi->bmiColors[1].rgbBlue);
619 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
620 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
621 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
622 test_color(hdcmem, PALETTEINDEX(0), c0, 1, 1);
623 test_color(hdcmem, PALETTEINDEX(1), c0, 1, 1);
624 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
625 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen,
626 pbmi->bmiColors[0].rgbBlue), c0, 1, 1);
627 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen,
628 pbmi->bmiColors[1].rgbBlue), c1, 1, 1);
629 test_color(hdcmem, PALETTERGB(0, 0, 0), c0, 1, 1);
630 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
631 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1, 1, 1);
633 SelectObject(hdcmem, oldbm);
636 pbmi->bmiColors[0].rgbRed = 0xff;
637 pbmi->bmiColors[0].rgbGreen = 0xff;
638 pbmi->bmiColors[0].rgbBlue = 0xff;
639 pbmi->bmiColors[1].rgbRed = 0;
640 pbmi->bmiColors[1].rgbGreen = 0;
641 pbmi->bmiColors[1].rgbBlue = 0;
643 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
644 ok(hdib != NULL, "CreateDIBSection failed\n");
646 test_dib_info(hdib, bits, &pbmi->bmiHeader);
648 oldbm = SelectObject(hdcmem, hdib);
650 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
651 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
652 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
653 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
654 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
655 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
657 SelectObject(hdcmem, oldbm);
658 test_dib_info(hdib, bits, &pbmi->bmiHeader);
661 pbmi->bmiHeader.biBitCount = 4;
662 for (i = 0; i < 16; i++) {
663 pbmi->bmiColors[i].rgbRed = i;
664 pbmi->bmiColors[i].rgbGreen = 16-i;
665 pbmi->bmiColors[i].rgbBlue = 0;
667 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
668 ok(hdib != NULL, "CreateDIBSection failed\n");
669 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
670 ok(dibsec.dsBmih.biClrUsed == 16,
671 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
672 test_dib_info(hdib, bits, &pbmi->bmiHeader);
675 pbmi->bmiHeader.biBitCount = 8;
677 for (i = 0; i < 128; i++) {
678 pbmi->bmiColors[i].rgbRed = 255 - i * 2;
679 pbmi->bmiColors[i].rgbGreen = i * 2;
680 pbmi->bmiColors[i].rgbBlue = 0;
681 pbmi->bmiColors[255 - i].rgbRed = 0;
682 pbmi->bmiColors[255 - i].rgbGreen = i * 2;
683 pbmi->bmiColors[255 - i].rgbBlue = 255 - i * 2;
685 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
686 ok(hdib != NULL, "CreateDIBSection failed\n");
687 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
688 ok(dibsec.dsBmih.biClrUsed == 256,
689 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
691 oldbm = SelectObject(hdcmem, hdib);
693 for (i = 0; i < 256; i++) {
694 test_color(hdcmem, DIBINDEX(i),
695 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
696 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue),
697 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
700 SelectObject(hdcmem, oldbm);
701 test_dib_info(hdib, bits, &pbmi->bmiHeader);
704 pbmi->bmiHeader.biBitCount = 1;
706 /* Now create a palette and a palette indexed dib section */
707 memset(plogpal, 0, sizeof(logpalbuf));
708 plogpal->palVersion = 0x300;
709 plogpal->palNumEntries = 2;
710 plogpal->palPalEntry[0].peRed = 0xff;
711 plogpal->palPalEntry[0].peBlue = 0xff;
712 plogpal->palPalEntry[1].peGreen = 0xff;
714 index = (WORD*)pbmi->bmiColors;
717 hpal = CreatePalette(plogpal);
718 ok(hpal != NULL, "CreatePalette failed\n");
719 oldpal = SelectPalette(hdc, hpal, TRUE);
720 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
721 ok(hdib != NULL, "CreateDIBSection failed\n");
722 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
723 ok(dibsec.dsBmih.biClrUsed == 2 ||
724 broken(dibsec.dsBmih.biClrUsed == 0), /* win9x */
725 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
727 /* The colour table has already been grabbed from the dc, so we select back the
730 SelectPalette(hdc, oldpal, TRUE);
731 oldbm = SelectObject(hdcmem, hdib);
732 oldpal = SelectPalette(hdcmem, hpal, TRUE);
734 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
735 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
736 ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
737 rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
738 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
739 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
740 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
742 c0 = RGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen, plogpal->palPalEntry[0].peBlue);
743 c1 = RGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen, plogpal->palPalEntry[1].peBlue);
745 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
746 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
747 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
748 test_color(hdcmem, PALETTEINDEX(0), c0, 0, 1);
749 test_color(hdcmem, PALETTEINDEX(1), c1, 0, 1);
750 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
751 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen,
752 plogpal->palPalEntry[0].peBlue), c0, 1, 1);
753 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen,
754 plogpal->palPalEntry[1].peBlue), c1, 1, 1);
755 test_color(hdcmem, PALETTERGB(0, 0, 0), c1, 1, 1);
756 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
757 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0, 1, 1);
758 test_color(hdcmem, PALETTERGB(0, 1, 0), c1, 1, 1);
759 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1, 1, 1);
760 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0, 1, 1);
762 /* Bottom and 2nd row from top green, everything else magenta */
763 bits[0] = bits[1] = 0xff;
764 bits[13 * 4] = bits[13*4 + 1] = 0xff;
766 test_dib_info(hdib, bits, &pbmi->bmiHeader);
768 pbmi->bmiHeader.biBitCount = 32;
770 hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
771 ok(hdib2 != NULL, "CreateDIBSection failed\n");
772 hdcmem2 = CreateCompatibleDC(hdc);
773 oldbm2 = SelectObject(hdcmem2, hdib2);
775 BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
777 ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
778 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
780 SelectObject(hdcmem2, oldbm2);
781 test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
784 SelectObject(hdcmem, oldbm);
785 SelectObject(hdcmem, oldpal);
790 pbmi->bmiHeader.biBitCount = 8;
792 memset(plogpal, 0, sizeof(logpalbuf));
793 plogpal->palVersion = 0x300;
794 plogpal->palNumEntries = 256;
796 for (i = 0; i < 128; i++) {
797 plogpal->palPalEntry[i].peRed = 255 - i * 2;
798 plogpal->palPalEntry[i].peBlue = i * 2;
799 plogpal->palPalEntry[i].peGreen = 0;
800 plogpal->palPalEntry[255 - i].peRed = 0;
801 plogpal->palPalEntry[255 - i].peGreen = i * 2;
802 plogpal->palPalEntry[255 - i].peBlue = 255 - i * 2;
805 index = (WORD*)pbmi->bmiColors;
806 for (i = 0; i < 256; i++) {
810 hpal = CreatePalette(plogpal);
811 ok(hpal != NULL, "CreatePalette failed\n");
812 oldpal = SelectPalette(hdc, hpal, TRUE);
813 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
814 ok(hdib != NULL, "CreateDIBSection failed\n");
815 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
816 ok(dibsec.dsBmih.biClrUsed == 256 ||
817 broken(dibsec.dsBmih.biClrUsed == 0), /* win9x */
818 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
820 test_dib_info(hdib, bits, &pbmi->bmiHeader);
822 SelectPalette(hdc, oldpal, TRUE);
823 oldbm = SelectObject(hdcmem, hdib);
824 oldpal = SelectPalette(hdcmem, hpal, TRUE);
826 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
827 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
828 for (i = 0; i < 256; i++) {
829 ok(rgb[i].rgbRed == plogpal->palPalEntry[i].peRed &&
830 rgb[i].rgbBlue == plogpal->palPalEntry[i].peBlue &&
831 rgb[i].rgbGreen == plogpal->palPalEntry[i].peGreen,
832 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
833 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
836 for (i = 0; i < 256; i++) {
837 test_color(hdcmem, DIBINDEX(i),
838 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
839 test_color(hdcmem, PALETTEINDEX(i),
840 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
841 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue),
842 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
845 SelectPalette(hdcmem, oldpal, TRUE);
846 SelectObject(hdcmem, oldbm);
855 static void test_mono_dibsection(void)
858 HBITMAP old_bm, mono_ds;
859 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
860 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
867 memdc = CreateCompatibleDC(hdc);
869 memset(pbmi, 0, sizeof(bmibuf));
870 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
871 pbmi->bmiHeader.biHeight = 10;
872 pbmi->bmiHeader.biWidth = 10;
873 pbmi->bmiHeader.biBitCount = 1;
874 pbmi->bmiHeader.biPlanes = 1;
875 pbmi->bmiHeader.biCompression = BI_RGB;
876 pbmi->bmiColors[0].rgbRed = 0xff;
877 pbmi->bmiColors[0].rgbGreen = 0xff;
878 pbmi->bmiColors[0].rgbBlue = 0xff;
879 pbmi->bmiColors[1].rgbRed = 0x0;
880 pbmi->bmiColors[1].rgbGreen = 0x0;
881 pbmi->bmiColors[1].rgbBlue = 0x0;
884 * First dib section is 'inverted' ie color[0] is white, color[1] is black
887 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
888 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
889 old_bm = SelectObject(memdc, mono_ds);
891 /* black border, white interior */
892 Rectangle(memdc, 0, 0, 10, 10);
893 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
894 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
896 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
898 memset(bits, 0, sizeof(bits));
901 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
902 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
904 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
906 pbmi->bmiColors[0].rgbRed = 0x0;
907 pbmi->bmiColors[0].rgbGreen = 0x0;
908 pbmi->bmiColors[0].rgbBlue = 0x0;
909 pbmi->bmiColors[1].rgbRed = 0xff;
910 pbmi->bmiColors[1].rgbGreen = 0xff;
911 pbmi->bmiColors[1].rgbBlue = 0xff;
913 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
914 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
916 SelectObject(memdc, old_bm);
917 DeleteObject(mono_ds);
920 * Next dib section is 'normal' ie color[0] is black, color[1] is white
923 pbmi->bmiColors[0].rgbRed = 0x0;
924 pbmi->bmiColors[0].rgbGreen = 0x0;
925 pbmi->bmiColors[0].rgbBlue = 0x0;
926 pbmi->bmiColors[1].rgbRed = 0xff;
927 pbmi->bmiColors[1].rgbGreen = 0xff;
928 pbmi->bmiColors[1].rgbBlue = 0xff;
930 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
931 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
932 old_bm = SelectObject(memdc, mono_ds);
934 /* black border, white interior */
935 Rectangle(memdc, 0, 0, 10, 10);
936 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
937 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
939 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
941 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
942 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
944 /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
946 pbmi->bmiColors[0].rgbRed = 0xff;
947 pbmi->bmiColors[0].rgbGreen = 0xff;
948 pbmi->bmiColors[0].rgbBlue = 0xff;
949 pbmi->bmiColors[1].rgbRed = 0x0;
950 pbmi->bmiColors[1].rgbGreen = 0x0;
951 pbmi->bmiColors[1].rgbBlue = 0x0;
953 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
954 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
957 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
960 pbmi->bmiColors[0].rgbRed = 0xff;
961 pbmi->bmiColors[0].rgbGreen = 0xff;
962 pbmi->bmiColors[0].rgbBlue = 0xff;
963 pbmi->bmiColors[1].rgbRed = 0x0;
964 pbmi->bmiColors[1].rgbGreen = 0x0;
965 pbmi->bmiColors[1].rgbBlue = 0x0;
966 num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors);
967 ok(num == 2, "num = %d\n", num);
969 /* black border, white interior */
970 Rectangle(memdc, 0, 0, 10, 10);
972 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
973 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
975 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
977 memset(bits, 0, sizeof(bits));
980 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
981 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
983 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
985 pbmi->bmiColors[0].rgbRed = 0x0;
986 pbmi->bmiColors[0].rgbGreen = 0x0;
987 pbmi->bmiColors[0].rgbBlue = 0x0;
988 pbmi->bmiColors[1].rgbRed = 0xff;
989 pbmi->bmiColors[1].rgbGreen = 0xff;
990 pbmi->bmiColors[1].rgbBlue = 0xff;
992 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
993 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
995 SelectObject(memdc, old_bm);
996 DeleteObject(mono_ds);
999 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
1002 pbmi->bmiColors[0].rgbRed = 0xff;
1003 pbmi->bmiColors[0].rgbGreen = 0x0;
1004 pbmi->bmiColors[0].rgbBlue = 0x0;
1005 pbmi->bmiColors[1].rgbRed = 0xfe;
1006 pbmi->bmiColors[1].rgbGreen = 0x0;
1007 pbmi->bmiColors[1].rgbBlue = 0x0;
1009 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1010 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1011 old_bm = SelectObject(memdc, mono_ds);
1013 /* black border, white interior */
1014 Rectangle(memdc, 0, 0, 10, 10);
1015 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1016 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1018 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1020 pbmi->bmiColors[0].rgbRed = 0x0;
1021 pbmi->bmiColors[0].rgbGreen = 0x0;
1022 pbmi->bmiColors[0].rgbBlue = 0x0;
1023 pbmi->bmiColors[1].rgbRed = 0xff;
1024 pbmi->bmiColors[1].rgbGreen = 0xff;
1025 pbmi->bmiColors[1].rgbBlue = 0xff;
1027 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1028 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1030 /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
1032 pbmi->bmiColors[0].rgbRed = 0xff;
1033 pbmi->bmiColors[0].rgbGreen = 0xff;
1034 pbmi->bmiColors[0].rgbBlue = 0xff;
1035 pbmi->bmiColors[1].rgbRed = 0x0;
1036 pbmi->bmiColors[1].rgbGreen = 0x0;
1037 pbmi->bmiColors[1].rgbBlue = 0x0;
1039 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1040 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1042 SelectObject(memdc, old_bm);
1043 DeleteObject(mono_ds);
1049 static void test_bitmap(void)
1051 char buf[256], buf_cmp[256];
1052 HBITMAP hbmp, hbmp_old;
1058 hdc = CreateCompatibleDC(0);
1061 SetLastError(0xdeadbeef);
1062 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1065 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1066 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1067 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1072 SetLastError(0xdeadbeef);
1073 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1076 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1077 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1078 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1083 SetLastError(0xdeadbeef);
1084 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1085 ok(!hbmp || broken(hbmp != NULL /* Win9x */), "CreateBitmap should fail\n");
1087 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1088 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1092 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1093 assert(hbmp != NULL);
1095 ret = GetObject(hbmp, sizeof(bm), &bm);
1096 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1098 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1099 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1100 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1101 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1102 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1103 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1104 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1106 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1107 assert(sizeof(buf) == sizeof(buf_cmp));
1109 ret = GetBitmapBits(hbmp, 0, NULL);
1110 ok(ret == bm.bmWidthBytes * bm.bmHeight || broken(ret == 0 /* Win9x */),
1111 "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1113 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1114 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1116 memset(buf, 0xAA, sizeof(buf));
1117 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1118 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1119 ok(!memcmp(buf, buf_cmp, sizeof(buf)) ||
1120 broken(memcmp(buf, buf_cmp, sizeof(buf))), /* win9x doesn't init the bitmap bits */
1121 "buffers do not match\n");
1123 hbmp_old = SelectObject(hdc, hbmp);
1125 ret = GetObject(hbmp, sizeof(bm), &bm);
1126 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1128 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1129 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1130 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1131 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1132 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1133 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1134 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1136 memset(buf, 0xAA, sizeof(buf));
1137 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1138 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1139 ok(!memcmp(buf, buf_cmp, sizeof(buf)) ||
1140 broken(memcmp(buf, buf_cmp, sizeof(buf))), /* win9x doesn't init the bitmap bits */
1141 "buffers do not match\n");
1143 hbmp_old = SelectObject(hdc, hbmp_old);
1144 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1146 /* test various buffer sizes for GetObject */
1147 ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
1148 ok(ret == sizeof(*bma) || broken(ret == sizeof(*bma) * 2 /* Win9x */), "wrong size %d\n", ret);
1150 ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1151 ok(ret == 0 || broken(ret == sizeof(bm) / 2 /* Win9x */), "%d != 0\n", ret);
1153 ret = GetObject(hbmp, 0, &bm);
1154 ok(ret == 0, "%d != 0\n", ret);
1156 ret = GetObject(hbmp, 1, &bm);
1157 ok(ret == 0 || broken(ret == 1 /* Win9x */), "%d != 0\n", ret);
1163 static void test_bmBits(void)
1169 memset(bits, 0, sizeof(bits));
1170 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1171 ok(hbmp != NULL, "CreateBitmap failed\n");
1173 memset(&bmp, 0xFF, sizeof(bmp));
1174 ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1175 "GetObject failed or returned a wrong structure size\n");
1176 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1181 static void test_GetDIBits_selected_DIB(UINT bpp)
1195 /* Create a DIB section with a color table */
1197 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD));
1198 info2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD));
1202 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1204 /* Choose width and height such that the row length (in bytes)
1205 is a multiple of 4 (makes things easier) */
1206 info->bmiHeader.biWidth = 32;
1207 info->bmiHeader.biHeight = 32;
1208 info->bmiHeader.biPlanes = 1;
1209 info->bmiHeader.biBitCount = bpp;
1210 info->bmiHeader.biCompression = BI_RGB;
1212 for (i=0; i < (1u << bpp); i++)
1214 BYTE c = i * (1 << (8 - bpp));
1215 info->bmiColors[i].rgbRed = c;
1216 info->bmiColors[i].rgbGreen = c;
1217 info->bmiColors[i].rgbBlue = c;
1218 info->bmiColors[i].rgbReserved = 0;
1221 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1223 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1225 /* Set the bits of the DIB section */
1226 for (i=0; i < dib_size; i++)
1228 ((BYTE *)bits)[i] = i % 256;
1231 /* Select the DIB into a DC */
1232 dib_dc = CreateCompatibleDC(NULL);
1233 old_bmp = SelectObject(dib_dc, dib);
1234 dc = CreateCompatibleDC(NULL);
1235 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib_size);
1238 /* Copy the DIB attributes but not the color table */
1239 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1241 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1242 ok(res, "GetDIBits failed\n");
1244 /* Compare the color table and the bits */
1245 equalContents = TRUE;
1246 for (i=0; i < (1u << bpp); i++)
1248 if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed)
1249 || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen)
1250 || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue)
1251 || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved))
1253 equalContents = FALSE;
1257 ok(equalContents, "GetDIBits with DIB selected in DC: Invalid DIB color table\n");
1259 equalContents = TRUE;
1260 for (i=0; i < dib_size / sizeof(DWORD); i++)
1262 if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i])
1264 equalContents = FALSE;
1268 ok(equalContents, "GetDIBits with %d bpp DIB selected in DC: Invalid DIB bits\n",bpp);
1270 HeapFree(GetProcessHeap(), 0, bits2);
1273 SelectObject(dib_dc, old_bmp);
1277 HeapFree(GetProcessHeap(), 0, info2);
1278 HeapFree(GetProcessHeap(), 0, info);
1281 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1296 width = height = 16;
1298 /* Create a DDB (device-dependent bitmap) */
1302 ddb = CreateBitmap(width, height, 1, 1, NULL);
1306 HDC screen_dc = GetDC(NULL);
1307 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1308 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1309 ReleaseDC(NULL, screen_dc);
1312 /* Set the pixels */
1313 ddb_dc = CreateCompatibleDC(NULL);
1314 old_bmp = SelectObject(ddb_dc, ddb);
1315 for (i = 0; i < width; i++)
1317 for (j=0; j < height; j++)
1319 BYTE c = (i * width + j) % 256;
1320 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1323 SelectObject(ddb_dc, old_bmp);
1325 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1326 info2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1330 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1331 info->bmiHeader.biWidth = width;
1332 info->bmiHeader.biHeight = height;
1333 info->bmiHeader.biPlanes = 1;
1334 info->bmiHeader.biBitCount = bpp;
1335 info->bmiHeader.biCompression = BI_RGB;
1337 dc = CreateCompatibleDC(NULL);
1339 /* Fill in biSizeImage */
1340 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1341 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1343 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1344 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1349 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1350 ok(res, "GetDIBits failed\n");
1352 /* Copy the DIB attributes but not the color table */
1353 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1355 /* Select the DDB into another DC */
1356 old_bmp = SelectObject(ddb_dc, ddb);
1359 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1360 ok(res, "GetDIBits failed\n");
1362 /* Compare the color table and the bits */
1365 equalContents = TRUE;
1366 for (i=0; i < (1u << bpp); i++)
1368 if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed)
1369 || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen)
1370 || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue)
1371 || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved))
1373 equalContents = FALSE;
1377 ok(equalContents, "GetDIBits with DDB selected in DC: Got a different color table\n");
1380 equalContents = TRUE;
1381 for (i=0; i < info->bmiHeader.biSizeImage / sizeof(DWORD); i++)
1383 if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i])
1385 equalContents = FALSE;
1388 ok(equalContents, "GetDIBits with DDB selected in DC: Got different DIB bits\n");
1390 /* Test the palette */
1391 equalContents = TRUE;
1392 if (info2->bmiHeader.biBitCount <= 8)
1394 WORD *colors = (WORD*)info2->bmiColors;
1396 /* Get the palette indices */
1397 res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1398 if (res == 0 && GetLastError() == ERROR_INVALID_PARAMETER) /* Win9x */
1399 res = GetDIBits(dc, ddb, 0, height, NULL, info2, DIB_PAL_COLORS);
1400 ok(res, "GetDIBits failed\n");
1402 for (i=0;i < 1 << info->bmiHeader.biSizeImage; i++)
1406 equalContents = FALSE;
1412 ok(equalContents, "GetDIBits with DDB selected in DC: non 1:1 palette indices\n");
1414 HeapFree(GetProcessHeap(), 0, bits2);
1415 HeapFree(GetProcessHeap(), 0, bits);
1418 SelectObject(ddb_dc, old_bmp);
1422 HeapFree(GetProcessHeap(), 0, info2);
1423 HeapFree(GetProcessHeap(), 0, info);
1426 static void test_GetDIBits(void)
1428 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1429 static const BYTE bmp_bits_1[16 * 2] =
1431 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1432 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1433 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1434 0xff,0xff, 0,0, 0xff,0xff, 0,0
1436 /* 4-bytes aligned 1-bit DIB data: 16x16 */
1437 static const BYTE dib_bits_1[16 * 4] =
1439 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1440 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1441 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1442 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1444 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1445 static const BYTE bmp_bits_24[16 * 16*3] =
1447 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1448 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1449 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1450 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1451 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1452 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1453 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1454 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1455 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1456 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1457 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1458 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1459 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1460 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1461 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1462 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1463 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1464 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1465 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1466 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1467 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1468 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1469 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1470 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1471 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1472 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1473 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1474 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1475 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1476 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1477 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1478 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1480 /* 4-bytes aligned 24-bit DIB data: 16x16 */
1481 static const BYTE dib_bits_24[16 * 16*3] =
1483 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1484 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1485 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1486 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1487 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1488 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1489 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1490 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1491 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1492 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1493 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1494 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1495 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1496 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1497 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1498 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1499 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1500 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1501 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1502 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1503 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1504 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1505 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1506 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1507 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1508 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1509 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1510 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1511 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1512 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1513 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1514 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1519 int i, bytes, lines;
1521 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1522 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1526 /* 1-bit source bitmap data */
1527 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1528 ok(hbmp != 0, "CreateBitmap failed\n");
1530 memset(&bm, 0xAA, sizeof(bm));
1531 bytes = GetObject(hbmp, sizeof(bm), &bm);
1532 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1533 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1534 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1535 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1536 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1537 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1538 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1539 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1541 bytes = GetBitmapBits(hbmp, 0, NULL);
1542 ok(bytes == sizeof(bmp_bits_1) || broken(bytes == 0 /* Win9x */), "expected 16*2 got %d bytes\n", bytes);
1543 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1544 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1545 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1547 /* retrieve 1-bit DIB data */
1548 memset(bi, 0, sizeof(*bi));
1549 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1550 bi->bmiHeader.biWidth = bm.bmWidth;
1551 bi->bmiHeader.biHeight = bm.bmHeight;
1552 bi->bmiHeader.biPlanes = 1;
1553 bi->bmiHeader.biBitCount = 1;
1554 bi->bmiHeader.biCompression = BI_RGB;
1555 bi->bmiHeader.biSizeImage = 0;
1556 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1557 SetLastError(0xdeadbeef);
1558 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1559 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1560 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1561 broken(GetLastError() == 0xdeadbeef), /* winnt */
1562 "wrong error %u\n", GetLastError());
1563 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1565 memset(buf, 0xAA, sizeof(buf));
1566 SetLastError(0xdeadbeef);
1567 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1568 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1569 lines, bm.bmHeight, GetLastError());
1570 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1) ||
1571 broken(bi->bmiHeader.biSizeImage == 0), /* win9x */
1572 "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1574 /* the color table consists of black and white */
1575 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1576 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1577 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1578 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1579 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1580 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1581 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1582 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1583 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1584 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1585 for (i = 2; i < 256; i++)
1587 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1588 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1589 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1590 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1591 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1594 /* returned bits are DWORD aligned and upside down */
1595 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1597 /* Test the palette indices */
1598 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1599 SetLastError(0xdeadbeef);
1600 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1602 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1603 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1604 for (i = 2; i < 256; i++)
1605 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[1]);
1607 /* retrieve 24-bit DIB data */
1608 memset(bi, 0, sizeof(*bi));
1609 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1610 bi->bmiHeader.biWidth = bm.bmWidth;
1611 bi->bmiHeader.biHeight = bm.bmHeight;
1612 bi->bmiHeader.biPlanes = 1;
1613 bi->bmiHeader.biBitCount = 24;
1614 bi->bmiHeader.biCompression = BI_RGB;
1615 bi->bmiHeader.biSizeImage = 0;
1616 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1617 memset(buf, 0xAA, sizeof(buf));
1618 SetLastError(0xdeadbeef);
1619 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1620 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1621 lines, bm.bmHeight, GetLastError());
1622 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24) ||
1623 broken(bi->bmiHeader.biSizeImage == 0), /* win9x */
1624 "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1626 /* the color table doesn't exist for 24-bit images */
1627 for (i = 0; i < 256; i++)
1629 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1630 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1631 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1632 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1633 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1636 /* returned bits are DWORD aligned and upside down */
1637 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1640 /* 24-bit source bitmap data */
1641 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1642 ok(hbmp != 0, "CreateBitmap failed\n");
1643 SetLastError(0xdeadbeef);
1644 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1645 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1646 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1647 lines, bm.bmHeight, GetLastError());
1649 memset(&bm, 0xAA, sizeof(bm));
1650 bytes = GetObject(hbmp, sizeof(bm), &bm);
1651 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1652 ok(bm.bmType == 0 ||
1653 broken(bm.bmType == 21072), /* win9x */
1654 "wrong bmType %d\n", bm.bmType);
1655 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1656 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1657 ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1658 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1659 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1660 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1662 bytes = GetBitmapBits(hbmp, 0, NULL);
1663 ok(bytes == bm.bmWidthBytes * bm.bmHeight ||
1664 broken(bytes == 0), /* win9x */
1665 "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
1666 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1667 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1668 bm.bmWidthBytes * bm.bmHeight, bytes);
1670 /* retrieve 1-bit DIB data */
1671 memset(bi, 0, sizeof(*bi));
1672 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1673 bi->bmiHeader.biWidth = bm.bmWidth;
1674 bi->bmiHeader.biHeight = bm.bmHeight;
1675 bi->bmiHeader.biPlanes = 1;
1676 bi->bmiHeader.biBitCount = 1;
1677 bi->bmiHeader.biCompression = BI_RGB;
1678 bi->bmiHeader.biSizeImage = 0;
1679 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1680 memset(buf, 0xAA, sizeof(buf));
1681 SetLastError(0xdeadbeef);
1682 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1683 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1684 lines, bm.bmHeight, GetLastError());
1685 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1) ||
1686 broken(bi->bmiHeader.biSizeImage == 0), /* win9x */
1687 "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1689 /* the color table consists of black and white */
1690 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1691 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1692 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1693 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1694 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1695 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1696 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1697 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1698 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1699 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1700 for (i = 2; i < 256; i++)
1702 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1703 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1704 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1705 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1706 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1709 /* returned bits are DWORD aligned and upside down */
1711 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1713 /* Test the palette indices */
1714 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1715 SetLastError(0xdeadbeef);
1716 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1718 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1719 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1720 for (i = 2; i < 256; i++)
1721 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[i]);
1723 /* retrieve 24-bit DIB data */
1724 memset(bi, 0, sizeof(*bi));
1725 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1726 bi->bmiHeader.biWidth = bm.bmWidth;
1727 bi->bmiHeader.biHeight = bm.bmHeight;
1728 bi->bmiHeader.biPlanes = 1;
1729 bi->bmiHeader.biBitCount = 24;
1730 bi->bmiHeader.biCompression = BI_RGB;
1731 bi->bmiHeader.biSizeImage = 0;
1732 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1733 memset(buf, 0xAA, sizeof(buf));
1734 SetLastError(0xdeadbeef);
1735 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1736 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1737 lines, bm.bmHeight, GetLastError());
1738 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24) ||
1739 broken(bi->bmiHeader.biSizeImage == 0), /* win9x */
1740 "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1742 /* the color table doesn't exist for 24-bit images */
1743 for (i = 0; i < 256; i++)
1745 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1746 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1747 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1748 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1749 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1752 /* returned bits are DWORD aligned and upside down */
1753 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1759 static void test_GetDIBits_BI_BITFIELDS(void)
1761 /* Try a screen resolution detection technique
1762 * from the September 1999 issue of Windows Developer's Journal
1763 * which seems to be in widespread use.
1764 * http://www.lesher.ws/highcolor.html
1765 * http://www.lesher.ws/vidfmt.c
1766 * It hinges on being able to retrieve the bitmaps
1767 * for the three primary colors in non-paletted 16 bit mode.
1769 char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
1771 LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
1776 memset(dibinfo, 0, sizeof(dibinfo_buf));
1777 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1780 ok(hdc != NULL, "GetDC failed?\n");
1781 hbm = CreateCompatibleBitmap(hdc, 1, 1);
1782 ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
1784 /* Call GetDIBits to fill in bmiHeader. */
1785 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1786 ok(ret == 1, "GetDIBits failed\n");
1787 if (dibinfo->bmiHeader.biBitCount > 8)
1789 DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
1791 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
1792 "compression is %u\n", dibinfo->bmiHeader.biCompression );
1794 ok( !bitmasks[0], "red mask is set\n" );
1795 ok( !bitmasks[1], "green mask is set\n" );
1796 ok( !bitmasks[2], "blue mask is set\n" );
1798 /* test with NULL bits pointer and correct bpp */
1799 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1800 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1801 ok(ret == 1, "GetDIBits failed\n");
1803 ok( bitmasks[0] != 0, "red mask is not set\n" );
1804 ok( bitmasks[1] != 0, "green mask is not set\n" );
1805 ok( bitmasks[2] != 0, "blue mask is not set\n" );
1806 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1808 /* test with valid bits pointer */
1809 memset(dibinfo, 0, sizeof(dibinfo_buf));
1810 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1811 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1812 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1813 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1814 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
1815 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1817 ok( bitmasks[0] != 0, "red mask is not set\n" );
1818 ok( bitmasks[1] != 0, "green mask is not set\n" );
1819 ok( bitmasks[2] != 0, "blue mask is not set\n" );
1820 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef ||
1821 broken(dibinfo->bmiHeader.biSizeImage == 0xdeadbeef), /* win9x */
1822 "size image not set\n" );
1824 /* now with bits and 0 lines */
1825 memset(dibinfo, 0, sizeof(dibinfo_buf));
1826 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1827 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1828 SetLastError(0xdeadbeef);
1829 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
1830 if (ret == 0 && GetLastError() == ERROR_INVALID_PARAMETER)
1831 win_skip("Win9x/WinMe doesn't handle 0 for the number of scan lines\n");
1834 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1836 ok( !bitmasks[0], "red mask is set\n" );
1837 ok( !bitmasks[1], "green mask is set\n" );
1838 ok( !bitmasks[2], "blue mask is set\n" );
1839 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1841 memset(bitmasks, 0, 3*sizeof(DWORD));
1842 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1843 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
1844 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1846 ok( bitmasks[0] != 0, "red mask is not set\n" );
1847 ok( bitmasks[1] != 0, "green mask is not set\n" );
1848 ok( bitmasks[2] != 0, "blue mask is not set\n" );
1849 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1852 else skip("not in 16 bpp BI_BITFIELDS mode, skipping that test\n");
1855 ReleaseDC(NULL, hdc);
1858 static void test_select_object(void)
1861 HBITMAP hbm, hbm_old;
1863 DWORD depths[] = {8, 15, 16, 24, 32};
1868 ok(hdc != 0, "GetDC(0) failed\n");
1869 hbm = CreateCompatibleBitmap(hdc, 10, 10);
1870 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
1872 hbm_old = SelectObject(hdc, hbm);
1873 ok(hbm_old == 0, "SelectObject should fail\n");
1878 hdc = CreateCompatibleDC(0);
1879 ok(hdc != 0, "GetDC(0) failed\n");
1880 hbm = CreateCompatibleBitmap(hdc, 10, 10);
1881 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
1883 hbm_old = SelectObject(hdc, hbm);
1884 ok(hbm_old != 0, "SelectObject failed\n");
1885 hbm_old = SelectObject(hdc, hbm_old);
1886 ok(hbm_old == hbm, "SelectObject failed\n");
1890 /* test an 1-bpp bitmap */
1891 planes = GetDeviceCaps(hdc, PLANES);
1894 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
1895 ok(hbm != 0, "CreateBitmap failed\n");
1897 hbm_old = SelectObject(hdc, hbm);
1898 ok(hbm_old != 0, "SelectObject failed\n");
1899 hbm_old = SelectObject(hdc, hbm_old);
1900 ok(hbm_old == hbm, "SelectObject failed\n");
1904 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
1905 /* test a color bitmap to dc bpp matching */
1906 planes = GetDeviceCaps(hdc, PLANES);
1907 bpp = GetDeviceCaps(hdc, BITSPIXEL);
1909 hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
1910 ok(hbm != 0, "CreateBitmap failed\n");
1912 hbm_old = SelectObject(hdc, hbm);
1913 if(depths[i] == bpp ||
1914 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
1916 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
1917 SelectObject(hdc, hbm_old);
1919 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
1922 memset(&bm, 0xAA, sizeof(bm));
1923 bytes = GetObject(hbm, sizeof(bm), &bm);
1924 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1925 ok(bm.bmType == 0 ||
1926 broken(bm.bmType == 21072), /* win9x */
1927 "wrong bmType %d\n", bm.bmType);
1928 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
1929 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
1930 ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1931 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
1932 if(depths[i] == 15) {
1933 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
1935 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1937 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1945 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
1950 ret = GetObjectType(hbmp);
1951 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
1953 ret = GetObject(hbmp, 0, 0);
1954 ok_(__FILE__, line)(ret == sizeof(BITMAP) /* XP */ ||
1955 ret == sizeof(DIBSECTION) /* Win9x */, "object size %d\n", ret);
1957 memset(&bm, 0xDA, sizeof(bm));
1958 SetLastError(0xdeadbeef);
1959 ret = GetObject(hbmp, sizeof(bm), &bm);
1960 if (!ret) /* XP, only for curObj2 */ return;
1961 ok_(__FILE__, line)(ret == sizeof(BITMAP) ||
1962 ret == sizeof(DIBSECTION) /* Win9x, only for curObj2 */,
1963 "GetObject returned %d, error %u\n", ret, GetLastError());
1964 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
1965 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
1966 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
1967 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
1968 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
1969 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
1970 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1973 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
1975 static void test_CreateBitmap(void)
1978 HDC screenDC = GetDC(0);
1979 HDC hdc = CreateCompatibleDC(screenDC);
1982 /* all of these are the stock monochrome bitmap */
1983 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
1984 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
1985 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
1986 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
1987 HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
1988 HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
1990 /* these 2 are not the stock monochrome bitmap */
1991 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
1992 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
1994 HBITMAP old1 = SelectObject(hdc, bm2);
1995 HBITMAP old2 = SelectObject(screenDC, bm3);
1996 SelectObject(hdc, old1);
1997 SelectObject(screenDC, old2);
1999 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2000 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2001 bm, bm1, bm4, bm5, curObj1, old1);
2002 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2004 ok(bm != curObj2 || /* WinXP */
2005 broken(bm == curObj2) /* Win9x */,
2006 "0: %p, curObj2 %p\n", bm, curObj2);
2007 ok(old2 == 0, "old2 %p\n", old2);
2009 test_mono_1x1_bmp(bm);
2010 test_mono_1x1_bmp(bm1);
2011 test_mono_1x1_bmp(bm2);
2012 test_mono_1x1_bmp(bm3);
2013 test_mono_1x1_bmp(bm4);
2014 test_mono_1x1_bmp(bm5);
2015 test_mono_1x1_bmp(old1);
2016 test_mono_1x1_bmp(curObj1);
2026 ReleaseDC(0, screenDC);
2028 /* show that Windows ignores the provided bm.bmWidthBytes */
2032 bmp.bmWidthBytes = 28;
2034 bmp.bmBitsPixel = 1;
2036 bm = CreateBitmapIndirect(&bmp);
2037 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2038 test_mono_1x1_bmp(bm);
2041 /* Test how the bmBitsPixel field is treated */
2042 for(i = 1; i <= 33; i++) {
2046 bmp.bmWidthBytes = 28;
2048 bmp.bmBitsPixel = i;
2050 SetLastError(0xdeadbeef);
2051 bm = CreateBitmapIndirect(&bmp);
2053 DWORD error = GetLastError();
2055 broken(bm != 0), /* Win9x and WinMe */
2056 "CreateBitmapIndirect for %d bpp succeeded\n", i);
2057 ok(error == ERROR_INVALID_PARAMETER ||
2058 broken(error == 0xdeadbeef), /* Win9x and WinME */
2059 "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2063 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2064 GetObject(bm, sizeof(bmp), &bmp);
2071 } else if(i <= 16) {
2073 } else if(i <= 24) {
2075 } else if(i <= 32) {
2078 ok(bmp.bmBitsPixel == expect ||
2079 broken(bmp.bmBitsPixel == i), /* Win9x and WinMe */
2080 "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2081 i, bmp.bmBitsPixel, expect);
2086 static void test_bitmapinfoheadersize(void)
2093 memset(&bmi, 0, sizeof(BITMAPINFO));
2094 bmi.bmiHeader.biHeight = 100;
2095 bmi.bmiHeader.biWidth = 512;
2096 bmi.bmiHeader.biBitCount = 24;
2097 bmi.bmiHeader.biPlanes = 1;
2099 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2101 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2102 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2104 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2106 SetLastError(0xdeadbeef);
2107 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2108 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2111 bmi.bmiHeader.biSize++;
2113 SetLastError(0xdeadbeef);
2114 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2116 broken(!hdib), /* Win98, WinMe */
2117 "CreateDIBSection error %d\n", GetLastError());
2120 bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2122 SetLastError(0xdeadbeef);
2123 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2125 broken(!hdib), /* Win98, WinMe */
2126 "CreateDIBSection error %d\n", GetLastError());
2129 bmi.bmiHeader.biSize++;
2131 SetLastError(0xdeadbeef);
2132 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2134 broken(!hdib), /* Win98, WinMe */
2135 "CreateDIBSection error %d\n", GetLastError());
2138 bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2140 SetLastError(0xdeadbeef);
2141 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2142 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2145 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2147 SetLastError(0xdeadbeef);
2148 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2150 broken(!hdib), /* Win95 */
2151 "CreateDIBSection error %d\n", GetLastError());
2154 memset(&bci, 0, sizeof(BITMAPCOREINFO));
2155 bci.bmciHeader.bcHeight = 100;
2156 bci.bmciHeader.bcWidth = 512;
2157 bci.bmciHeader.bcBitCount = 24;
2158 bci.bmciHeader.bcPlanes = 1;
2160 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2162 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2163 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2165 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2167 SetLastError(0xdeadbeef);
2168 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2169 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2172 bci.bmciHeader.bcSize++;
2174 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2175 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2177 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2179 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2180 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2185 static void test_get16dibits(void)
2187 BYTE bits[4 * (16 / sizeof(BYTE))];
2189 HDC screen_dc = GetDC(NULL);
2192 int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2194 int overwritten_bytes = 0;
2196 memset(bits, 0, sizeof(bits));
2197 hbmp = CreateBitmap(2, 2, 1, 16, bits);
2198 ok(hbmp != NULL, "CreateBitmap failed\n");
2200 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2203 memset(info, '!', info_len);
2204 memset(info, 0, sizeof(info->bmiHeader));
2206 info->bmiHeader.biSize = sizeof(info->bmiHeader);
2207 info->bmiHeader.biWidth = 2;
2208 info->bmiHeader.biHeight = 2;
2209 info->bmiHeader.biPlanes = 1;
2210 info->bmiHeader.biCompression = BI_RGB;
2212 ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2214 broken(ret == 0), /* win9x */
2215 "GetDIBits failed got %d\n", ret);
2217 for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2219 overwritten_bytes++;
2220 ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2222 HeapFree(GetProcessHeap(), 0, info);
2224 ReleaseDC(NULL, screen_dc);
2227 static void test_GdiAlphaBlend(void)
2229 /* test out-of-bound parameters for GdiAlphaBlend */
2242 BLENDFUNCTION blend;
2244 if (!pGdiAlphaBlend)
2246 win_skip("GdiAlphaBlend() is not implemented\n");
2250 hdcNull = GetDC(NULL);
2251 hdcDst = CreateCompatibleDC(hdcNull);
2252 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
2253 hdcSrc = CreateCompatibleDC(hdcNull);
2255 memset(&bmi, 0, sizeof(bmi)); /* as of Wine 0.9.44 we require the src to be a DIB section */
2256 bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
2257 bmi.bmiHeader.biHeight = 20;
2258 bmi.bmiHeader.biWidth = 20;
2259 bmi.bmiHeader.biBitCount = 32;
2260 bmi.bmiHeader.biPlanes = 1;
2261 bmi.bmiHeader.biCompression = BI_RGB;
2262 bmpSrc = CreateDIBSection(hdcDst, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
2263 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
2265 oldDst = SelectObject(hdcDst, bmpDst);
2266 oldSrc = SelectObject(hdcSrc, bmpSrc);
2268 blend.BlendOp = AC_SRC_OVER;
2269 blend.BlendFlags = 0;
2270 blend.SourceConstantAlpha = 128;
2271 blend.AlphaFormat = 0;
2273 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend), TRUE, BOOL, "%d");
2274 SetLastError(0xdeadbeef);
2275 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), FALSE, BOOL, "%d");
2276 expect_eq(GetLastError(), ERROR_INVALID_PARAMETER, int, "%d");
2277 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), FALSE, BOOL, "%d");
2278 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend), FALSE, BOOL, "%d");
2279 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
2280 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
2282 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
2283 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), TRUE, BOOL, "%d");
2284 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), TRUE, BOOL, "%d");
2285 SetMapMode(hdcSrc, MM_ANISOTROPIC);
2286 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
2287 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend), TRUE, BOOL, "%d");
2288 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend), TRUE, BOOL, "%d");
2290 SelectObject(hdcDst, oldDst);
2291 SelectObject(hdcSrc, oldSrc);
2292 DeleteObject(bmpSrc);
2293 DeleteObject(bmpDst);
2297 ReleaseDC(NULL, hdcNull);
2301 static void test_clipping(void)
2311 HDC hdcDst = CreateCompatibleDC( NULL );
2312 HDC hdcSrc = CreateCompatibleDC( NULL );
2314 BITMAPINFO bmpinfo={{0}};
2315 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2316 bmpinfo.bmiHeader.biWidth = 100;
2317 bmpinfo.bmiHeader.biHeight = 100;
2318 bmpinfo.bmiHeader.biPlanes = 1;
2319 bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
2320 bmpinfo.bmiHeader.biCompression = BI_RGB;
2322 bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
2323 ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
2324 oldDst = SelectObject( hdcDst, bmpDst );
2326 bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
2327 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
2328 oldSrc = SelectObject( hdcSrc, bmpSrc );
2330 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
2331 ok(result, "BitBlt failed\n");
2333 hRgn = CreateRectRgn( 0,0,0,0 );
2334 SelectClipRgn( hdcDst, hRgn );
2336 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
2337 ok(result, "BitBlt failed\n");
2339 DeleteObject( bmpDst );
2340 DeleteObject( bmpSrc );
2341 DeleteObject( hRgn );
2349 is_win9x = GetWindowLongPtrW(GetDesktopWindow(), GWLP_WNDPROC) == 0;
2351 hdll = GetModuleHandle("gdi32.dll");
2352 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
2354 test_createdibitmap();
2356 test_mono_dibsection();
2359 test_GetDIBits_selected_DIB(1);
2360 test_GetDIBits_selected_DIB(4);
2361 test_GetDIBits_selected_DIB(8);
2362 test_GetDIBits_selected_DDB(TRUE);
2363 test_GetDIBits_selected_DDB(FALSE);
2365 test_GetDIBits_BI_BITFIELDS();
2366 test_select_object();
2367 test_CreateBitmap();
2368 test_GdiAlphaBlend();
2369 test_bitmapinfoheadersize();