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);
36 static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
38 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
40 static INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp )
45 return 2 * ((bmWidth+15) >> 4);
48 bmWidth *= 3; /* fall through */
50 return bmWidth + (bmWidth & 1);
60 return 2 * ((bmWidth+3) >> 2);
63 trace("Unknown depth %d, please report.\n", bpp );
69 static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHEADER *bmih)
74 BYTE 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 SetLastError(0xdeadbeef);
92 ret = GetBitmapBits(hbm, 0, NULL);
93 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
95 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
96 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
98 memset(buf, 0xAA, sizeof(buf));
99 ret = GetBitmapBits(hbm, sizeof(buf), buf);
100 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
101 ok(!memcmp(buf, buf_cmp, sizeof(buf)),
102 "buffers do not match, depth %d\n", bmih->biBitCount);
104 /* test various buffer sizes for GetObject */
105 ret = GetObject(hbm, sizeof(*bma) * 2, bma);
106 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
108 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
109 ok(ret == 0, "%d != 0\n", ret);
111 ret = GetObject(hbm, 0, &bm);
112 ok(ret == 0, "%d != 0\n", ret);
114 ret = GetObject(hbm, 1, &bm);
115 ok(ret == 0, "%d != 0\n", ret);
117 ret = GetObject(hbm, 0, NULL);
118 ok(ret == sizeof(bm), "wrong size %d\n", ret);
121 static void test_createdibitmap(void)
124 BITMAPINFOHEADER bmih;
126 HBITMAP hbm, hbm_colour, hbm_old;
131 screen_depth = GetDeviceCaps(hdc, BITSPIXEL);
132 memset(&bmih, 0, sizeof(bmih));
133 bmih.biSize = sizeof(bmih);
137 bmih.biBitCount = 32;
138 bmih.biCompression = BI_RGB;
140 hbm = CreateDIBitmap(hdc, NULL, CBM_INIT, NULL, NULL, 0);
141 ok(hbm == NULL, "CreateDIBitmap should fail\n");
142 hbm = CreateDIBitmap(hdc, NULL, 0, NULL, NULL, 0);
143 ok(hbm == NULL, "CreateDIBitmap should fail\n");
145 /* First create an un-initialised bitmap. The depth of the bitmap
146 should match that of the hdc and not that supplied in bmih.
149 /* First try 32 bits */
150 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
151 ok(hbm != NULL, "CreateDIBitmap failed\n");
152 test_bitmap_info(hbm, screen_depth, &bmih);
156 bmih.biBitCount = 16;
157 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
158 ok(hbm != NULL, "CreateDIBitmap failed\n");
159 test_bitmap_info(hbm, screen_depth, &bmih);
164 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
165 ok(hbm != NULL, "CreateDIBitmap failed\n");
166 test_bitmap_info(hbm, screen_depth, &bmih);
169 /* Now with a monochrome dc we expect a monochrome bitmap */
170 hdcmem = CreateCompatibleDC(hdc);
172 /* First try 32 bits */
173 bmih.biBitCount = 32;
174 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
175 ok(hbm != NULL, "CreateDIBitmap failed\n");
176 test_bitmap_info(hbm, 1, &bmih);
180 bmih.biBitCount = 16;
181 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
182 ok(hbm != NULL, "CreateDIBitmap failed\n");
183 test_bitmap_info(hbm, 1, &bmih);
188 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
189 ok(hbm != NULL, "CreateDIBitmap failed\n");
190 test_bitmap_info(hbm, 1, &bmih);
193 /* Now select a polychrome bitmap into the dc and we expect
194 screen_depth bitmaps again */
195 hbm_colour = CreateCompatibleBitmap(hdc, bmih.biWidth, bmih.biHeight);
196 test_bitmap_info(hbm_colour, screen_depth, &bmih);
197 hbm_old = SelectObject(hdcmem, hbm_colour);
199 /* First try 32 bits */
200 bmih.biBitCount = 32;
201 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
202 ok(hbm != NULL, "CreateDIBitmap failed\n");
203 test_bitmap_info(hbm, screen_depth, &bmih);
207 bmih.biBitCount = 16;
208 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
209 ok(hbm != NULL, "CreateDIBitmap failed\n");
210 test_bitmap_info(hbm, screen_depth, &bmih);
215 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
216 ok(hbm != NULL, "CreateDIBitmap failed\n");
217 test_bitmap_info(hbm, screen_depth, &bmih);
220 SelectObject(hdcmem, hbm_old);
221 DeleteObject(hbm_colour);
224 bmih.biBitCount = 32;
225 hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0);
226 ok(hbm != NULL, "CreateDIBitmap failed\n");
227 test_bitmap_info(hbm, 1, &bmih);
230 /* Test how formats are converted */
236 memset(&bm, 0, sizeof(bm));
237 bm.bmiHeader.biSize = sizeof(bm.bmiHeader);
238 bm.bmiHeader.biWidth = 1;
239 bm.bmiHeader.biHeight = 1;
240 bm.bmiHeader.biPlanes = 1;
241 bm.bmiHeader.biBitCount= 24;
242 bm.bmiHeader.biCompression= BI_RGB;
243 bm.bmiHeader.biSizeImage = 0;
244 hbm = CreateDIBitmap(hdc, &bmih, CBM_INIT, &pixel, &bm, DIB_RGB_COLORS);
245 ok(hbm != NULL, "CreateDIBitmap failed\n");
248 bm.bmiHeader.biBitCount= 32;
249 GetDIBits(hdc, hbm, 0, 1, &pixel, &bm, DIB_RGB_COLORS);
250 ok(pixel == 0x00ffffff, "Reading a 32 bit pixel from a DDB returned %08x\n", pixel);
256 static INT DIB_GetWidthBytes( int width, int bpp )
262 case 1: words = (width + 31) / 32; break;
263 case 4: words = (width + 7) / 8; break;
264 case 8: words = (width + 3) / 4; break;
266 case 16: words = (width + 1) / 2; break;
267 case 24: words = (width * 3 + 3)/4; break;
268 case 32: words = width; break;
272 trace("Unknown depth %d, please report.\n", bpp );
279 static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
285 INT ret, bm_width_bytes, dib_width_bytes;
288 ret = GetObject(hbm, sizeof(bm), &bm);
289 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
291 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
292 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
293 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
294 dib_width_bytes = DIB_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
295 bm_width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
296 if (bm.bmWidthBytes != dib_width_bytes) /* Win2k bug */
297 ok(bm.bmWidthBytes == bm_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, bm_width_bytes);
299 ok(bm.bmWidthBytes == dib_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, dib_width_bytes);
300 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
301 ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount);
302 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
304 buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);
306 /* GetBitmapBits returns not 32-bit aligned data */
307 SetLastError(0xdeadbeef);
308 ret = GetBitmapBits(hbm, 0, NULL);
309 ok(ret == bm_width_bytes * bm.bmHeight,
310 "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
312 memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
313 ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
314 ok(ret == bm_width_bytes * bm.bmHeight, "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
316 HeapFree(GetProcessHeap(), 0, buf);
318 /* test various buffer sizes for GetObject */
319 memset(&ds, 0xAA, sizeof(ds));
320 ret = GetObject(hbm, sizeof(*bma) * 2, bma);
321 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
322 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
323 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
324 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
326 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
327 ok(ret == 0, "%d != 0\n", ret);
329 ret = GetObject(hbm, 0, &bm);
330 ok(ret == 0, "%d != 0\n", ret);
332 ret = GetObject(hbm, 1, &bm);
333 ok(ret == 0, "%d != 0\n", ret);
335 /* test various buffer sizes for GetObject */
336 ret = GetObject(hbm, 0, NULL);
337 ok(ret == sizeof(bm), "wrong size %d\n", ret);
339 ret = GetObject(hbm, sizeof(*dsa) * 2, dsa);
340 ok(ret == sizeof(*dsa), "wrong size %d\n", ret);
342 memset(&ds, 0xAA, sizeof(ds));
343 ret = GetObject(hbm, sizeof(ds), &ds);
344 ok(ret == sizeof(ds), "wrong size %d\n", ret);
346 ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
347 if (ds.dsBm.bmWidthBytes != bm_width_bytes) /* Win2k bug */
348 ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%u != %u\n",
349 ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
350 ok(bmih->biSizeImage == 0, "%u != 0\n", bmih->biSizeImage);
351 ds.dsBmih.biSizeImage = 0;
353 ok(ds.dsBmih.biSize == bmih->biSize, "%u != %u\n", ds.dsBmih.biSize, bmih->biSize);
354 ok(ds.dsBmih.biWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
355 ok(ds.dsBmih.biHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
356 ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes);
357 ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount);
358 ok(ds.dsBmih.biCompression == bmih->biCompression ||
359 ((bmih->biBitCount == 32) && broken(ds.dsBmih.biCompression == BI_BITFIELDS)), /* nt4 sp1 and 2 */
360 "%u != %u\n", ds.dsBmih.biCompression, bmih->biCompression);
361 ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%u != %u\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
362 ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%d != %d\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
363 ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%d != %d\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);
365 memset(&ds, 0xAA, sizeof(ds));
366 ret = GetObject(hbm, sizeof(ds) - 4, &ds);
367 ok(ret == sizeof(ds.dsBm), "wrong size %d\n", ret);
368 ok(ds.dsBm.bmWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
369 ok(ds.dsBm.bmHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
370 ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);
372 ret = GetObject(hbm, 0, &ds);
373 ok(ret == 0, "%d != 0\n", ret);
375 ret = GetObject(hbm, 1, &ds);
376 ok(ret == 0, "%d != 0\n", ret);
379 #define test_color_todo(got, exp, txt, todo) \
380 if (!todo && got != exp && screen_depth < 24) { \
381 todo_wine ok(0, #txt " failed at %d-bit screen depth: got 0x%06x expected 0x%06x - skipping DIB tests\n", \
382 screen_depth, (UINT)got, (UINT)exp); \
384 } else if (todo) todo_wine { ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp); } \
385 else ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp) \
387 #define test_color(hdc, color, exp, todo_setp, todo_getp) \
390 c = SetPixel(hdc, 0, 0, color); \
391 test_color_todo(c, exp, SetPixel, todo_setp); \
392 c = GetPixel(hdc, 0, 0); \
393 test_color_todo(c, exp, GetPixel, todo_getp); \
396 static void test_dib_bits_access( HBITMAP hdib, void *bits )
398 MEMORY_BASIC_INFORMATION info;
399 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
401 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
403 char filename[MAX_PATH];
408 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
409 "VirtualQuery failed\n");
410 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
411 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
412 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
413 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
414 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
415 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
417 memset( pbmi, 0, sizeof(bmibuf) );
418 memset( data, 0xcc, sizeof(data) );
419 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
420 pbmi->bmiHeader.biHeight = 16;
421 pbmi->bmiHeader.biWidth = 16;
422 pbmi->bmiHeader.biBitCount = 32;
423 pbmi->bmiHeader.biPlanes = 1;
424 pbmi->bmiHeader.biCompression = BI_RGB;
428 ret = SetDIBits( hdc, hdib, 0, 16, data, pbmi, DIB_RGB_COLORS );
429 ok(ret == 16, "SetDIBits failed: expected 16 got %d\n", ret);
433 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
434 "VirtualQuery failed\n");
435 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
436 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
437 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
438 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
439 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
440 /* it has been protected now */
441 todo_wine ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
443 /* try writing protected bits to a file */
445 GetTempFileNameA( ".", "dib", 0, filename );
446 file = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
447 CREATE_ALWAYS, 0, 0 );
448 ok( file != INVALID_HANDLE_VALUE, "failed to open %s error %u\n", filename, GetLastError() );
449 ret = WriteFile( file, bits, 8192, &written, NULL );
450 ok( ret, "WriteFile failed error %u\n", GetLastError() );
451 if (ret) ok( written == 8192, "only wrote %u bytes\n", written );
453 DeleteFileA( filename );
456 static void test_dibsections(void)
458 HDC hdc, hdcmem, hdcmem2;
459 HBITMAP hdib, oldbm, hdib2, oldbm2;
460 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
461 char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
462 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
463 BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
469 char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
470 LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
473 HPALETTE hpal, oldpal;
478 MEMORY_BASIC_INFORMATION info;
481 screen_depth = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
483 memset(pbmi, 0, sizeof(bmibuf));
484 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
485 pbmi->bmiHeader.biHeight = 100;
486 pbmi->bmiHeader.biWidth = 512;
487 pbmi->bmiHeader.biBitCount = 24;
488 pbmi->bmiHeader.biPlanes = 1;
489 pbmi->bmiHeader.biCompression = BI_RGB;
491 SetLastError(0xdeadbeef);
493 /* invalid pointer for BITMAPINFO
494 (*bits should be NULL on error) */
495 bits = (BYTE*)0xdeadbeef;
496 hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
497 ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n");
499 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
500 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
501 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
502 ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
504 /* test the DIB memory */
505 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
506 "VirtualQuery failed\n");
507 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
508 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
509 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
510 ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
511 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
512 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
513 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
515 test_dib_bits_access( hdib, bits );
517 test_dib_info(hdib, bits, &pbmi->bmiHeader);
520 /* Test a top-down DIB. */
521 pbmi->bmiHeader.biHeight = -100;
522 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
523 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
524 test_dib_info(hdib, bits, &pbmi->bmiHeader);
527 pbmi->bmiHeader.biHeight = 100;
528 pbmi->bmiHeader.biBitCount = 8;
529 pbmi->bmiHeader.biCompression = BI_RLE8;
530 SetLastError(0xdeadbeef);
531 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
532 ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
533 ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
535 for (i = 0; i < 128; i++)
537 pbmi->bmiHeader.biBitCount = i;
538 pbmi->bmiHeader.biCompression = BI_RGB;
539 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
540 if (i == 1 || i == 4 || i == 8 || i == 16 || i == 24 || i == 32)
541 ok(hdib != NULL, "CreateDIBSection bpp %u\n", i);
543 ok(hdib == NULL, "CreateDIBSection bpp %u succeeded\n", i);
544 if (hdib) DeleteObject( hdib );
547 pbmi->bmiHeader.biBitCount = 16;
548 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
549 ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
550 ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
551 ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
552 SetLastError(0xdeadbeef);
553 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
554 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
556 /* test the DIB memory */
557 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
558 "VirtualQuery failed\n");
559 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
560 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
561 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
562 ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
563 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
564 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
565 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
567 test_dib_info(hdib, bits, &pbmi->bmiHeader);
570 memset(pbmi, 0, sizeof(bmibuf));
571 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
572 pbmi->bmiHeader.biHeight = 16;
573 pbmi->bmiHeader.biWidth = 16;
574 pbmi->bmiHeader.biBitCount = 1;
575 pbmi->bmiHeader.biPlanes = 1;
576 pbmi->bmiHeader.biCompression = BI_RGB;
577 pbmi->bmiColors[0].rgbRed = 0xff;
578 pbmi->bmiColors[0].rgbGreen = 0;
579 pbmi->bmiColors[0].rgbBlue = 0;
580 pbmi->bmiColors[1].rgbRed = 0;
581 pbmi->bmiColors[1].rgbGreen = 0;
582 pbmi->bmiColors[1].rgbBlue = 0xff;
584 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
585 ok(hdib != NULL, "CreateDIBSection failed\n");
586 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
587 ok(dibsec.dsBmih.biClrUsed == 2,
588 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
590 /* Test if the old BITMAPCOREINFO structure is supported */
592 pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
593 pbci->bmciHeader.bcBitCount = 0;
595 ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
596 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
597 ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
598 && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
599 "GetDIBits did't fill in the BITMAPCOREHEADER structure properly\n");
601 ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
602 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
603 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
604 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
605 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
606 "The color table has not been translated to the old BITMAPCOREINFO format\n");
608 hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
609 ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
611 ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
612 ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
613 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
614 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
615 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
616 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
617 "The color table has not been translated to the old BITMAPCOREINFO format\n");
619 DeleteObject(hcoredib);
621 hdcmem = CreateCompatibleDC(hdc);
622 oldbm = SelectObject(hdcmem, hdib);
624 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
625 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
626 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
627 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
628 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
629 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
631 c0 = RGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen, pbmi->bmiColors[0].rgbBlue);
632 c1 = RGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen, pbmi->bmiColors[1].rgbBlue);
634 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
635 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
636 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
637 test_color(hdcmem, PALETTEINDEX(0), c0, 1, 1);
638 test_color(hdcmem, PALETTEINDEX(1), c0, 1, 1);
639 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
640 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen,
641 pbmi->bmiColors[0].rgbBlue), c0, 1, 1);
642 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen,
643 pbmi->bmiColors[1].rgbBlue), c1, 1, 1);
644 test_color(hdcmem, PALETTERGB(0, 0, 0), c0, 1, 1);
645 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
646 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1, 1, 1);
648 SelectObject(hdcmem, oldbm);
651 pbmi->bmiColors[0].rgbRed = 0xff;
652 pbmi->bmiColors[0].rgbGreen = 0xff;
653 pbmi->bmiColors[0].rgbBlue = 0xff;
654 pbmi->bmiColors[1].rgbRed = 0;
655 pbmi->bmiColors[1].rgbGreen = 0;
656 pbmi->bmiColors[1].rgbBlue = 0;
658 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
659 ok(hdib != NULL, "CreateDIBSection failed\n");
661 test_dib_info(hdib, bits, &pbmi->bmiHeader);
663 oldbm = SelectObject(hdcmem, hdib);
665 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
666 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
667 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
668 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
669 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
670 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
672 SelectObject(hdcmem, oldbm);
673 test_dib_info(hdib, bits, &pbmi->bmiHeader);
676 pbmi->bmiHeader.biBitCount = 4;
677 for (i = 0; i < 16; i++) {
678 pbmi->bmiColors[i].rgbRed = i;
679 pbmi->bmiColors[i].rgbGreen = 16-i;
680 pbmi->bmiColors[i].rgbBlue = 0;
682 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
683 ok(hdib != NULL, "CreateDIBSection failed\n");
684 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
685 ok(dibsec.dsBmih.biClrUsed == 16,
686 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
687 test_dib_info(hdib, bits, &pbmi->bmiHeader);
690 pbmi->bmiHeader.biBitCount = 8;
692 for (i = 0; i < 128; i++) {
693 pbmi->bmiColors[i].rgbRed = 255 - i * 2;
694 pbmi->bmiColors[i].rgbGreen = i * 2;
695 pbmi->bmiColors[i].rgbBlue = 0;
696 pbmi->bmiColors[255 - i].rgbRed = 0;
697 pbmi->bmiColors[255 - i].rgbGreen = i * 2;
698 pbmi->bmiColors[255 - i].rgbBlue = 255 - i * 2;
700 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
701 ok(hdib != NULL, "CreateDIBSection failed\n");
702 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
703 ok(dibsec.dsBmih.biClrUsed == 256,
704 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
706 oldbm = SelectObject(hdcmem, hdib);
708 for (i = 0; i < 256; i++) {
709 test_color(hdcmem, DIBINDEX(i),
710 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
711 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue),
712 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
715 SelectObject(hdcmem, oldbm);
716 test_dib_info(hdib, bits, &pbmi->bmiHeader);
719 pbmi->bmiHeader.biBitCount = 1;
721 /* Now create a palette and a palette indexed dib section */
722 memset(plogpal, 0, sizeof(logpalbuf));
723 plogpal->palVersion = 0x300;
724 plogpal->palNumEntries = 2;
725 plogpal->palPalEntry[0].peRed = 0xff;
726 plogpal->palPalEntry[0].peBlue = 0xff;
727 plogpal->palPalEntry[1].peGreen = 0xff;
729 index = (WORD*)pbmi->bmiColors;
732 hpal = CreatePalette(plogpal);
733 ok(hpal != NULL, "CreatePalette failed\n");
734 oldpal = SelectPalette(hdc, hpal, TRUE);
735 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
736 ok(hdib != NULL, "CreateDIBSection failed\n");
737 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
738 ok(dibsec.dsBmih.biClrUsed == 2, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
740 /* The colour table has already been grabbed from the dc, so we select back the
743 SelectPalette(hdc, oldpal, TRUE);
744 oldbm = SelectObject(hdcmem, hdib);
745 oldpal = SelectPalette(hdcmem, hpal, TRUE);
747 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
748 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
749 ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
750 rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
751 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
752 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
753 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
755 c0 = RGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen, plogpal->palPalEntry[0].peBlue);
756 c1 = RGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen, plogpal->palPalEntry[1].peBlue);
758 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
759 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
760 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
761 test_color(hdcmem, PALETTEINDEX(0), c0, 0, 1);
762 test_color(hdcmem, PALETTEINDEX(1), c1, 0, 1);
763 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
764 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen,
765 plogpal->palPalEntry[0].peBlue), c0, 1, 1);
766 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen,
767 plogpal->palPalEntry[1].peBlue), c1, 1, 1);
768 test_color(hdcmem, PALETTERGB(0, 0, 0), c1, 1, 1);
769 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
770 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0, 1, 1);
771 test_color(hdcmem, PALETTERGB(0, 1, 0), c1, 1, 1);
772 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1, 1, 1);
773 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0, 1, 1);
775 /* Bottom and 2nd row from top green, everything else magenta */
776 bits[0] = bits[1] = 0xff;
777 bits[13 * 4] = bits[13*4 + 1] = 0xff;
779 test_dib_info(hdib, bits, &pbmi->bmiHeader);
781 pbmi->bmiHeader.biBitCount = 32;
783 hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
784 ok(hdib2 != NULL, "CreateDIBSection failed\n");
785 hdcmem2 = CreateCompatibleDC(hdc);
786 oldbm2 = SelectObject(hdcmem2, hdib2);
788 BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
790 ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
791 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
793 SelectObject(hdcmem2, oldbm2);
794 test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
797 SelectObject(hdcmem, oldbm);
798 SelectPalette(hdcmem, oldpal, TRUE);
803 pbmi->bmiHeader.biBitCount = 8;
805 memset(plogpal, 0, sizeof(logpalbuf));
806 plogpal->palVersion = 0x300;
807 plogpal->palNumEntries = 256;
809 for (i = 0; i < 128; i++) {
810 plogpal->palPalEntry[i].peRed = 255 - i * 2;
811 plogpal->palPalEntry[i].peBlue = i * 2;
812 plogpal->palPalEntry[i].peGreen = 0;
813 plogpal->palPalEntry[255 - i].peRed = 0;
814 plogpal->palPalEntry[255 - i].peGreen = i * 2;
815 plogpal->palPalEntry[255 - i].peBlue = 255 - i * 2;
818 index = (WORD*)pbmi->bmiColors;
819 for (i = 0; i < 256; i++) {
823 hpal = CreatePalette(plogpal);
824 ok(hpal != NULL, "CreatePalette failed\n");
825 oldpal = SelectPalette(hdc, hpal, TRUE);
826 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
827 ok(hdib != NULL, "CreateDIBSection failed\n");
828 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
829 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
831 test_dib_info(hdib, bits, &pbmi->bmiHeader);
833 SelectPalette(hdc, oldpal, TRUE);
834 oldbm = SelectObject(hdcmem, hdib);
835 oldpal = SelectPalette(hdcmem, hpal, TRUE);
837 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
838 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
839 for (i = 0; i < 256; i++) {
840 ok(rgb[i].rgbRed == plogpal->palPalEntry[i].peRed &&
841 rgb[i].rgbBlue == plogpal->palPalEntry[i].peBlue &&
842 rgb[i].rgbGreen == plogpal->palPalEntry[i].peGreen,
843 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
844 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
847 for (i = 0; i < 256; i++) {
848 test_color(hdcmem, DIBINDEX(i),
849 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
850 test_color(hdcmem, PALETTEINDEX(i),
851 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
852 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue),
853 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
856 SelectPalette(hdcmem, oldpal, TRUE);
857 SelectObject(hdcmem, oldbm);
866 static void test_mono_dibsection(void)
869 HBITMAP old_bm, mono_ds;
870 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
871 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
878 memdc = CreateCompatibleDC(hdc);
880 memset(pbmi, 0, sizeof(bmibuf));
881 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
882 pbmi->bmiHeader.biHeight = 10;
883 pbmi->bmiHeader.biWidth = 10;
884 pbmi->bmiHeader.biBitCount = 1;
885 pbmi->bmiHeader.biPlanes = 1;
886 pbmi->bmiHeader.biCompression = BI_RGB;
887 pbmi->bmiColors[0].rgbRed = 0xff;
888 pbmi->bmiColors[0].rgbGreen = 0xff;
889 pbmi->bmiColors[0].rgbBlue = 0xff;
890 pbmi->bmiColors[1].rgbRed = 0x0;
891 pbmi->bmiColors[1].rgbGreen = 0x0;
892 pbmi->bmiColors[1].rgbBlue = 0x0;
895 * First dib section is 'inverted' ie color[0] is white, color[1] is black
898 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
899 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
900 old_bm = SelectObject(memdc, mono_ds);
902 /* black border, white interior */
903 Rectangle(memdc, 0, 0, 10, 10);
904 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
905 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
907 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
909 memset(bits, 0, sizeof(bits));
912 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
913 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
915 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
917 pbmi->bmiColors[0].rgbRed = 0x0;
918 pbmi->bmiColors[0].rgbGreen = 0x0;
919 pbmi->bmiColors[0].rgbBlue = 0x0;
920 pbmi->bmiColors[1].rgbRed = 0xff;
921 pbmi->bmiColors[1].rgbGreen = 0xff;
922 pbmi->bmiColors[1].rgbBlue = 0xff;
924 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
925 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
927 SelectObject(memdc, old_bm);
928 DeleteObject(mono_ds);
931 * Next dib section is 'normal' ie color[0] is black, color[1] is white
934 pbmi->bmiColors[0].rgbRed = 0x0;
935 pbmi->bmiColors[0].rgbGreen = 0x0;
936 pbmi->bmiColors[0].rgbBlue = 0x0;
937 pbmi->bmiColors[1].rgbRed = 0xff;
938 pbmi->bmiColors[1].rgbGreen = 0xff;
939 pbmi->bmiColors[1].rgbBlue = 0xff;
941 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
942 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
943 old_bm = SelectObject(memdc, mono_ds);
945 /* black border, white interior */
946 Rectangle(memdc, 0, 0, 10, 10);
947 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
948 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
950 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
952 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
953 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
955 /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
957 pbmi->bmiColors[0].rgbRed = 0xff;
958 pbmi->bmiColors[0].rgbGreen = 0xff;
959 pbmi->bmiColors[0].rgbBlue = 0xff;
960 pbmi->bmiColors[1].rgbRed = 0x0;
961 pbmi->bmiColors[1].rgbGreen = 0x0;
962 pbmi->bmiColors[1].rgbBlue = 0x0;
964 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
965 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
968 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
971 pbmi->bmiColors[0].rgbRed = 0xff;
972 pbmi->bmiColors[0].rgbGreen = 0xff;
973 pbmi->bmiColors[0].rgbBlue = 0xff;
974 pbmi->bmiColors[1].rgbRed = 0x0;
975 pbmi->bmiColors[1].rgbGreen = 0x0;
976 pbmi->bmiColors[1].rgbBlue = 0x0;
977 num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors);
978 ok(num == 2, "num = %d\n", num);
980 /* black border, white interior */
981 Rectangle(memdc, 0, 0, 10, 10);
982 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
983 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
985 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
987 memset(bits, 0, sizeof(bits));
990 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
991 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
993 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
995 pbmi->bmiColors[0].rgbRed = 0x0;
996 pbmi->bmiColors[0].rgbGreen = 0x0;
997 pbmi->bmiColors[0].rgbBlue = 0x0;
998 pbmi->bmiColors[1].rgbRed = 0xff;
999 pbmi->bmiColors[1].rgbGreen = 0xff;
1000 pbmi->bmiColors[1].rgbBlue = 0xff;
1002 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1003 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1005 SelectObject(memdc, old_bm);
1006 DeleteObject(mono_ds);
1009 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
1012 pbmi->bmiColors[0].rgbRed = 0xff;
1013 pbmi->bmiColors[0].rgbGreen = 0x0;
1014 pbmi->bmiColors[0].rgbBlue = 0x0;
1015 pbmi->bmiColors[1].rgbRed = 0xfe;
1016 pbmi->bmiColors[1].rgbGreen = 0x0;
1017 pbmi->bmiColors[1].rgbBlue = 0x0;
1019 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1020 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1021 old_bm = SelectObject(memdc, mono_ds);
1023 /* black border, white interior */
1024 Rectangle(memdc, 0, 0, 10, 10);
1025 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1026 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1028 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1030 pbmi->bmiColors[0].rgbRed = 0x0;
1031 pbmi->bmiColors[0].rgbGreen = 0x0;
1032 pbmi->bmiColors[0].rgbBlue = 0x0;
1033 pbmi->bmiColors[1].rgbRed = 0xff;
1034 pbmi->bmiColors[1].rgbGreen = 0xff;
1035 pbmi->bmiColors[1].rgbBlue = 0xff;
1037 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1038 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1040 /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
1042 pbmi->bmiColors[0].rgbRed = 0xff;
1043 pbmi->bmiColors[0].rgbGreen = 0xff;
1044 pbmi->bmiColors[0].rgbBlue = 0xff;
1045 pbmi->bmiColors[1].rgbRed = 0x0;
1046 pbmi->bmiColors[1].rgbGreen = 0x0;
1047 pbmi->bmiColors[1].rgbBlue = 0x0;
1049 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1050 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1052 SelectObject(memdc, old_bm);
1053 DeleteObject(mono_ds);
1059 static void test_bitmap(void)
1061 char buf[256], buf_cmp[256];
1062 HBITMAP hbmp, hbmp_old;
1068 hdc = CreateCompatibleDC(0);
1071 SetLastError(0xdeadbeef);
1072 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1075 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1076 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1077 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1082 SetLastError(0xdeadbeef);
1083 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1086 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1087 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1088 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1093 SetLastError(0xdeadbeef);
1094 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1095 ok(!hbmp, "CreateBitmap should fail\n");
1097 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1098 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1102 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1103 assert(hbmp != NULL);
1105 ret = GetObject(hbmp, sizeof(bm), &bm);
1106 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1108 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1109 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1110 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1111 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1112 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1113 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1114 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1116 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1117 assert(sizeof(buf) == sizeof(buf_cmp));
1119 ret = GetBitmapBits(hbmp, 0, NULL);
1120 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1122 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1123 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1125 memset(buf, 0xAA, sizeof(buf));
1126 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1127 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1128 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1130 hbmp_old = SelectObject(hdc, hbmp);
1132 ret = GetObject(hbmp, sizeof(bm), &bm);
1133 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1135 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1136 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1137 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1138 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1139 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1140 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1141 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1143 memset(buf, 0xAA, sizeof(buf));
1144 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1145 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1146 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1148 hbmp_old = SelectObject(hdc, hbmp_old);
1149 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1151 /* test various buffer sizes for GetObject */
1152 ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
1153 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1155 ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1156 ok(ret == 0, "%d != 0\n", ret);
1158 ret = GetObject(hbmp, 0, &bm);
1159 ok(ret == 0, "%d != 0\n", ret);
1161 ret = GetObject(hbmp, 1, &bm);
1162 ok(ret == 0, "%d != 0\n", ret);
1168 static void test_bmBits(void)
1174 memset(bits, 0, sizeof(bits));
1175 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1176 ok(hbmp != NULL, "CreateBitmap failed\n");
1178 memset(&bmp, 0xFF, sizeof(bmp));
1179 ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1180 "GetObject failed or returned a wrong structure size\n");
1181 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1186 static void test_GetDIBits_selected_DIB(UINT bpp)
1193 UINT dib_size, dib32_size;
1201 /* Create a DIB section with a color table */
1203 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD));
1204 info2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD));
1208 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1210 /* Choose width and height such that the row length (in bytes)
1211 is a multiple of 4 (makes things easier) */
1212 info->bmiHeader.biWidth = 32;
1213 info->bmiHeader.biHeight = 32;
1214 info->bmiHeader.biPlanes = 1;
1215 info->bmiHeader.biBitCount = bpp;
1216 info->bmiHeader.biCompression = BI_RGB;
1218 for (i=0; i < (1u << bpp); i++)
1220 BYTE c = i * (1 << (8 - bpp));
1221 info->bmiColors[i].rgbRed = c;
1222 info->bmiColors[i].rgbGreen = c;
1223 info->bmiColors[i].rgbBlue = c;
1224 info->bmiColors[i].rgbReserved = 0;
1227 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1229 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1230 dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1232 /* Set the bits of the DIB section */
1233 for (i=0; i < dib_size; i++)
1235 ((BYTE *)bits)[i] = i % 256;
1238 /* Select the DIB into a DC */
1239 dib_dc = CreateCompatibleDC(NULL);
1240 old_bmp = SelectObject(dib_dc, dib);
1241 dc = CreateCompatibleDC(NULL);
1242 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
1245 /* Copy the DIB attributes but not the color table */
1246 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1248 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1249 ok(res, "GetDIBits failed\n");
1251 /* Compare the color table and the bits */
1252 equalContents = TRUE;
1253 for (i=0; i < (1u << bpp); i++)
1255 if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed)
1256 || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen)
1257 || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue)
1258 || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved))
1260 equalContents = FALSE;
1264 ok(equalContents, "GetDIBits with DIB selected in DC: Invalid DIB color table\n");
1266 equalContents = TRUE;
1267 for (i=0; i < dib_size / sizeof(DWORD); i++)
1269 if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i])
1271 equalContents = FALSE;
1275 ok(equalContents, "GetDIBits with %d bpp DIB selected in DC: Invalid DIB bits\n",bpp);
1277 /* Map into a 32bit-DIB */
1278 info2->bmiHeader.biBitCount = 32;
1279 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1280 ok(res, "GetDIBits failed\n");
1282 /* Check if last pixel was set */
1283 pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
1284 ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
1286 HeapFree(GetProcessHeap(), 0, bits2);
1289 SelectObject(dib_dc, old_bmp);
1293 HeapFree(GetProcessHeap(), 0, info2);
1294 HeapFree(GetProcessHeap(), 0, info);
1297 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1312 width = height = 16;
1314 /* Create a DDB (device-dependent bitmap) */
1318 ddb = CreateBitmap(width, height, 1, 1, NULL);
1322 HDC screen_dc = GetDC(NULL);
1323 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1324 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1325 ReleaseDC(NULL, screen_dc);
1328 /* Set the pixels */
1329 ddb_dc = CreateCompatibleDC(NULL);
1330 old_bmp = SelectObject(ddb_dc, ddb);
1331 for (i = 0; i < width; i++)
1333 for (j=0; j < height; j++)
1335 BYTE c = (i * width + j) % 256;
1336 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1339 SelectObject(ddb_dc, old_bmp);
1341 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1342 info2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1346 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1347 info->bmiHeader.biWidth = width;
1348 info->bmiHeader.biHeight = height;
1349 info->bmiHeader.biPlanes = 1;
1350 info->bmiHeader.biBitCount = bpp;
1351 info->bmiHeader.biCompression = BI_RGB;
1353 dc = CreateCompatibleDC(NULL);
1355 /* Fill in biSizeImage */
1356 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1357 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1359 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1360 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1365 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1366 ok(res, "GetDIBits failed\n");
1368 /* Copy the DIB attributes but not the color table */
1369 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1371 /* Select the DDB into another DC */
1372 old_bmp = SelectObject(ddb_dc, ddb);
1375 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1376 ok(res, "GetDIBits failed\n");
1378 /* Compare the color table and the bits */
1381 equalContents = TRUE;
1382 for (i=0; i < (1u << bpp); i++)
1384 if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed)
1385 || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen)
1386 || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue)
1387 || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved))
1389 equalContents = FALSE;
1393 ok(equalContents, "GetDIBits with DDB selected in DC: Got a different color table\n");
1396 equalContents = TRUE;
1397 for (i=0; i < info->bmiHeader.biSizeImage / sizeof(DWORD); i++)
1399 if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i])
1401 equalContents = FALSE;
1404 ok(equalContents, "GetDIBits with DDB selected in DC: Got different DIB bits\n");
1406 /* Test the palette */
1407 equalContents = TRUE;
1408 if (info2->bmiHeader.biBitCount <= 8)
1410 WORD *colors = (WORD*)info2->bmiColors;
1412 /* Get the palette indices */
1413 res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1414 ok(res, "GetDIBits failed\n");
1416 for (i=0;i < 1 << info->bmiHeader.biSizeImage; i++)
1420 equalContents = FALSE;
1426 ok(equalContents, "GetDIBits with DDB selected in DC: non 1:1 palette indices\n");
1428 HeapFree(GetProcessHeap(), 0, bits2);
1429 HeapFree(GetProcessHeap(), 0, bits);
1432 SelectObject(ddb_dc, old_bmp);
1436 HeapFree(GetProcessHeap(), 0, info2);
1437 HeapFree(GetProcessHeap(), 0, info);
1440 static void test_GetDIBits(void)
1442 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1443 static const BYTE bmp_bits_1[16 * 2] =
1445 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1446 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1447 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1448 0xff,0xff, 0,0, 0xff,0xff, 0,0
1450 /* 4-bytes aligned 1-bit DIB data: 16x16 */
1451 static const BYTE dib_bits_1[16 * 4] =
1453 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1454 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1455 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1456 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1458 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1459 static const BYTE bmp_bits_24[16 * 16*3] =
1461 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1462 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1463 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1464 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1465 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1466 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1467 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1468 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1469 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1470 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1471 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1472 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1473 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1474 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1475 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1476 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1477 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1478 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1479 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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1481 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1482 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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
1494 /* 4-bytes aligned 24-bit DIB data: 16x16 */
1495 static const BYTE dib_bits_24[16 * 16*3] =
1497 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1498 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1499 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1500 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1501 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1502 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1503 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1504 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1505 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1506 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1507 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1508 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1509 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1510 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1511 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1512 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1513 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1514 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1515 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1516 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1517 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1518 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1519 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1520 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1521 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1522 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1523 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1524 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1525 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1526 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1527 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1528 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1533 int i, bytes, lines;
1535 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1536 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1537 PALETTEENTRY pal_ents[20];
1541 /* 1-bit source bitmap data */
1542 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1543 ok(hbmp != 0, "CreateBitmap failed\n");
1545 memset(&bm, 0xAA, sizeof(bm));
1546 bytes = GetObject(hbmp, sizeof(bm), &bm);
1547 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1548 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1549 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1550 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1551 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1552 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1553 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1554 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1556 bytes = GetBitmapBits(hbmp, 0, NULL);
1557 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1558 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1559 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1560 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1562 /* retrieve 1-bit DIB data */
1563 memset(bi, 0, sizeof(*bi));
1564 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1565 bi->bmiHeader.biWidth = bm.bmWidth;
1566 bi->bmiHeader.biHeight = bm.bmHeight;
1567 bi->bmiHeader.biPlanes = 1;
1568 bi->bmiHeader.biBitCount = 1;
1569 bi->bmiHeader.biCompression = BI_RGB;
1570 bi->bmiHeader.biSizeImage = 0;
1571 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1572 SetLastError(0xdeadbeef);
1573 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1574 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1575 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1576 broken(GetLastError() == 0xdeadbeef), /* winnt */
1577 "wrong error %u\n", GetLastError());
1578 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1580 memset(buf, 0xAA, sizeof(buf));
1581 SetLastError(0xdeadbeef);
1582 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1583 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1584 lines, bm.bmHeight, GetLastError());
1585 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1587 /* the color table consists of black and white */
1588 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1589 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1590 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1591 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1592 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1593 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1594 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1595 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1596 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1597 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1598 for (i = 2; i < 256; i++)
1600 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1601 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1602 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1603 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1604 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1607 /* returned bits are DWORD aligned and upside down */
1608 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1610 /* Test the palette indices */
1611 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1612 SetLastError(0xdeadbeef);
1613 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1614 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1615 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1616 for (i = 2; i < 256; i++)
1617 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[1]);
1619 /* retrieve 24-bit DIB data */
1620 memset(bi, 0, sizeof(*bi));
1621 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1622 bi->bmiHeader.biWidth = bm.bmWidth;
1623 bi->bmiHeader.biHeight = bm.bmHeight;
1624 bi->bmiHeader.biPlanes = 1;
1625 bi->bmiHeader.biBitCount = 24;
1626 bi->bmiHeader.biCompression = BI_RGB;
1627 bi->bmiHeader.biSizeImage = 0;
1628 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1629 memset(buf, 0xAA, sizeof(buf));
1630 SetLastError(0xdeadbeef);
1631 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1632 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1633 lines, bm.bmHeight, GetLastError());
1634 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1636 /* the color table doesn't exist for 24-bit images */
1637 for (i = 0; i < 256; i++)
1639 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1640 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1641 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1642 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1643 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1646 /* returned bits are DWORD aligned and upside down */
1647 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1650 /* 24-bit source bitmap data */
1651 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1652 ok(hbmp != 0, "CreateBitmap failed\n");
1653 SetLastError(0xdeadbeef);
1654 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1655 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1656 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1657 lines, bm.bmHeight, GetLastError());
1659 memset(&bm, 0xAA, sizeof(bm));
1660 bytes = GetObject(hbmp, sizeof(bm), &bm);
1661 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1662 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1663 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1664 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1665 ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1666 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1667 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1668 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1670 bytes = GetBitmapBits(hbmp, 0, NULL);
1671 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
1672 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1673 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1674 bm.bmWidthBytes * bm.bmHeight, bytes);
1676 /* retrieve 1-bit DIB data */
1677 memset(bi, 0, sizeof(*bi));
1678 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1679 bi->bmiHeader.biWidth = bm.bmWidth;
1680 bi->bmiHeader.biHeight = bm.bmHeight;
1681 bi->bmiHeader.biPlanes = 1;
1682 bi->bmiHeader.biBitCount = 1;
1683 bi->bmiHeader.biCompression = BI_RGB;
1684 bi->bmiHeader.biSizeImage = 0;
1685 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1686 memset(buf, 0xAA, sizeof(buf));
1687 SetLastError(0xdeadbeef);
1688 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1689 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1690 lines, bm.bmHeight, GetLastError());
1691 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1693 /* the color table consists of black and white */
1694 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1695 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1696 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1697 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1698 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1699 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1700 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1701 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1702 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1703 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1704 for (i = 2; i < 256; i++)
1706 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1707 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1708 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1709 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1710 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1713 /* returned bits are DWORD aligned and upside down */
1714 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1716 /* Test the palette indices */
1717 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1718 SetLastError(0xdeadbeef);
1719 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1720 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1721 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1722 for (i = 2; i < 256; i++)
1723 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[i]);
1725 /* retrieve 4-bit DIB data */
1726 memset(bi, 0, sizeof(*bi));
1727 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1728 bi->bmiHeader.biWidth = bm.bmWidth;
1729 bi->bmiHeader.biHeight = bm.bmHeight;
1730 bi->bmiHeader.biPlanes = 1;
1731 bi->bmiHeader.biBitCount = 4;
1732 bi->bmiHeader.biCompression = BI_RGB;
1733 bi->bmiHeader.biSizeImage = 0;
1734 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1735 memset(buf, 0xAA, sizeof(buf));
1736 SetLastError(0xdeadbeef);
1737 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1738 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1739 lines, bm.bmHeight, GetLastError());
1741 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
1743 for (i = 0; i < 16; i++)
1746 int entry = i < 8 ? i : i + 4;
1748 if(entry == 7) entry = 12;
1749 else if(entry == 12) entry = 7;
1751 expect.rgbRed = pal_ents[entry].peRed;
1752 expect.rgbGreen = pal_ents[entry].peGreen;
1753 expect.rgbBlue = pal_ents[entry].peBlue;
1754 expect.rgbReserved = 0;
1756 ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
1757 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
1758 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
1759 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1760 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1763 /* retrieve 8-bit DIB data */
1764 memset(bi, 0, sizeof(*bi));
1765 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1766 bi->bmiHeader.biWidth = bm.bmWidth;
1767 bi->bmiHeader.biHeight = bm.bmHeight;
1768 bi->bmiHeader.biPlanes = 1;
1769 bi->bmiHeader.biBitCount = 8;
1770 bi->bmiHeader.biCompression = BI_RGB;
1771 bi->bmiHeader.biSizeImage = 0;
1772 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1773 memset(buf, 0xAA, sizeof(buf));
1774 SetLastError(0xdeadbeef);
1775 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1776 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1777 lines, bm.bmHeight, GetLastError());
1779 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
1781 for (i = 0; i < 256; i++)
1785 if (i < 10 || i >= 246)
1787 int entry = i < 10 ? i : i - 236;
1788 expect.rgbRed = pal_ents[entry].peRed;
1789 expect.rgbGreen = pal_ents[entry].peGreen;
1790 expect.rgbBlue = pal_ents[entry].peBlue;
1794 expect.rgbRed = (i & 0x07) << 5;
1795 expect.rgbGreen = (i & 0x38) << 2;
1796 expect.rgbBlue = i & 0xc0;
1798 expect.rgbReserved = 0;
1800 ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
1801 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
1802 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
1803 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1804 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1807 /* retrieve 24-bit DIB data */
1808 memset(bi, 0, sizeof(*bi));
1809 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1810 bi->bmiHeader.biWidth = bm.bmWidth;
1811 bi->bmiHeader.biHeight = bm.bmHeight;
1812 bi->bmiHeader.biPlanes = 1;
1813 bi->bmiHeader.biBitCount = 24;
1814 bi->bmiHeader.biCompression = BI_RGB;
1815 bi->bmiHeader.biSizeImage = 0;
1816 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1817 memset(buf, 0xAA, sizeof(buf));
1818 SetLastError(0xdeadbeef);
1819 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1820 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1821 lines, bm.bmHeight, GetLastError());
1822 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1824 /* the color table doesn't exist for 24-bit images */
1825 for (i = 0; i < 256; i++)
1827 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1828 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1829 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1830 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1831 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1834 /* returned bits are DWORD aligned and upside down */
1835 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1841 static void test_GetDIBits_BI_BITFIELDS(void)
1843 /* Try a screen resolution detection technique
1844 * from the September 1999 issue of Windows Developer's Journal
1845 * which seems to be in widespread use.
1846 * http://www.lesher.ws/highcolor.html
1847 * http://www.lesher.ws/vidfmt.c
1848 * It hinges on being able to retrieve the bitmaps
1849 * for the three primary colors in non-paletted 16 bit mode.
1851 char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
1853 LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
1854 DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
1860 memset(dibinfo, 0, sizeof(dibinfo_buf));
1861 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1864 ok(hdc != NULL, "GetDC failed?\n");
1865 hbm = CreateCompatibleBitmap(hdc, 1, 1);
1866 ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
1868 /* Call GetDIBits to fill in bmiHeader. */
1869 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1870 ok(ret == 1, "GetDIBits failed\n");
1871 if (dibinfo->bmiHeader.biBitCount > 8)
1873 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
1874 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
1875 "compression is %u (%d bpp)\n", dibinfo->bmiHeader.biCompression, dibinfo->bmiHeader.biBitCount );
1877 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
1879 ok( !bitmasks[0], "red mask is set\n" );
1880 ok( !bitmasks[1], "green mask is set\n" );
1881 ok( !bitmasks[2], "blue mask is set\n" );
1883 /* test with NULL bits pointer and correct bpp */
1884 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1885 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1886 ok(ret == 1, "GetDIBits failed\n");
1888 ok( bitmasks[0] != 0, "red mask is not set\n" );
1889 ok( bitmasks[1] != 0, "green mask is not set\n" );
1890 ok( bitmasks[2] != 0, "blue mask is not set\n" );
1891 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1893 /* test with valid bits pointer */
1894 memset(dibinfo, 0, sizeof(dibinfo_buf));
1895 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1896 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1897 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1898 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1899 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
1900 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1902 ok( bitmasks[0] != 0, "red mask is not set\n" );
1903 ok( bitmasks[1] != 0, "green mask is not set\n" );
1904 ok( bitmasks[2] != 0, "blue mask is not set\n" );
1905 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1907 /* now with bits and 0 lines */
1908 memset(dibinfo, 0, sizeof(dibinfo_buf));
1909 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1910 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1911 SetLastError(0xdeadbeef);
1912 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
1913 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1915 ok( !bitmasks[0], "red mask is set\n" );
1916 ok( !bitmasks[1], "green mask is set\n" );
1917 ok( !bitmasks[2], "blue mask is set\n" );
1918 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1920 memset(bitmasks, 0, 3*sizeof(DWORD));
1921 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1922 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
1923 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1925 ok( bitmasks[0] != 0, "red mask is not set\n" );
1926 ok( bitmasks[1] != 0, "green mask is not set\n" );
1927 ok( bitmasks[2] != 0, "blue mask is not set\n" );
1928 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1931 else skip("bitmap in colortable mode, skipping BI_BITFIELDS tests\n");
1935 /* same thing now with a 32-bpp DIB section */
1937 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1938 dibinfo->bmiHeader.biWidth = 1;
1939 dibinfo->bmiHeader.biHeight = 1;
1940 dibinfo->bmiHeader.biPlanes = 1;
1941 dibinfo->bmiHeader.biBitCount = 32;
1942 dibinfo->bmiHeader.biCompression = BI_RGB;
1943 dibinfo->bmiHeader.biSizeImage = 0;
1944 dibinfo->bmiHeader.biXPelsPerMeter = 0;
1945 dibinfo->bmiHeader.biYPelsPerMeter = 0;
1946 dibinfo->bmiHeader.biClrUsed = 0;
1947 dibinfo->bmiHeader.biClrImportant = 0;
1948 bitmasks[0] = 0x0000ff;
1949 bitmasks[1] = 0x00ff00;
1950 bitmasks[2] = 0xff0000;
1951 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
1952 ok( hbm != 0, "failed to create bitmap\n" );
1954 memset(dibinfo, 0, sizeof(dibinfo_buf));
1955 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1956 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
1957 ok(ret == 1, "GetDIBits failed\n");
1958 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
1960 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
1961 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
1962 "compression is %u\n", dibinfo->bmiHeader.biCompression );
1963 ok( !bitmasks[0], "red mask is set\n" );
1964 ok( !bitmasks[1], "green mask is set\n" );
1965 ok( !bitmasks[2], "blue mask is set\n" );
1967 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1968 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
1969 ok(ret == 1, "GetDIBits failed\n");
1970 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
1971 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
1972 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
1973 "compression is %u\n", dibinfo->bmiHeader.biCompression );
1974 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
1976 ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
1977 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
1978 ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
1980 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1984 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1985 dibinfo->bmiHeader.biWidth = 1;
1986 dibinfo->bmiHeader.biHeight = 1;
1987 dibinfo->bmiHeader.biPlanes = 1;
1988 dibinfo->bmiHeader.biBitCount = 32;
1989 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
1990 dibinfo->bmiHeader.biSizeImage = 0;
1991 dibinfo->bmiHeader.biXPelsPerMeter = 0;
1992 dibinfo->bmiHeader.biYPelsPerMeter = 0;
1993 dibinfo->bmiHeader.biClrUsed = 0;
1994 dibinfo->bmiHeader.biClrImportant = 0;
1995 bitmasks[0] = 0x0000ff;
1996 bitmasks[1] = 0x00ff00;
1997 bitmasks[2] = 0xff0000;
1998 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
1999 ok( hbm != 0, "failed to create bitmap\n" );
2003 memset(dibinfo, 0, sizeof(dibinfo_buf));
2004 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2005 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2006 ok(ret == 1, "GetDIBits failed\n");
2008 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
2009 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2010 ok( !bitmasks[0], "red mask is set\n" );
2011 ok( !bitmasks[1], "green mask is set\n" );
2012 ok( !bitmasks[2], "blue mask is set\n" );
2014 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2015 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2016 ok(ret == 1, "GetDIBits failed\n");
2017 ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
2018 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2019 ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
2020 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2025 /* 24-bpp DIB sections don't have bitfields */
2027 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2028 dibinfo->bmiHeader.biWidth = 1;
2029 dibinfo->bmiHeader.biHeight = 1;
2030 dibinfo->bmiHeader.biPlanes = 1;
2031 dibinfo->bmiHeader.biBitCount = 24;
2032 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2033 dibinfo->bmiHeader.biSizeImage = 0;
2034 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2035 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2036 dibinfo->bmiHeader.biClrUsed = 0;
2037 dibinfo->bmiHeader.biClrImportant = 0;
2038 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2039 ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
2040 dibinfo->bmiHeader.biCompression = BI_RGB;
2041 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2042 ok( hbm != 0, "failed to create bitmap\n" );
2044 memset(dibinfo, 0, sizeof(dibinfo_buf));
2045 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2046 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2047 ok(ret == 1, "GetDIBits failed\n");
2048 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2050 ok( dibinfo->bmiHeader.biCompression == BI_RGB,
2051 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2052 ok( !bitmasks[0], "red mask is set\n" );
2053 ok( !bitmasks[1], "green mask is set\n" );
2054 ok( !bitmasks[2], "blue mask is set\n" );
2056 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2057 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2058 ok(ret == 1, "GetDIBits failed\n");
2059 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2060 ok( !bitmasks[0], "red mask is set\n" );
2061 ok( !bitmasks[1], "green mask is set\n" );
2062 ok( !bitmasks[2], "blue mask is set\n" );
2063 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2066 ReleaseDC(NULL, hdc);
2069 static void test_select_object(void)
2072 HBITMAP hbm, hbm_old;
2074 DWORD depths[] = {8, 15, 16, 24, 32};
2079 ok(hdc != 0, "GetDC(0) failed\n");
2080 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2081 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2083 hbm_old = SelectObject(hdc, hbm);
2084 ok(hbm_old == 0, "SelectObject should fail\n");
2089 hdc = CreateCompatibleDC(0);
2090 ok(hdc != 0, "GetDC(0) failed\n");
2091 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2092 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2094 hbm_old = SelectObject(hdc, hbm);
2095 ok(hbm_old != 0, "SelectObject failed\n");
2096 hbm_old = SelectObject(hdc, hbm_old);
2097 ok(hbm_old == hbm, "SelectObject failed\n");
2101 /* test an 1-bpp bitmap */
2102 planes = GetDeviceCaps(hdc, PLANES);
2105 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
2106 ok(hbm != 0, "CreateBitmap failed\n");
2108 hbm_old = SelectObject(hdc, hbm);
2109 ok(hbm_old != 0, "SelectObject failed\n");
2110 hbm_old = SelectObject(hdc, hbm_old);
2111 ok(hbm_old == hbm, "SelectObject failed\n");
2115 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
2116 /* test a color bitmap to dc bpp matching */
2117 planes = GetDeviceCaps(hdc, PLANES);
2118 bpp = GetDeviceCaps(hdc, BITSPIXEL);
2120 hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
2121 ok(hbm != 0, "CreateBitmap failed\n");
2123 hbm_old = SelectObject(hdc, hbm);
2124 if(depths[i] == bpp ||
2125 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
2127 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
2128 SelectObject(hdc, hbm_old);
2130 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
2133 memset(&bm, 0xAA, sizeof(bm));
2134 bytes = GetObject(hbm, sizeof(bm), &bm);
2135 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2136 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2137 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
2138 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
2139 ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2140 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
2141 if(depths[i] == 15) {
2142 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
2144 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2146 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2154 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
2159 ret = GetObjectType(hbmp);
2160 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
2162 ret = GetObject(hbmp, 0, 0);
2163 ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
2165 memset(&bm, 0xDA, sizeof(bm));
2166 SetLastError(0xdeadbeef);
2167 ret = GetObject(hbmp, sizeof(bm), &bm);
2168 if (!ret) /* XP, only for curObj2 */ return;
2169 ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
2170 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2171 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2172 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2173 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2174 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2175 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2176 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2179 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2181 static void test_CreateBitmap(void)
2184 HDC screenDC = GetDC(0);
2185 HDC hdc = CreateCompatibleDC(screenDC);
2188 /* all of these are the stock monochrome bitmap */
2189 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2190 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2191 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2192 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2193 HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2194 HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2196 /* these 2 are not the stock monochrome bitmap */
2197 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2198 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2200 HBITMAP old1 = SelectObject(hdc, bm2);
2201 HBITMAP old2 = SelectObject(screenDC, bm3);
2202 SelectObject(hdc, old1);
2203 SelectObject(screenDC, old2);
2205 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2206 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2207 bm, bm1, bm4, bm5, curObj1, old1);
2208 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2210 ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
2211 ok(old2 == 0, "old2 %p\n", old2);
2213 test_mono_1x1_bmp(bm);
2214 test_mono_1x1_bmp(bm1);
2215 test_mono_1x1_bmp(bm2);
2216 test_mono_1x1_bmp(bm3);
2217 test_mono_1x1_bmp(bm4);
2218 test_mono_1x1_bmp(bm5);
2219 test_mono_1x1_bmp(old1);
2220 test_mono_1x1_bmp(curObj1);
2230 ReleaseDC(0, screenDC);
2232 /* show that Windows ignores the provided bm.bmWidthBytes */
2236 bmp.bmWidthBytes = 28;
2238 bmp.bmBitsPixel = 1;
2240 bm = CreateBitmapIndirect(&bmp);
2241 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2242 test_mono_1x1_bmp(bm);
2245 /* Test how the bmBitsPixel field is treated */
2246 for(i = 1; i <= 33; i++) {
2250 bmp.bmWidthBytes = 28;
2252 bmp.bmBitsPixel = i;
2254 SetLastError(0xdeadbeef);
2255 bm = CreateBitmapIndirect(&bmp);
2257 DWORD error = GetLastError();
2258 ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
2259 ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2263 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2264 GetObject(bm, sizeof(bmp), &bmp);
2271 } else if(i <= 16) {
2273 } else if(i <= 24) {
2275 } else if(i <= 32) {
2278 ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2279 i, bmp.bmBitsPixel, expect);
2284 static void test_bitmapinfoheadersize(void)
2291 memset(&bmi, 0, sizeof(BITMAPINFO));
2292 bmi.bmiHeader.biHeight = 100;
2293 bmi.bmiHeader.biWidth = 512;
2294 bmi.bmiHeader.biBitCount = 24;
2295 bmi.bmiHeader.biPlanes = 1;
2297 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2299 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2300 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2302 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2304 SetLastError(0xdeadbeef);
2305 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2306 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2309 bmi.bmiHeader.biSize++;
2311 SetLastError(0xdeadbeef);
2312 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2314 broken(!hdib), /* Win98, WinMe */
2315 "CreateDIBSection error %d\n", GetLastError());
2318 bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2320 SetLastError(0xdeadbeef);
2321 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2323 broken(!hdib), /* Win98, WinMe */
2324 "CreateDIBSection error %d\n", GetLastError());
2327 bmi.bmiHeader.biSize++;
2329 SetLastError(0xdeadbeef);
2330 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2332 broken(!hdib), /* Win98, WinMe */
2333 "CreateDIBSection error %d\n", GetLastError());
2336 bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2338 SetLastError(0xdeadbeef);
2339 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2340 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2343 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2345 SetLastError(0xdeadbeef);
2346 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2348 broken(!hdib), /* Win95 */
2349 "CreateDIBSection error %d\n", GetLastError());
2352 memset(&bci, 0, sizeof(BITMAPCOREINFO));
2353 bci.bmciHeader.bcHeight = 100;
2354 bci.bmciHeader.bcWidth = 512;
2355 bci.bmciHeader.bcBitCount = 24;
2356 bci.bmciHeader.bcPlanes = 1;
2358 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2360 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2361 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2363 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2365 SetLastError(0xdeadbeef);
2366 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2367 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2370 bci.bmciHeader.bcSize++;
2372 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2373 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2375 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2377 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2378 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2383 static void test_get16dibits(void)
2385 BYTE bits[4 * (16 / sizeof(BYTE))];
2387 HDC screen_dc = GetDC(NULL);
2390 int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2392 int overwritten_bytes = 0;
2394 memset(bits, 0, sizeof(bits));
2395 hbmp = CreateBitmap(2, 2, 1, 16, bits);
2396 ok(hbmp != NULL, "CreateBitmap failed\n");
2398 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2401 memset(info, '!', info_len);
2402 memset(info, 0, sizeof(info->bmiHeader));
2404 info->bmiHeader.biSize = sizeof(info->bmiHeader);
2405 info->bmiHeader.biWidth = 2;
2406 info->bmiHeader.biHeight = 2;
2407 info->bmiHeader.biPlanes = 1;
2408 info->bmiHeader.biCompression = BI_RGB;
2410 ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2411 ok(ret != 0, "GetDIBits failed got %d\n", ret);
2413 for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2415 overwritten_bytes++;
2416 ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2418 HeapFree(GetProcessHeap(), 0, info);
2420 ReleaseDC(NULL, screen_dc);
2423 static BOOL compare_buffers_no_alpha(UINT32 *a, UINT32 *b, int length)
2426 for(i = 0; i < length; i++)
2427 if((a[i] & 0x00FFFFFF) != (b[i] & 0x00FFFFFF))
2432 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2433 DWORD dwRop, UINT32 expected, int line)
2435 *srcBuffer = 0xFEDCBA98;
2436 *dstBuffer = 0x89ABCDEF;
2437 Rectangle(hdcSrc, 0, 0, 1, 1); /* A null operation to ensure dibs are coerced to X11 */
2438 BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
2439 ok(expected == *dstBuffer,
2440 "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2441 dwRop, expected, *dstBuffer, line);
2444 static void test_BitBlt(void)
2446 HBITMAP bmpDst, bmpSrc;
2447 HBITMAP oldDst, oldSrc;
2448 HDC hdcScreen, hdcDst, hdcSrc;
2449 UINT32 *dstBuffer, *srcBuffer;
2450 HBRUSH hBrush, hOldBrush;
2451 BITMAPINFO bitmapInfo;
2453 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2454 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2455 bitmapInfo.bmiHeader.biWidth = 1;
2456 bitmapInfo.bmiHeader.biHeight = 1;
2457 bitmapInfo.bmiHeader.biPlanes = 1;
2458 bitmapInfo.bmiHeader.biBitCount = 32;
2459 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2460 bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2462 hdcScreen = CreateCompatibleDC(0);
2463 hdcDst = CreateCompatibleDC(hdcScreen);
2464 hdcSrc = CreateCompatibleDC(hdcDst);
2466 /* Setup the destination dib section */
2467 bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
2469 oldDst = SelectObject(hdcDst, bmpDst);
2471 hBrush = CreateSolidBrush(0x012345678);
2472 hOldBrush = SelectObject(hdcDst, hBrush);
2474 /* Setup the source dib section */
2475 bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
2477 oldSrc = SelectObject(hdcSrc, bmpSrc);
2479 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2480 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2481 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2482 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2483 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2484 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2485 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2486 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2487 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2488 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2489 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2490 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2491 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2492 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2493 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2496 SelectObject(hdcSrc, oldSrc);
2497 DeleteObject(bmpSrc);
2500 SelectObject(hdcDst, hOldBrush);
2501 DeleteObject(hBrush);
2502 SelectObject(hdcDst, oldDst);
2503 DeleteObject(bmpDst);
2507 DeleteDC(hdcScreen);
2510 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2511 DWORD dwRop, UINT32 expected, int line)
2513 *srcBuffer = 0xFEDCBA98;
2514 *dstBuffer = 0x89ABCDEF;
2515 StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
2516 ok(expected == *dstBuffer,
2517 "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2518 dwRop, expected, *dstBuffer, line);
2521 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2522 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2523 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2524 UINT32 expected[4], UINT32 legacy_expected[4], int line)
2526 memset(dstBuffer, 0, 16);
2527 StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2528 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
2529 ok(memcmp(dstBuffer, expected, 16) == 0 ||
2530 broken(compare_buffers_no_alpha(dstBuffer, legacy_expected, 4)),
2531 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2532 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2533 expected[0], expected[1], expected[2], expected[3],
2534 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2535 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2536 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2539 static void test_StretchBlt(void)
2541 HBITMAP bmpDst, bmpSrc;
2542 HBITMAP oldDst, oldSrc;
2543 HDC hdcScreen, hdcDst, hdcSrc;
2544 UINT32 *dstBuffer, *srcBuffer;
2545 HBRUSH hBrush, hOldBrush;
2546 BITMAPINFO biDst, biSrc;
2547 UINT32 expected[4], legacy_expected[4];
2549 memset(&biDst, 0, sizeof(BITMAPINFO));
2550 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2551 biDst.bmiHeader.biWidth = 2;
2552 biDst.bmiHeader.biHeight = -2;
2553 biDst.bmiHeader.biPlanes = 1;
2554 biDst.bmiHeader.biBitCount = 32;
2555 biDst.bmiHeader.biCompression = BI_RGB;
2556 memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
2558 hdcScreen = CreateCompatibleDC(0);
2559 hdcDst = CreateCompatibleDC(hdcScreen);
2560 hdcSrc = CreateCompatibleDC(hdcDst);
2563 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2565 oldDst = SelectObject(hdcDst, bmpDst);
2567 bmpSrc = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&srcBuffer,
2569 oldSrc = SelectObject(hdcSrc, bmpSrc);
2571 hBrush = CreateSolidBrush(0x012345678);
2572 hOldBrush = SelectObject(hdcDst, hBrush);
2574 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2575 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2576 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2577 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2578 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2579 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2580 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2581 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2582 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2583 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2584 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2585 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2586 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2587 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2588 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2590 SelectObject(hdcDst, hOldBrush);
2591 DeleteObject(hBrush);
2593 /* Top-down to top-down tests */
2594 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2595 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
2597 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2598 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2599 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2600 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2602 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2603 expected[2] = 0x00000000, expected[3] = 0x00000000;
2604 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2605 0, 0, 1, 1, 0, 0, 1, 1, expected, expected, __LINE__);
2607 expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
2608 expected[2] = 0xCAFED00D, expected[3] = 0xCAFED00D;
2609 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2610 0, 0, 2, 2, 0, 0, 1, 1, expected, expected, __LINE__);
2612 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2613 expected[2] = 0x00000000, expected[3] = 0x00000000;
2614 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2615 0, 0, 1, 1, 0, 0, 2, 2, expected, expected, __LINE__);
2617 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2618 expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2619 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2620 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2622 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2623 expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2624 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2625 1, 1, -2, -2, 0, 0, 2, 2, expected, expected, __LINE__);
2627 /* This result seems broken. One might expect the following result:
2628 * 0xCAFED00D 0xFEEDFACE
2629 * 0xFEDCBA98 0x76543210
2631 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2632 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2633 legacy_expected[0] = 0xCAFED00D, legacy_expected[1] = 0x00000000;
2634 legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
2635 todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2636 1, 1, -2, -2, 1, 1, -2, -2, expected,
2637 legacy_expected, __LINE__);
2639 expected[0] = 0x00000000, expected[1] = 0x00000000;
2640 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
2641 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2642 1, 1, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2644 SelectObject(hdcDst, oldDst);
2645 DeleteObject(bmpDst);
2647 /* Top-down to bottom-up tests */
2648 biDst.bmiHeader.biHeight = 2;
2649 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2651 oldDst = SelectObject(hdcDst, bmpDst);
2653 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2654 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
2655 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2656 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2658 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2659 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2660 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2661 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2663 SelectObject(hdcSrc, oldSrc);
2664 DeleteObject(bmpSrc);
2666 /* Bottom-up to bottom-up tests */
2667 biSrc.bmiHeader.biHeight = 2;
2668 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2670 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2671 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
2672 oldSrc = SelectObject(hdcSrc, bmpSrc);
2674 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2675 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2676 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2677 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2679 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2680 expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2681 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2682 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2684 SelectObject(hdcDst, oldDst);
2685 DeleteObject(bmpDst);
2687 /* Bottom-up to top-down tests */
2688 biDst.bmiHeader.biHeight = -2;
2689 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2691 oldDst = SelectObject(hdcDst, bmpDst);
2693 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2694 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
2695 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2696 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2698 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2699 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2700 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2701 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2704 SelectObject(hdcSrc, oldSrc);
2705 DeleteObject(bmpSrc);
2708 SelectObject(hdcDst, oldDst);
2709 DeleteObject(bmpDst);
2712 DeleteDC(hdcScreen);
2715 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
2716 DWORD dwRop, UINT32 expected, int line)
2718 const UINT32 buffer[2] = { 0xFEDCBA98, 0 };
2719 BITMAPINFO bitmapInfo;
2721 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2722 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2723 bitmapInfo.bmiHeader.biWidth = 2;
2724 bitmapInfo.bmiHeader.biHeight = 1;
2725 bitmapInfo.bmiHeader.biPlanes = 1;
2726 bitmapInfo.bmiHeader.biBitCount = 32;
2727 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2728 bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer);
2730 *dstBuffer = 0x89ABCDEF;
2732 StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop);
2733 ok(expected == *dstBuffer,
2734 "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2735 dwRop, expected, *dstBuffer, line);
2738 static void check_StretchDIBits_stretch(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
2739 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2740 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2741 UINT32 expected[4], UINT32 legacy_expected[4], int line)
2743 BITMAPINFO bitmapInfo;
2745 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2746 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2747 bitmapInfo.bmiHeader.biWidth = 2;
2748 bitmapInfo.bmiHeader.biHeight = -2;
2749 bitmapInfo.bmiHeader.biPlanes = 1;
2750 bitmapInfo.bmiHeader.biBitCount = 32;
2751 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2753 memset(dstBuffer, 0, 16);
2754 StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2755 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2756 srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
2757 ok(memcmp(dstBuffer, expected, 16) == 0,
2758 "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2759 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2760 expected[0], expected[1], expected[2], expected[3],
2761 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2762 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2763 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2766 static void test_StretchDIBits(void)
2770 HDC hdcScreen, hdcDst;
2771 UINT32 *dstBuffer, srcBuffer[4];
2772 HBRUSH hBrush, hOldBrush;
2774 UINT32 expected[4], legacy_expected[4];
2776 memset(&biDst, 0, sizeof(BITMAPINFO));
2777 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2778 biDst.bmiHeader.biWidth = 2;
2779 biDst.bmiHeader.biHeight = -2;
2780 biDst.bmiHeader.biPlanes = 1;
2781 biDst.bmiHeader.biBitCount = 32;
2782 biDst.bmiHeader.biCompression = BI_RGB;
2784 hdcScreen = CreateCompatibleDC(0);
2785 hdcDst = CreateCompatibleDC(hdcScreen);
2788 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2790 oldDst = SelectObject(hdcDst, bmpDst);
2792 hBrush = CreateSolidBrush(0x012345678);
2793 hOldBrush = SelectObject(hdcDst, hBrush);
2795 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2796 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2797 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2798 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2799 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2800 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2801 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2802 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2803 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2804 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2805 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2806 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2807 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2808 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2809 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2811 SelectObject(hdcDst, hOldBrush);
2812 DeleteObject(hBrush);
2814 /* Top-down destination tests */
2815 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2816 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
2818 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2819 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2820 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2821 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2823 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2824 expected[2] = 0x00000000, expected[3] = 0x00000000;
2825 legacy_expected[0] = 0xFEDCBA98, legacy_expected[1] = 0x00000000;
2826 legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
2827 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2828 0, 0, 1, 1, 0, 0, 1, 1, expected, legacy_expected, __LINE__);
2830 expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
2831 expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
2832 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2833 0, 0, 2, 2, 0, 0, 1, 1, expected, expected, __LINE__);
2835 expected[0] = 0x42441000, expected[1] = 0x00000000;
2836 expected[2] = 0x00000000, expected[3] = 0x00000000;
2837 legacy_expected[0] = 0x00543210, legacy_expected[1] = 0x00000000;
2838 legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
2839 todo_wine check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2840 0, 0, 1, 1, 0, 0, 2, 2, expected, legacy_expected, __LINE__);
2842 expected[0] = 0x00000000, expected[1] = 0x00000000;
2843 expected[2] = 0x00000000, expected[3] = 0x00000000;
2844 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2845 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2847 expected[0] = 0x00000000, expected[1] = 0x00000000;
2848 expected[2] = 0x00000000, expected[3] = 0x00000000;
2849 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2850 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2852 expected[0] = 0x00000000, expected[1] = 0x00000000;
2853 expected[2] = 0x00000000, expected[3] = 0x00000000;
2854 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2855 1, 1, -2, -2, 1, 1, -2, -2, expected, expected, __LINE__);
2857 expected[0] = 0x00000000, expected[1] = 0x00000000;
2858 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
2859 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2860 1, 1, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2862 SelectObject(hdcDst, oldDst);
2863 DeleteObject(bmpDst);
2865 /* Bottom up destination tests */
2866 biDst.bmiHeader.biHeight = 2;
2867 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2869 oldDst = SelectObject(hdcDst, bmpDst);
2871 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2872 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
2873 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2874 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2877 SelectObject(hdcDst, oldDst);
2878 DeleteObject(bmpDst);
2881 DeleteDC(hdcScreen);
2884 static void test_GdiAlphaBlend(void)
2886 /* test out-of-bound parameters for GdiAlphaBlend */
2899 BLENDFUNCTION blend;
2901 if (!pGdiAlphaBlend)
2903 win_skip("GdiAlphaBlend() is not implemented\n");
2907 hdcNull = GetDC(NULL);
2908 hdcDst = CreateCompatibleDC(hdcNull);
2909 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
2910 hdcSrc = CreateCompatibleDC(hdcNull);
2912 memset(&bmi, 0, sizeof(bmi)); /* as of Wine 0.9.44 we require the src to be a DIB section */
2913 bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
2914 bmi.bmiHeader.biHeight = 20;
2915 bmi.bmiHeader.biWidth = 20;
2916 bmi.bmiHeader.biBitCount = 32;
2917 bmi.bmiHeader.biPlanes = 1;
2918 bmi.bmiHeader.biCompression = BI_RGB;
2919 bmpSrc = CreateDIBSection(hdcDst, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
2920 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
2922 oldDst = SelectObject(hdcDst, bmpDst);
2923 oldSrc = SelectObject(hdcSrc, bmpSrc);
2925 blend.BlendOp = AC_SRC_OVER;
2926 blend.BlendFlags = 0;
2927 blend.SourceConstantAlpha = 128;
2928 blend.AlphaFormat = 0;
2930 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend), TRUE, BOOL, "%d");
2931 SetLastError(0xdeadbeef);
2932 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), FALSE, BOOL, "%d");
2933 expect_eq(GetLastError(), ERROR_INVALID_PARAMETER, int, "%d");
2934 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), FALSE, BOOL, "%d");
2935 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend), FALSE, BOOL, "%d");
2936 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
2937 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
2939 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
2940 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), TRUE, BOOL, "%d");
2941 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), TRUE, BOOL, "%d");
2942 SetMapMode(hdcSrc, MM_ANISOTROPIC);
2943 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
2944 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend), TRUE, BOOL, "%d");
2945 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend), TRUE, BOOL, "%d");
2947 SetLastError(0xdeadbeef);
2948 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend), FALSE, BOOL, "%d");
2949 expect_eq(GetLastError(), 0xdeadbeef, int, "%d");
2951 SelectObject(hdcDst, oldDst);
2952 SelectObject(hdcSrc, oldSrc);
2953 DeleteObject(bmpSrc);
2954 DeleteObject(bmpDst);
2958 ReleaseDC(NULL, hdcNull);
2962 static void test_clipping(void)
2970 HDC hdcDst = CreateCompatibleDC( NULL );
2971 HDC hdcSrc = CreateCompatibleDC( NULL );
2973 BITMAPINFO bmpinfo={{0}};
2974 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2975 bmpinfo.bmiHeader.biWidth = 100;
2976 bmpinfo.bmiHeader.biHeight = 100;
2977 bmpinfo.bmiHeader.biPlanes = 1;
2978 bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
2979 bmpinfo.bmiHeader.biCompression = BI_RGB;
2981 bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
2982 ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
2983 SelectObject( hdcDst, bmpDst );
2985 bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
2986 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
2987 SelectObject( hdcSrc, bmpSrc );
2989 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
2990 ok(result, "BitBlt failed\n");
2992 hRgn = CreateRectRgn( 0,0,0,0 );
2993 SelectClipRgn( hdcDst, hRgn );
2995 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
2996 ok(result, "BitBlt failed\n");
2998 DeleteObject( bmpDst );
2999 DeleteObject( bmpSrc );
3000 DeleteObject( hRgn );
3005 static void test_32bit_bitmap_blt(void)
3008 HBITMAP bmpSrc, bmpDst;
3009 HBITMAP oldSrc, oldDst;
3010 HDC hdcSrc, hdcDst, hdcScreen;
3012 DWORD colorSrc = 0x11223344;
3014 memset(&biDst, 0, sizeof(BITMAPINFO));
3015 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3016 biDst.bmiHeader.biWidth = 2;
3017 biDst.bmiHeader.biHeight = -2;
3018 biDst.bmiHeader.biPlanes = 1;
3019 biDst.bmiHeader.biBitCount = 32;
3020 biDst.bmiHeader.biCompression = BI_RGB;
3022 hdcScreen = CreateCompatibleDC(0);
3023 if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3025 DeleteDC(hdcScreen);
3026 trace("Skipping 32-bit DDB test\n");
3030 hdcSrc = CreateCompatibleDC(hdcScreen);
3031 bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3032 oldSrc = SelectObject(hdcSrc, bmpSrc);
3034 hdcDst = CreateCompatibleDC(hdcScreen);
3035 bmpDst = CreateDIBSection(hdcDst, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3036 oldDst = SelectObject(hdcDst, bmpDst);
3038 StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3039 ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3042 SelectObject(hdcDst, oldDst);
3043 DeleteObject(bmpDst);
3046 SelectObject(hdcSrc, oldSrc);
3047 DeleteObject(bmpSrc);
3050 DeleteDC(hdcScreen);
3054 * Used by test_GetDIBits_top_down to create the bitmap to test against.
3056 static void setup_picture(char *picture, int bpp)
3064 /*Set the first byte in each pixel to the index of that pixel.*/
3065 for (i = 0; i < 4; i++)
3066 picture[i * (bpp / 8)] = i;
3071 /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
3078 static void test_GetDIBits_top_down(int bpp)
3081 HBITMAP bmptb, bmpbt;
3087 bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
3088 bi.bmiHeader.biWidth=2;
3089 bi.bmiHeader.biHeight=2;
3090 bi.bmiHeader.biPlanes=1;
3091 bi.bmiHeader.biBitCount=bpp;
3092 bi.bmiHeader.biCompression=BI_RGB;
3094 /*Get the device context for the screen.*/
3096 ok(hdc != NULL, "Could not get a handle to a device context.\n");
3098 /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
3099 bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3100 ok(bmpbt != NULL, "Could not create a DIB section.\n");
3101 /*Now that we have a pointer to the pixels, we write to them.*/
3102 setup_picture((char*)picture, bpp);
3103 /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
3104 bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
3105 bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3106 ok(bmptb != NULL, "Could not create a DIB section.\n");
3107 /*Write to this top to bottom bitmap.*/
3108 setup_picture((char*)picture, bpp);
3110 bi.bmiHeader.biWidth = 1;
3112 bi.bmiHeader.biHeight = 2;
3113 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3114 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3115 /*Check the first byte of the pixel.*/
3116 ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3117 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3118 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3119 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3120 /*Check second scanline.*/
3121 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3122 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3123 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3124 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3125 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3126 ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3127 /*Check both scanlines.*/
3128 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3129 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3130 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3131 ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3132 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3133 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3134 ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3135 ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3137 /*Make destination bitmap top-down.*/
3138 bi.bmiHeader.biHeight = -2;
3139 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3140 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3141 ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3142 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3143 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3144 ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3145 /*Check second scanline.*/
3146 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3147 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3148 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3149 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3150 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3151 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3152 /*Check both scanlines.*/
3153 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3154 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3155 ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3156 ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3157 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3158 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3159 ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3160 ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3162 DeleteObject(bmpbt);
3163 DeleteObject(bmptb);
3166 static void test_GetSetDIBits_rtl(void)
3169 HBITMAP bitmap, orig_bitmap;
3172 DWORD bits_1[8 * 8], bits_2[8 * 8];
3176 win_skip("Don't have SetLayout\n");
3180 hdc = GetDC( NULL );
3181 hdc_mem = CreateCompatibleDC( hdc );
3182 pSetLayout( hdc_mem, LAYOUT_LTR );
3184 bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
3185 orig_bitmap = SelectObject( hdc_mem, bitmap );
3186 SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
3187 SelectObject( hdc_mem, orig_bitmap );
3189 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3190 info.bmiHeader.biWidth = 8;
3191 info.bmiHeader.biHeight = 8;
3192 info.bmiHeader.biPlanes = 1;
3193 info.bmiHeader.biBitCount = 32;
3194 info.bmiHeader.biCompression = BI_RGB;
3196 /* First show that GetDIBits ignores the layout mode. */
3198 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3199 ok(ret == 8, "got %d\n", ret);
3200 ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
3202 pSetLayout( hdc_mem, LAYOUT_RTL );
3204 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3205 ok(ret == 8, "got %d\n", ret);
3207 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3209 /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
3210 followed by a GetDIBits and show that the bits remain unchanged. */
3212 pSetLayout( hdc_mem, LAYOUT_LTR );
3214 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3215 ok(ret == 8, "got %d\n", ret);
3216 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3217 ok(ret == 8, "got %d\n", ret);
3218 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3220 pSetLayout( hdc_mem, LAYOUT_RTL );
3222 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3223 ok(ret == 8, "got %d\n", ret);
3224 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3225 ok(ret == 8, "got %d\n", ret);
3226 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3228 DeleteObject( bitmap );
3229 DeleteDC( hdc_mem );
3230 ReleaseDC( NULL, hdc );
3233 static void test_GetDIBits_scanlines(void)
3235 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3236 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3238 HDC hdc = GetDC( NULL );
3240 DWORD data[128], inverted_bits[64];
3243 memset( info, 0, sizeof(bmi_buf) );
3245 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3246 info->bmiHeader.biWidth = 8;
3247 info->bmiHeader.biHeight = 8;
3248 info->bmiHeader.biPlanes = 1;
3249 info->bmiHeader.biBitCount = 32;
3250 info->bmiHeader.biCompression = BI_RGB;
3252 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3254 for (i = 0; i < 64; i++)
3257 inverted_bits[56 - (i & ~7) + (i & 7)] = i;
3262 memset( data, 0xaa, sizeof(data) );
3264 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3265 ok( ret == 8, "got %d\n", ret );
3266 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3267 memset( data, 0xaa, sizeof(data) );
3269 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3270 ok( ret == 5, "got %d\n", ret );
3271 ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
3272 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3273 memset( data, 0xaa, sizeof(data) );
3275 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3276 ok( ret == 7, "got %d\n", ret );
3277 ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
3278 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3279 memset( data, 0xaa, sizeof(data) );
3281 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3282 ok( ret == 1, "got %d\n", ret );
3283 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3284 memset( data, 0xaa, sizeof(data) );
3286 info->bmiHeader.biHeight = 16;
3287 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3288 ok( ret == 5, "got %d\n", ret );
3289 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3290 ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
3291 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3292 memset( data, 0xaa, sizeof(data) );
3294 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3295 ok( ret == 6, "got %d\n", ret );
3296 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3297 ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
3298 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3299 memset( data, 0xaa, sizeof(data) );
3301 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3302 ok( ret == 0, "got %d\n", ret );
3303 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3304 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3305 memset( data, 0xaa, sizeof(data) );
3307 info->bmiHeader.biHeight = 5;
3308 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3309 ok( ret == 2, "got %d\n", ret );
3310 ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
3311 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3312 memset( data, 0xaa, sizeof(data) );
3316 info->bmiHeader.biHeight = -8;
3317 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3318 ok( ret == 8, "got %d\n", ret );
3319 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3320 memset( data, 0xaa, sizeof(data) );
3322 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3323 ok( ret == 5, "got %d\n", ret );
3324 ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
3325 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3326 memset( data, 0xaa, sizeof(data) );
3328 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3329 ok( ret == 7, "got %d\n", ret );
3330 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3331 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3332 memset( data, 0xaa, sizeof(data) );
3334 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3335 ok( ret == 4, "got %d\n", ret );
3336 ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
3337 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3338 memset( data, 0xaa, sizeof(data) );
3340 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3341 ok( ret == 5, "got %d\n", ret );
3342 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3343 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3344 memset( data, 0xaa, sizeof(data) );
3346 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3347 ok( ret == 5, "got %d\n", ret );
3348 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3349 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3350 memset( data, 0xaa, sizeof(data) );
3352 info->bmiHeader.biHeight = -16;
3353 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3354 ok( ret == 8, "got %d\n", ret );
3355 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3356 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3357 memset( data, 0xaa, sizeof(data) );
3359 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3360 ok( ret == 5, "got %d\n", ret );
3361 ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
3362 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3363 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3364 memset( data, 0xaa, sizeof(data) );
3366 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3367 ok( ret == 8, "got %d\n", ret );
3368 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3369 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3370 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3371 memset( data, 0xaa, sizeof(data) );
3373 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3374 ok( ret == 8, "got %d\n", ret );
3375 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3376 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3377 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3378 memset( data, 0xaa, sizeof(data) );
3380 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3381 ok( ret == 7, "got %d\n", ret );
3382 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3383 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3384 memset( data, 0xaa, sizeof(data) );
3386 ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
3387 ok( ret == 1, "got %d\n", ret );
3388 for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3389 memset( data, 0xaa, sizeof(data) );
3391 info->bmiHeader.biHeight = -5;
3392 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3393 ok( ret == 2, "got %d\n", ret );
3394 ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
3395 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3396 memset( data, 0xaa, sizeof(data) );
3398 DeleteObject( dib );
3400 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3401 info->bmiHeader.biWidth = 8;
3402 info->bmiHeader.biHeight = -8;
3403 info->bmiHeader.biPlanes = 1;
3404 info->bmiHeader.biBitCount = 32;
3405 info->bmiHeader.biCompression = BI_RGB;
3407 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3409 for (i = 0; i < 64; i++) dib_bits[i] = i;
3413 info->bmiHeader.biHeight = -8;
3414 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3415 ok( ret == 8, "got %d\n", ret );
3416 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3417 memset( data, 0xaa, sizeof(data) );
3419 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3420 ok( ret == 5, "got %d\n", ret );
3421 ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
3422 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3423 memset( data, 0xaa, sizeof(data) );
3425 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3426 ok( ret == 7, "got %d\n", ret );
3427 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3428 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3429 memset( data, 0xaa, sizeof(data) );
3431 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3432 ok( ret == 4, "got %d\n", ret );
3433 ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
3434 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3435 memset( data, 0xaa, sizeof(data) );
3437 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3438 ok( ret == 5, "got %d\n", ret );
3439 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3440 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3441 memset( data, 0xaa, sizeof(data) );
3443 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3444 ok( ret == 5, "got %d\n", ret );
3445 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3446 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3447 memset( data, 0xaa, sizeof(data) );
3449 info->bmiHeader.biHeight = -16;
3450 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3451 ok( ret == 8, "got %d\n", ret );
3452 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3453 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3454 memset( data, 0xaa, sizeof(data) );
3456 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3457 ok( ret == 5, "got %d\n", ret );
3458 ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
3459 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3460 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3461 memset( data, 0xaa, sizeof(data) );
3463 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3464 ok( ret == 8, "got %d\n", ret );
3465 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3466 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3467 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3468 memset( data, 0xaa, sizeof(data) );
3470 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3471 ok( ret == 8, "got %d\n", ret );
3472 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3473 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3474 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3475 memset( data, 0xaa, sizeof(data) );
3477 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3478 ok( ret == 7, "got %d\n", ret );
3479 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3480 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3481 memset( data, 0xaa, sizeof(data) );
3483 info->bmiHeader.biHeight = -5;
3484 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3485 ok( ret == 2, "got %d\n", ret );
3486 ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
3487 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3488 memset( data, 0xaa, sizeof(data) );
3493 info->bmiHeader.biHeight = 8;
3495 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3496 ok( ret == 8, "got %d\n", ret );
3497 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3498 memset( data, 0xaa, sizeof(data) );
3500 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3501 ok( ret == 5, "got %d\n", ret );
3502 ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
3503 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3504 memset( data, 0xaa, sizeof(data) );
3506 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3507 ok( ret == 7, "got %d\n", ret );
3508 ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
3509 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3510 memset( data, 0xaa, sizeof(data) );
3512 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3513 ok( ret == 1, "got %d\n", ret );
3514 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3515 memset( data, 0xaa, sizeof(data) );
3517 info->bmiHeader.biHeight = 16;
3518 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3519 ok( ret == 5, "got %d\n", ret );
3520 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3521 ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
3522 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3523 memset( data, 0xaa, sizeof(data) );
3525 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3526 ok( ret == 6, "got %d\n", ret );
3527 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3528 ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
3529 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3530 memset( data, 0xaa, sizeof(data) );
3532 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3533 ok( ret == 0, "got %d\n", ret );
3534 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3535 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3536 memset( data, 0xaa, sizeof(data) );
3538 info->bmiHeader.biHeight = 5;
3539 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3540 ok( ret == 2, "got %d\n", ret );
3541 ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
3542 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3543 memset( data, 0xaa, sizeof(data) );
3545 DeleteObject( dib );
3547 ReleaseDC( NULL, hdc );
3551 static void test_SetDIBits(void)
3553 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3554 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3556 HDC hdc = GetDC( NULL );
3557 DWORD data[128], inverted_data[128];
3561 memset( info, 0, sizeof(bmi_buf) );
3563 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3564 info->bmiHeader.biWidth = 8;
3565 info->bmiHeader.biHeight = 8;
3566 info->bmiHeader.biPlanes = 1;
3567 info->bmiHeader.biBitCount = 32;
3568 info->bmiHeader.biCompression = BI_RGB;
3570 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3571 memset( dib_bits, 0xaa, 64 * 4 );
3573 for (i = 0; i < 128; i++)
3576 inverted_data[120 - (i & ~7) + (i & 7)] = i;
3581 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3582 ok( ret == 8, "got %d\n", ret );
3583 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
3584 memset( dib_bits, 0xaa, 64 * 4 );
3586 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3587 ok( ret == 5, "got %d\n", ret );
3588 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3589 ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
3590 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3591 memset( dib_bits, 0xaa, 64 * 4 );
3593 /* top of dst is aligned with startscans down for the top of the src.
3594 Then starting from the bottom of src, lines rows are copied across. */
3596 info->bmiHeader.biHeight = 16;
3597 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3598 ok( ret == 12, "got %d\n", ret );
3599 ok( !memcmp( dib_bits, data + 56, 40 * 4 ), "bits differ\n");
3600 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3601 memset( dib_bits, 0xaa, 64 * 4 );
3603 info->bmiHeader.biHeight = 5;
3604 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3605 ok( ret == 2, "got %d\n", ret );
3606 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3607 ok( !memcmp( dib_bits + 32, data, 16 * 4 ), "bits differ\n");
3608 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3609 memset( dib_bits, 0xaa, 64 * 4 );
3612 info->bmiHeader.biHeight = -8;
3613 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3614 ok( ret == 8, "got %d\n", ret );
3615 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3616 memset( dib_bits, 0xaa, 64 * 4 );
3618 /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
3619 we copy lines rows from the top of the src */
3621 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3622 ok( ret == 5, "got %d\n", ret );
3623 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3624 ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
3625 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3626 memset( dib_bits, 0xaa, 64 * 4 );
3628 info->bmiHeader.biHeight = -16;
3629 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3630 ok( ret == 12, "got %d\n", ret );
3631 ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
3632 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3633 memset( dib_bits, 0xaa, 64 * 4 );
3635 ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3636 ok( ret == 12, "got %d\n", ret );
3637 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3638 memset( dib_bits, 0xaa, 64 * 4 );
3640 ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3641 ok( ret == 12, "got %d\n", ret );
3642 ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
3643 memset( dib_bits, 0xaa, 64 * 4 );
3645 info->bmiHeader.biHeight = -5;
3646 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3647 ok( ret == 2, "got %d\n", ret );
3648 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3649 ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
3650 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3651 memset( dib_bits, 0xaa, 64 * 4 );
3653 DeleteObject( dib );
3655 info->bmiHeader.biHeight = -8;
3657 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3658 memset( dib_bits, 0xaa, 16 * 16 * 4 );
3662 /* like the t-d -> b-u case. */
3664 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3665 ok( ret == 8, "got %d\n", ret );
3666 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
3667 memset( dib_bits, 0xaa, 64 * 4 );
3669 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3670 ok( ret == 5, "got %d\n", ret );
3671 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3672 ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
3673 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3674 memset( dib_bits, 0xaa, 64 * 4 );
3676 info->bmiHeader.biHeight = -16;
3677 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3678 ok( ret == 12, "got %d\n", ret );
3679 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3680 ok( !memcmp( dib_bits + 24, data, 40 * 4 ), "bits differ\n");
3681 memset( dib_bits, 0xaa, 64 * 4 );
3683 info->bmiHeader.biHeight = -5;
3684 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3685 ok( ret == 2, "got %d\n", ret );
3686 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3687 ok( !memcmp( dib_bits + 16, data, 16 * 4 ), "bits differ\n");
3688 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3689 memset( dib_bits, 0xaa, 64 * 4 );
3692 /* like the b-u -> b-u case */
3694 info->bmiHeader.biHeight = 8;
3695 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3696 ok( ret == 8, "got %d\n", ret );
3697 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3698 memset( dib_bits, 0xaa, 64 * 4 );
3700 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3701 ok( ret == 5, "got %d\n", ret );
3702 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3703 ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
3704 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3705 memset( dib_bits, 0xaa, 64 * 4 );
3707 info->bmiHeader.biHeight = 16;
3708 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3709 ok( ret == 12, "got %d\n", ret );
3710 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3711 ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
3712 memset( dib_bits, 0xaa, 64 * 4 );
3714 info->bmiHeader.biHeight = 5;
3715 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3716 ok( ret == 2, "got %d\n", ret );
3717 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3718 ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
3719 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3720 memset( dib_bits, 0xaa, 64 * 4 );
3722 DeleteObject( dib );
3723 ReleaseDC( NULL, hdc );
3726 static void test_SetDIBits_RLE4(void)
3728 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3729 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3731 HDC hdc = GetDC( NULL );
3732 BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00, /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
3733 0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
3734 0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00, /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
3735 0x00, 0x02, 0x01, 0x02, 0x05, 0x87, /* dx=1, dy=2, 8, 7, 8, 7, 8 */
3736 0x00, 0x01 }; /* <eod> */
3739 DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
3740 0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
3741 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3742 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3743 0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
3744 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3745 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3746 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
3748 memset( info, 0, sizeof(bmi_buf) );
3750 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3751 info->bmiHeader.biWidth = 8;
3752 info->bmiHeader.biHeight = 8;
3753 info->bmiHeader.biPlanes = 1;
3754 info->bmiHeader.biBitCount = 32;
3755 info->bmiHeader.biCompression = BI_RGB;
3757 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3758 memset( dib_bits, 0xaa, 64 * 4 );
3760 info->bmiHeader.biBitCount = 4;
3761 info->bmiHeader.biCompression = BI_RLE4;
3762 info->bmiHeader.biSizeImage = sizeof(rle4_data);
3764 for (i = 0; i < 16; i++)
3766 info->bmiColors[i].rgbRed = i;
3767 info->bmiColors[i].rgbGreen = i;
3768 info->bmiColors[i].rgbBlue = i;
3769 info->bmiColors[i].rgbReserved = 0;
3772 ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
3773 ok( ret == 8, "got %d\n", ret );
3774 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
3775 memset( dib_bits, 0xaa, 64 * 4 );
3777 DeleteObject( dib );
3778 ReleaseDC( NULL, hdc );
3781 static void test_SetDIBits_RLE8(void)
3783 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3784 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3786 HDC hdc = GetDC( NULL );
3787 BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00, /* 2, 2, 2, f0, f0, f0, f0, <eol> */
3788 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
3789 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
3790 0x00, 0x01 }; /* <eod> */
3793 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
3794 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3795 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3796 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
3797 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3798 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3799 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3800 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
3801 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3802 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3803 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3804 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3805 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
3806 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3807 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3808 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
3810 memset( info, 0, sizeof(bmi_buf) );
3812 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3813 info->bmiHeader.biWidth = 8;
3814 info->bmiHeader.biHeight = 8;
3815 info->bmiHeader.biPlanes = 1;
3816 info->bmiHeader.biBitCount = 32;
3817 info->bmiHeader.biCompression = BI_RGB;
3819 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3820 memset( dib_bits, 0xaa, 64 * 4 );
3822 info->bmiHeader.biBitCount = 8;
3823 info->bmiHeader.biCompression = BI_RLE8;
3824 info->bmiHeader.biSizeImage = sizeof(rle8_data);
3826 for (i = 0; i < 256; i++)
3828 info->bmiColors[i].rgbRed = i;
3829 info->bmiColors[i].rgbGreen = i;
3830 info->bmiColors[i].rgbBlue = i;
3831 info->bmiColors[i].rgbReserved = 0;
3834 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
3835 ok( ret == 8, "got %d\n", ret );
3836 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
3837 memset( dib_bits, 0xaa, 64 * 4 );
3839 /* startscan and lines are ignored, unless lines == 0 */
3840 ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
3841 ok( ret == 8, "got %d\n", ret );
3842 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
3843 memset( dib_bits, 0xaa, 64 * 4 );
3845 ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
3846 ok( ret == 8, "got %d\n", ret );
3847 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
3848 memset( dib_bits, 0xaa, 64 * 4 );
3850 ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
3851 ok( ret == 0, "got %d\n", ret );
3852 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3853 memset( dib_bits, 0xaa, 64 * 4 );
3855 /* reduce width to 4, left-hand side of dst is touched. */
3856 info->bmiHeader.biWidth = 4;
3857 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
3858 ok( ret == 8, "got %d\n", ret );
3859 for (i = 0; i < 64; i++)
3861 DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
3862 ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
3864 memset( dib_bits, 0xaa, 64 * 4 );
3866 /* Show that the top lines are aligned by adjusting the height of the src */
3868 /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
3869 info->bmiHeader.biWidth = 8;
3870 info->bmiHeader.biHeight = 4;
3871 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
3872 ok( ret == 4, "got %d\n", ret );
3873 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3874 ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
3875 memset( dib_bits, 0xaa, 64 * 4 );
3877 /* increase the height to 9 -> everything moves down one row. */
3878 info->bmiHeader.biHeight = 9;
3879 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
3880 ok( ret == 9, "got %d\n", ret );
3881 ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
3882 for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
3883 memset( dib_bits, 0xaa, 64 * 4 );
3885 /* top-down compressed dibs are invalid */
3886 info->bmiHeader.biHeight = -8;
3887 SetLastError( 0xdeadbeef );
3888 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
3889 ok( ret == 0, "got %d\n", ret );
3890 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
3891 DeleteObject( dib );
3895 info->bmiHeader.biHeight = -8;
3896 info->bmiHeader.biBitCount = 32;
3897 info->bmiHeader.biCompression = BI_RGB;
3898 info->bmiHeader.biSizeImage = 0;
3900 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3901 memset( dib_bits, 0xaa, 16 * 16 * 4 );
3903 info->bmiHeader.biHeight = 8;
3904 info->bmiHeader.biBitCount = 8;
3905 info->bmiHeader.biCompression = BI_RLE8;
3906 info->bmiHeader.biSizeImage = sizeof(rle8_data);
3908 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
3909 ok( ret == 8, "got %d\n", ret );
3910 ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
3911 memset( dib_bits, 0xaa, 64 * 4 );
3913 info->bmiHeader.biHeight = 4;
3914 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
3915 ok( ret == 4, "got %d\n", ret );
3916 ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
3917 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3918 memset( dib_bits, 0xaa, 64 * 4 );
3920 info->bmiHeader.biHeight = 9;
3921 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
3922 ok( ret == 9, "got %d\n", ret );
3923 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3924 ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
3925 memset( dib_bits, 0xaa, 64 * 4 );
3927 DeleteObject( dib );
3929 ReleaseDC( NULL, hdc );
3936 hdll = GetModuleHandle("gdi32.dll");
3937 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
3938 pSetLayout = (void*)GetProcAddress(hdll, "SetLayout");
3940 test_createdibitmap();
3942 test_mono_dibsection();
3945 test_GetDIBits_selected_DIB(1);
3946 test_GetDIBits_selected_DIB(4);
3947 test_GetDIBits_selected_DIB(8);
3948 test_GetDIBits_selected_DDB(TRUE);
3949 test_GetDIBits_selected_DDB(FALSE);
3951 test_GetDIBits_BI_BITFIELDS();
3952 test_select_object();
3953 test_CreateBitmap();
3956 test_StretchDIBits();
3957 test_GdiAlphaBlend();
3958 test_32bit_bitmap_blt();
3959 test_bitmapinfoheadersize();
3962 test_GetDIBits_top_down(16);
3963 test_GetDIBits_top_down(24);
3964 test_GetDIBits_top_down(32);
3965 test_GetSetDIBits_rtl();
3966 test_GetDIBits_scanlines();
3968 test_SetDIBits_RLE4();
3969 test_SetDIBits_RLE8();