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 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
442 /* try writing protected bits to a file */
444 GetTempFileNameA( ".", "dib", 0, filename );
445 file = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
446 CREATE_ALWAYS, 0, 0 );
447 ok( file != INVALID_HANDLE_VALUE, "failed to open %s error %u\n", filename, GetLastError() );
448 ret = WriteFile( file, bits, 8192, &written, NULL );
449 ok( ret, "WriteFile failed error %u\n", GetLastError() );
450 if (ret) ok( written == 8192, "only wrote %u bytes\n", written );
452 DeleteFileA( filename );
455 static void test_dibsections(void)
457 HDC hdc, hdcmem, hdcmem2;
458 HBITMAP hdib, oldbm, hdib2, oldbm2;
459 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
460 char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
461 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
462 BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
468 char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
469 LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
472 HPALETTE hpal, oldpal;
477 MEMORY_BASIC_INFORMATION info;
480 screen_depth = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
482 memset(pbmi, 0, sizeof(bmibuf));
483 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
484 pbmi->bmiHeader.biHeight = 100;
485 pbmi->bmiHeader.biWidth = 512;
486 pbmi->bmiHeader.biBitCount = 24;
487 pbmi->bmiHeader.biPlanes = 1;
488 pbmi->bmiHeader.biCompression = BI_RGB;
490 SetLastError(0xdeadbeef);
492 /* invalid pointer for BITMAPINFO
493 (*bits should be NULL on error) */
494 bits = (BYTE*)0xdeadbeef;
495 hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
496 ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n");
498 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
499 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
500 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
501 ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
503 /* test the DIB memory */
504 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
505 "VirtualQuery failed\n");
506 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
507 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
508 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
509 ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
510 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
511 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
512 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
514 test_dib_bits_access( hdib, bits );
516 test_dib_info(hdib, bits, &pbmi->bmiHeader);
519 /* Test a top-down DIB. */
520 pbmi->bmiHeader.biHeight = -100;
521 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
522 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
523 test_dib_info(hdib, bits, &pbmi->bmiHeader);
526 pbmi->bmiHeader.biHeight = 100;
527 pbmi->bmiHeader.biBitCount = 8;
528 pbmi->bmiHeader.biCompression = BI_RLE8;
529 SetLastError(0xdeadbeef);
530 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
531 ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
532 ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
534 pbmi->bmiHeader.biBitCount = 16;
535 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
536 ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
537 ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
538 ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
539 SetLastError(0xdeadbeef);
540 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
541 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
543 /* test the DIB memory */
544 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
545 "VirtualQuery failed\n");
546 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
547 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
548 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
549 ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
550 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
551 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
552 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
554 test_dib_info(hdib, bits, &pbmi->bmiHeader);
557 memset(pbmi, 0, sizeof(bmibuf));
558 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
559 pbmi->bmiHeader.biHeight = 16;
560 pbmi->bmiHeader.biWidth = 16;
561 pbmi->bmiHeader.biBitCount = 1;
562 pbmi->bmiHeader.biPlanes = 1;
563 pbmi->bmiHeader.biCompression = BI_RGB;
564 pbmi->bmiColors[0].rgbRed = 0xff;
565 pbmi->bmiColors[0].rgbGreen = 0;
566 pbmi->bmiColors[0].rgbBlue = 0;
567 pbmi->bmiColors[1].rgbRed = 0;
568 pbmi->bmiColors[1].rgbGreen = 0;
569 pbmi->bmiColors[1].rgbBlue = 0xff;
571 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
572 ok(hdib != NULL, "CreateDIBSection failed\n");
573 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
574 ok(dibsec.dsBmih.biClrUsed == 2,
575 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
577 /* Test if the old BITMAPCOREINFO structure is supported */
579 pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
580 pbci->bmciHeader.bcBitCount = 0;
582 ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
583 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
584 ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
585 && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
586 "GetDIBits didn't fill in the BITMAPCOREHEADER structure properly\n");
588 ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
589 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
590 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
591 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
592 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
593 "The color table has not been translated to the old BITMAPCOREINFO format\n");
595 hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
596 ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
598 ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
599 ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
600 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
601 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
602 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
603 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
604 "The color table has not been translated to the old BITMAPCOREINFO format\n");
606 DeleteObject(hcoredib);
608 hdcmem = CreateCompatibleDC(hdc);
609 oldbm = SelectObject(hdcmem, hdib);
611 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
612 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
613 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
614 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
615 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
616 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
618 c0 = RGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen, pbmi->bmiColors[0].rgbBlue);
619 c1 = RGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen, pbmi->bmiColors[1].rgbBlue);
621 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
622 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
623 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
624 test_color(hdcmem, PALETTEINDEX(0), c0, 1, 1);
625 test_color(hdcmem, PALETTEINDEX(1), c0, 1, 1);
626 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
627 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen,
628 pbmi->bmiColors[0].rgbBlue), c0, 1, 1);
629 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen,
630 pbmi->bmiColors[1].rgbBlue), c1, 1, 1);
631 test_color(hdcmem, PALETTERGB(0, 0, 0), c0, 1, 1);
632 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
633 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1, 1, 1);
635 SelectObject(hdcmem, oldbm);
638 pbmi->bmiColors[0].rgbRed = 0xff;
639 pbmi->bmiColors[0].rgbGreen = 0xff;
640 pbmi->bmiColors[0].rgbBlue = 0xff;
641 pbmi->bmiColors[1].rgbRed = 0;
642 pbmi->bmiColors[1].rgbGreen = 0;
643 pbmi->bmiColors[1].rgbBlue = 0;
645 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
646 ok(hdib != NULL, "CreateDIBSection failed\n");
648 test_dib_info(hdib, bits, &pbmi->bmiHeader);
650 oldbm = SelectObject(hdcmem, hdib);
652 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
653 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
654 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
655 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
656 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
657 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
659 SelectObject(hdcmem, oldbm);
660 test_dib_info(hdib, bits, &pbmi->bmiHeader);
663 pbmi->bmiHeader.biBitCount = 4;
664 for (i = 0; i < 16; i++) {
665 pbmi->bmiColors[i].rgbRed = i;
666 pbmi->bmiColors[i].rgbGreen = 16-i;
667 pbmi->bmiColors[i].rgbBlue = 0;
669 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
670 ok(hdib != NULL, "CreateDIBSection failed\n");
671 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
672 ok(dibsec.dsBmih.biClrUsed == 16,
673 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
674 test_dib_info(hdib, bits, &pbmi->bmiHeader);
677 pbmi->bmiHeader.biBitCount = 8;
679 for (i = 0; i < 128; i++) {
680 pbmi->bmiColors[i].rgbRed = 255 - i * 2;
681 pbmi->bmiColors[i].rgbGreen = i * 2;
682 pbmi->bmiColors[i].rgbBlue = 0;
683 pbmi->bmiColors[255 - i].rgbRed = 0;
684 pbmi->bmiColors[255 - i].rgbGreen = i * 2;
685 pbmi->bmiColors[255 - i].rgbBlue = 255 - i * 2;
687 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
688 ok(hdib != NULL, "CreateDIBSection failed\n");
689 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
690 ok(dibsec.dsBmih.biClrUsed == 256,
691 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
693 oldbm = SelectObject(hdcmem, hdib);
695 for (i = 0; i < 256; i++) {
696 test_color(hdcmem, DIBINDEX(i),
697 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
698 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue),
699 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
702 SelectObject(hdcmem, oldbm);
703 test_dib_info(hdib, bits, &pbmi->bmiHeader);
706 pbmi->bmiHeader.biBitCount = 1;
708 /* Now create a palette and a palette indexed dib section */
709 memset(plogpal, 0, sizeof(logpalbuf));
710 plogpal->palVersion = 0x300;
711 plogpal->palNumEntries = 2;
712 plogpal->palPalEntry[0].peRed = 0xff;
713 plogpal->palPalEntry[0].peBlue = 0xff;
714 plogpal->palPalEntry[1].peGreen = 0xff;
716 index = (WORD*)pbmi->bmiColors;
719 hpal = CreatePalette(plogpal);
720 ok(hpal != NULL, "CreatePalette failed\n");
721 oldpal = SelectPalette(hdc, hpal, TRUE);
722 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
723 ok(hdib != NULL, "CreateDIBSection failed\n");
724 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
725 ok(dibsec.dsBmih.biClrUsed == 2, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
727 /* The colour table has already been grabbed from the dc, so we select back the
730 SelectPalette(hdc, oldpal, TRUE);
731 oldbm = SelectObject(hdcmem, hdib);
732 oldpal = SelectPalette(hdcmem, hpal, TRUE);
734 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
735 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
736 ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
737 rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
738 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
739 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
740 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
742 c0 = RGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen, plogpal->palPalEntry[0].peBlue);
743 c1 = RGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen, plogpal->palPalEntry[1].peBlue);
745 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
746 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
747 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
748 test_color(hdcmem, PALETTEINDEX(0), c0, 0, 1);
749 test_color(hdcmem, PALETTEINDEX(1), c1, 0, 1);
750 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
751 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen,
752 plogpal->palPalEntry[0].peBlue), c0, 1, 1);
753 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen,
754 plogpal->palPalEntry[1].peBlue), c1, 1, 1);
755 test_color(hdcmem, PALETTERGB(0, 0, 0), c1, 1, 1);
756 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
757 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0, 1, 1);
758 test_color(hdcmem, PALETTERGB(0, 1, 0), c1, 1, 1);
759 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1, 1, 1);
760 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0, 1, 1);
762 /* Bottom and 2nd row from top green, everything else magenta */
763 bits[0] = bits[1] = 0xff;
764 bits[13 * 4] = bits[13*4 + 1] = 0xff;
766 test_dib_info(hdib, bits, &pbmi->bmiHeader);
768 pbmi->bmiHeader.biBitCount = 32;
770 hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
771 ok(hdib2 != NULL, "CreateDIBSection failed\n");
772 hdcmem2 = CreateCompatibleDC(hdc);
773 oldbm2 = SelectObject(hdcmem2, hdib2);
775 BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
777 ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
778 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
780 SelectObject(hdcmem2, oldbm2);
781 test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
784 SelectObject(hdcmem, oldbm);
785 SelectPalette(hdcmem, oldpal, TRUE);
790 pbmi->bmiHeader.biBitCount = 8;
792 memset(plogpal, 0, sizeof(logpalbuf));
793 plogpal->palVersion = 0x300;
794 plogpal->palNumEntries = 256;
796 for (i = 0; i < 128; i++) {
797 plogpal->palPalEntry[i].peRed = 255 - i * 2;
798 plogpal->palPalEntry[i].peBlue = i * 2;
799 plogpal->palPalEntry[i].peGreen = 0;
800 plogpal->palPalEntry[255 - i].peRed = 0;
801 plogpal->palPalEntry[255 - i].peGreen = i * 2;
802 plogpal->palPalEntry[255 - i].peBlue = 255 - i * 2;
805 index = (WORD*)pbmi->bmiColors;
806 for (i = 0; i < 256; i++) {
810 hpal = CreatePalette(plogpal);
811 ok(hpal != NULL, "CreatePalette failed\n");
812 oldpal = SelectPalette(hdc, hpal, TRUE);
813 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
814 ok(hdib != NULL, "CreateDIBSection failed\n");
815 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
816 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
818 test_dib_info(hdib, bits, &pbmi->bmiHeader);
820 SelectPalette(hdc, oldpal, TRUE);
821 oldbm = SelectObject(hdcmem, hdib);
822 oldpal = SelectPalette(hdcmem, hpal, TRUE);
824 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
825 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
826 for (i = 0; i < 256; i++) {
827 ok(rgb[i].rgbRed == plogpal->palPalEntry[i].peRed &&
828 rgb[i].rgbBlue == plogpal->palPalEntry[i].peBlue &&
829 rgb[i].rgbGreen == plogpal->palPalEntry[i].peGreen,
830 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
831 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
834 for (i = 0; i < 256; i++) {
835 test_color(hdcmem, DIBINDEX(i),
836 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
837 test_color(hdcmem, PALETTEINDEX(i),
838 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
839 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue),
840 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
843 SelectPalette(hdcmem, oldpal, TRUE);
844 SelectObject(hdcmem, oldbm);
853 static void test_dib_formats(void)
855 char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256])];
856 BITMAPINFO *bi = (BITMAPINFO *)buffer;
859 int planes, bpp, compr;
863 BOOL expect_ok, todo;
866 memdc = CreateCompatibleDC( 0 );
867 hbmp = CreateCompatibleBitmap( hdc, 10, 10 );
869 memset( data, 0xaa, sizeof(data) );
871 for (bpp = 0; bpp <= 64; bpp++)
873 for (planes = 0; planes <= 64; planes++)
875 for (compr = 0; compr < 8; compr++)
882 case 24: expect_ok = (compr == BI_RGB); break;
884 case 32: expect_ok = (compr == BI_RGB || compr == BI_BITFIELDS); break;
885 default: expect_ok = FALSE; break;
887 if (!planes) expect_ok = FALSE;
888 todo = (compr == BI_BITFIELDS); /* wine doesn't like strange bitfields */
890 memset( bi, 0, sizeof(bi->bmiHeader) );
891 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
892 bi->bmiHeader.biWidth = 2;
893 bi->bmiHeader.biHeight = 2;
894 bi->bmiHeader.biPlanes = planes;
895 bi->bmiHeader.biBitCount = bpp;
896 bi->bmiHeader.biCompression = compr;
897 bi->bmiHeader.biSizeImage = 0;
898 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
900 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
901 if (expect_ok && (planes == 1 || planes * bpp <= 16))
902 ok( hdib != NULL, "CreateDIBSection failed for %u/%u/%u\n", bpp, planes, compr );
904 ok( hdib == NULL, "CreateDIBSection succeeded for %u/%u/%u\n", bpp, planes, compr );
905 if (hdib) DeleteObject( hdib );
907 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, data, bi, DIB_RGB_COLORS );
908 /* no sanity checks in CreateDIBitmap except compression */
909 if (compr == BI_JPEG || compr == BI_PNG)
910 ok( hdib == NULL || broken(hdib != NULL), /* nt4 */
911 "CreateDIBitmap succeeded for %u/%u/%u\n", bpp, planes, compr );
913 ok( hdib != NULL, "CreateDIBitmap failed for %u/%u/%u\n", bpp, planes, compr );
914 if (hdib) DeleteObject( hdib );
916 /* RLE needs a size */
917 bi->bmiHeader.biSizeImage = 0;
918 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
922 todo_wine ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
924 ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
928 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
929 "SetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
930 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
932 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
935 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
936 "SetDIBitsToDevice succeeded for %u/%u/%u\n", bpp, planes, compr );
937 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
941 todo_wine ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
943 ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
947 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
948 "StretchDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
950 bi->bmiHeader.biSizeImage = 1;
951 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
952 if (expect_ok || (bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8))
955 todo_wine ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
957 ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
960 ok( !ret, "SetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
961 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
962 if (expect_ok || (bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8))
963 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
965 ok( !ret, "SetDIBitsToDevice succeeded for %u/%u/%u\n", bpp, planes, compr );
966 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
967 if (expect_ok || (bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8))
970 todo_wine ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
972 ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
975 ok( !ret, "StretchDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
980 memset( bi, 0, sizeof(bi->bmiHeader) );
981 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
982 bi->bmiHeader.biWidth = 2;
983 bi->bmiHeader.biHeight = 2;
984 bi->bmiHeader.biPlanes = 1;
985 bi->bmiHeader.biBitCount = 16;
986 bi->bmiHeader.biCompression = BI_BITFIELDS;
987 bi->bmiHeader.biSizeImage = 0;
988 *(DWORD *)&bi->bmiColors[0] = 0;
989 *(DWORD *)&bi->bmiColors[1] = 0;
990 *(DWORD *)&bi->bmiColors[2] = 0;
992 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
993 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
994 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
995 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
996 /* other functions don't check */
997 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
998 ok( hdib != NULL, "CreateDIBitmap failed with null bitfields\n" );
999 DeleteObject( hdib );
1000 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1001 ok( ret, "SetDIBitsToDevice failed with null bitfields\n" );
1002 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1003 todo_wine ok( ret, "StretchDIBits failed with null bitfields\n" );
1005 /* all fields must be non-zero */
1006 *(DWORD *)&bi->bmiColors[0] = 3;
1007 *(DWORD *)&bi->bmiColors[1] = 0;
1008 *(DWORD *)&bi->bmiColors[2] = 7;
1009 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1010 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1011 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1012 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1014 /* garbage is ok though */
1015 *(DWORD *)&bi->bmiColors[0] = 0x55;
1016 *(DWORD *)&bi->bmiColors[1] = 0x44;
1017 *(DWORD *)&bi->bmiColors[2] = 0x33;
1018 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1019 ok( hdib != NULL, "CreateDIBSection failed with bad bitfields\n" );
1020 if (hdib) DeleteObject( hdib );
1021 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1022 todo_wine ok( ret, "SetDIBits failed with bad bitfields\n" );
1024 bi->bmiHeader.biWidth = -2;
1025 bi->bmiHeader.biHeight = 2;
1026 bi->bmiHeader.biBitCount = 32;
1027 bi->bmiHeader.biCompression = BI_RGB;
1028 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1029 ok( hdib == NULL, "CreateDIBSection succeeded with negative width\n" );
1030 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1031 ok( hdib == NULL, "CreateDIBitmap succeeded with negative width\n" );
1032 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1033 ok( !ret, "SetDIBits succeeded with negative width\n" );
1034 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1035 ok( !ret, "SetDIBitsToDevice succeeded with negative width\n" );
1036 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1037 ok( !ret, "StretchDIBits succeeded with negative width\n" );
1039 bi->bmiHeader.biWidth = 0;
1040 bi->bmiHeader.biHeight = 2;
1041 bi->bmiHeader.biBitCount = 32;
1042 bi->bmiHeader.biCompression = BI_RGB;
1043 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1044 ok( hdib == NULL, "CreateDIBSection succeeded with zero width\n" );
1045 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1046 ok( hdib != NULL, "CreateDIBitmap failed with zero width\n" );
1047 DeleteObject( hdib );
1048 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1049 ok( !ret || broken(ret), /* nt4 */ "SetDIBits succeeded with zero width\n" );
1050 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1051 ok( !ret || broken(ret), /* nt4 */ "SetDIBitsToDevice succeeded with zero width\n" );
1052 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1053 ok( !ret || broken(ret), /* nt4 */ "StretchDIBits succeeded with zero width\n" );
1055 bi->bmiHeader.biWidth = 2;
1056 bi->bmiHeader.biHeight = 0;
1057 bi->bmiHeader.biBitCount = 32;
1058 bi->bmiHeader.biCompression = BI_RGB;
1059 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1060 ok( hdib == NULL, "CreateDIBSection succeeded with zero height\n" );
1061 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1062 ok( hdib != NULL, "CreateDIBitmap failed with zero height\n" );
1063 DeleteObject( hdib );
1064 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1065 ok( !ret, "SetDIBits succeeded with zero height\n" );
1066 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1067 ok( !ret, "SetDIBitsToDevice succeeded with zero height\n" );
1068 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1069 ok( !ret, "StretchDIBits succeeded with zero height\n" );
1072 DeleteObject( hbmp );
1073 ReleaseDC( 0, hdc );
1076 static void test_mono_dibsection(void)
1079 HBITMAP old_bm, mono_ds;
1080 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
1081 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
1088 memdc = CreateCompatibleDC(hdc);
1090 memset(pbmi, 0, sizeof(bmibuf));
1091 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
1092 pbmi->bmiHeader.biHeight = 10;
1093 pbmi->bmiHeader.biWidth = 10;
1094 pbmi->bmiHeader.biBitCount = 1;
1095 pbmi->bmiHeader.biPlanes = 1;
1096 pbmi->bmiHeader.biCompression = BI_RGB;
1097 pbmi->bmiColors[0].rgbRed = 0xff;
1098 pbmi->bmiColors[0].rgbGreen = 0xff;
1099 pbmi->bmiColors[0].rgbBlue = 0xff;
1100 pbmi->bmiColors[1].rgbRed = 0x0;
1101 pbmi->bmiColors[1].rgbGreen = 0x0;
1102 pbmi->bmiColors[1].rgbBlue = 0x0;
1105 * First dib section is 'inverted' ie color[0] is white, color[1] is black
1108 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1109 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1110 old_bm = SelectObject(memdc, mono_ds);
1112 /* black border, white interior */
1113 Rectangle(memdc, 0, 0, 10, 10);
1114 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1115 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1117 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1119 memset(bits, 0, sizeof(bits));
1122 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1123 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1125 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1127 pbmi->bmiColors[0].rgbRed = 0x0;
1128 pbmi->bmiColors[0].rgbGreen = 0x0;
1129 pbmi->bmiColors[0].rgbBlue = 0x0;
1130 pbmi->bmiColors[1].rgbRed = 0xff;
1131 pbmi->bmiColors[1].rgbGreen = 0xff;
1132 pbmi->bmiColors[1].rgbBlue = 0xff;
1134 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1135 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1137 SelectObject(memdc, old_bm);
1138 DeleteObject(mono_ds);
1141 * Next dib section is 'normal' ie color[0] is black, color[1] is white
1144 pbmi->bmiColors[0].rgbRed = 0x0;
1145 pbmi->bmiColors[0].rgbGreen = 0x0;
1146 pbmi->bmiColors[0].rgbBlue = 0x0;
1147 pbmi->bmiColors[1].rgbRed = 0xff;
1148 pbmi->bmiColors[1].rgbGreen = 0xff;
1149 pbmi->bmiColors[1].rgbBlue = 0xff;
1151 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1152 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1153 old_bm = SelectObject(memdc, mono_ds);
1155 /* black border, white interior */
1156 Rectangle(memdc, 0, 0, 10, 10);
1157 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
1158 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
1160 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
1162 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1163 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1165 /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
1167 pbmi->bmiColors[0].rgbRed = 0xff;
1168 pbmi->bmiColors[0].rgbGreen = 0xff;
1169 pbmi->bmiColors[0].rgbBlue = 0xff;
1170 pbmi->bmiColors[1].rgbRed = 0x0;
1171 pbmi->bmiColors[1].rgbGreen = 0x0;
1172 pbmi->bmiColors[1].rgbBlue = 0x0;
1174 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1175 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1178 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
1181 pbmi->bmiColors[0].rgbRed = 0xff;
1182 pbmi->bmiColors[0].rgbGreen = 0xff;
1183 pbmi->bmiColors[0].rgbBlue = 0xff;
1184 pbmi->bmiColors[1].rgbRed = 0x0;
1185 pbmi->bmiColors[1].rgbGreen = 0x0;
1186 pbmi->bmiColors[1].rgbBlue = 0x0;
1187 num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors);
1188 ok(num == 2, "num = %d\n", num);
1190 /* black border, white interior */
1191 Rectangle(memdc, 0, 0, 10, 10);
1192 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1193 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1195 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1197 memset(bits, 0, sizeof(bits));
1200 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1201 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1203 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1205 pbmi->bmiColors[0].rgbRed = 0x0;
1206 pbmi->bmiColors[0].rgbGreen = 0x0;
1207 pbmi->bmiColors[0].rgbBlue = 0x0;
1208 pbmi->bmiColors[1].rgbRed = 0xff;
1209 pbmi->bmiColors[1].rgbGreen = 0xff;
1210 pbmi->bmiColors[1].rgbBlue = 0xff;
1212 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1213 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1215 SelectObject(memdc, old_bm);
1216 DeleteObject(mono_ds);
1219 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
1222 pbmi->bmiColors[0].rgbRed = 0xff;
1223 pbmi->bmiColors[0].rgbGreen = 0x0;
1224 pbmi->bmiColors[0].rgbBlue = 0x0;
1225 pbmi->bmiColors[1].rgbRed = 0xfe;
1226 pbmi->bmiColors[1].rgbGreen = 0x0;
1227 pbmi->bmiColors[1].rgbBlue = 0x0;
1229 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1230 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1231 old_bm = SelectObject(memdc, mono_ds);
1233 /* black border, white interior */
1234 Rectangle(memdc, 0, 0, 10, 10);
1235 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1236 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1238 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1240 pbmi->bmiColors[0].rgbRed = 0x0;
1241 pbmi->bmiColors[0].rgbGreen = 0x0;
1242 pbmi->bmiColors[0].rgbBlue = 0x0;
1243 pbmi->bmiColors[1].rgbRed = 0xff;
1244 pbmi->bmiColors[1].rgbGreen = 0xff;
1245 pbmi->bmiColors[1].rgbBlue = 0xff;
1247 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1248 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1250 /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
1252 pbmi->bmiColors[0].rgbRed = 0xff;
1253 pbmi->bmiColors[0].rgbGreen = 0xff;
1254 pbmi->bmiColors[0].rgbBlue = 0xff;
1255 pbmi->bmiColors[1].rgbRed = 0x0;
1256 pbmi->bmiColors[1].rgbGreen = 0x0;
1257 pbmi->bmiColors[1].rgbBlue = 0x0;
1259 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1260 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1262 SelectObject(memdc, old_bm);
1263 DeleteObject(mono_ds);
1269 static void test_bitmap(void)
1271 char buf[256], buf_cmp[256];
1272 HBITMAP hbmp, hbmp_old;
1278 hdc = CreateCompatibleDC(0);
1281 SetLastError(0xdeadbeef);
1282 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1285 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1286 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1287 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1292 SetLastError(0xdeadbeef);
1293 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1296 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1297 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1298 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1303 SetLastError(0xdeadbeef);
1304 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1305 ok(!hbmp, "CreateBitmap should fail\n");
1307 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1308 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1312 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1313 assert(hbmp != NULL);
1315 ret = GetObject(hbmp, sizeof(bm), &bm);
1316 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1318 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1319 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1320 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1321 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1322 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1323 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1324 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1326 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1327 assert(sizeof(buf) == sizeof(buf_cmp));
1329 ret = GetBitmapBits(hbmp, 0, NULL);
1330 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1332 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1333 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1335 memset(buf, 0xAA, sizeof(buf));
1336 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1337 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1338 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1340 hbmp_old = SelectObject(hdc, hbmp);
1342 ret = GetObject(hbmp, sizeof(bm), &bm);
1343 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1345 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1346 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1347 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1348 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1349 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1350 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1351 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1353 memset(buf, 0xAA, sizeof(buf));
1354 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1355 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1356 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1358 hbmp_old = SelectObject(hdc, hbmp_old);
1359 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1361 /* test various buffer sizes for GetObject */
1362 ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
1363 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1365 ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1366 ok(ret == 0, "%d != 0\n", ret);
1368 ret = GetObject(hbmp, 0, &bm);
1369 ok(ret == 0, "%d != 0\n", ret);
1371 ret = GetObject(hbmp, 1, &bm);
1372 ok(ret == 0, "%d != 0\n", ret);
1378 static void test_bmBits(void)
1384 memset(bits, 0, sizeof(bits));
1385 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1386 ok(hbmp != NULL, "CreateBitmap failed\n");
1388 memset(&bmp, 0xFF, sizeof(bmp));
1389 ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1390 "GetObject failed or returned a wrong structure size\n");
1391 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1396 static void test_GetDIBits_selected_DIB(UINT bpp)
1399 char bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1400 char bmibuf2[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1401 BITMAPINFO *info = (BITMAPINFO *)bmibuf;
1402 BITMAPINFO *info2 = (BITMAPINFO *)bmibuf2;
1405 UINT dib_size, dib32_size;
1412 /* Create a DIB section with a color table */
1414 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1415 info->bmiHeader.biWidth = 32;
1416 info->bmiHeader.biHeight = 32;
1417 info->bmiHeader.biPlanes = 1;
1418 info->bmiHeader.biBitCount = bpp;
1419 info->bmiHeader.biCompression = BI_RGB;
1420 info->bmiHeader.biXPelsPerMeter = 0;
1421 info->bmiHeader.biYPelsPerMeter = 0;
1422 info->bmiHeader.biClrUsed = 0;
1423 info->bmiHeader.biClrImportant = 0;
1425 for (i=0; i < (1u << bpp); i++)
1427 BYTE c = i * (1 << (8 - bpp));
1428 info->bmiColors[i].rgbRed = c;
1429 info->bmiColors[i].rgbGreen = c;
1430 info->bmiColors[i].rgbBlue = c;
1431 info->bmiColors[i].rgbReserved = 0;
1434 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1435 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1436 dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1438 /* Set the bits of the DIB section */
1439 for (i=0; i < dib_size; i++)
1441 ((BYTE *)bits)[i] = i % 256;
1444 /* Select the DIB into a DC */
1445 dib_dc = CreateCompatibleDC(NULL);
1446 old_bmp = SelectObject(dib_dc, dib);
1447 dc = CreateCompatibleDC(NULL);
1448 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
1450 /* Copy the DIB attributes but not the color table */
1451 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1453 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1454 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1456 /* Compare the color table and the bits */
1457 for (i=0; i < (1u << bpp); i++)
1458 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1459 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1460 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1461 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1462 "color table entry %d differs (bpp %d)\n", i, bpp );
1464 ok( !memcmp( bits, bits2, dib_size ), "bit mismatch (bpp %d)\n", bpp );
1466 /* Test various combinations of lines = 0 and bits2 = NULL */
1467 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1468 res = GetDIBits( dc, dib, 0, 0, bits2, info2, DIB_RGB_COLORS );
1469 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1470 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1471 "color table mismatch (bpp %d)\n", bpp );
1473 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1474 res = GetDIBits( dc, dib, 0, 0, NULL, info2, DIB_RGB_COLORS );
1475 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1476 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1477 "color table mismatch (bpp %d)\n", bpp );
1479 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1480 res = GetDIBits( dc, dib, 0, info->bmiHeader.biHeight, NULL, info2, DIB_RGB_COLORS );
1481 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1482 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1483 "color table mismatch (bpp %d)\n", bpp );
1485 /* Map into a 32bit-DIB */
1486 info2->bmiHeader.biBitCount = 32;
1487 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1488 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1490 /* Check if last pixel was set */
1491 pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
1492 ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
1494 HeapFree(GetProcessHeap(), 0, bits2);
1497 SelectObject(dib_dc, old_bmp);
1502 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1505 char bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1506 char bmibuf2[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1507 BITMAPINFO *info = (BITMAPINFO *)bmibuf;
1508 BITMAPINFO *info2 = (BITMAPINFO *)bmibuf2;
1518 width = height = 16;
1520 /* Create a DDB (device-dependent bitmap) */
1524 ddb = CreateBitmap(width, height, 1, 1, NULL);
1528 HDC screen_dc = GetDC(NULL);
1529 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1530 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1531 ReleaseDC(NULL, screen_dc);
1534 /* Set the pixels */
1535 ddb_dc = CreateCompatibleDC(NULL);
1536 old_bmp = SelectObject(ddb_dc, ddb);
1537 for (i = 0; i < width; i++)
1539 for (j=0; j < height; j++)
1541 BYTE c = (i * width + j) % 256;
1542 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1545 SelectObject(ddb_dc, old_bmp);
1547 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1548 info->bmiHeader.biWidth = width;
1549 info->bmiHeader.biHeight = height;
1550 info->bmiHeader.biPlanes = 1;
1551 info->bmiHeader.biBitCount = bpp;
1552 info->bmiHeader.biCompression = BI_RGB;
1554 dc = CreateCompatibleDC(NULL);
1556 /* Fill in biSizeImage */
1557 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1558 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1560 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1561 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1564 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1565 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1567 /* Copy the DIB attributes but not the color table */
1568 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1570 /* Select the DDB into another DC */
1571 old_bmp = SelectObject(ddb_dc, ddb);
1574 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1575 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1577 /* Compare the color table and the bits */
1580 for (i=0; i < (1u << bpp); i++)
1581 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1582 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1583 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1584 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1585 "color table entry %d differs (bpp %d)\n", i, bpp );
1588 ok( !memcmp( bits, bits2, info->bmiHeader.biSizeImage ), "bit mismatch (bpp %d)\n", bpp );
1590 /* Test the palette */
1591 if (info2->bmiHeader.biBitCount <= 8)
1593 WORD *colors = (WORD*)info2->bmiColors;
1595 /* Get the palette indices */
1596 res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1597 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1599 for (i = 0; i < (1 << info->bmiHeader.biBitCount); i++)
1600 ok( colors[i] == i, "%d: got %d (bpp %d)\n", i, colors[i], bpp );
1603 HeapFree(GetProcessHeap(), 0, bits2);
1604 HeapFree(GetProcessHeap(), 0, bits);
1607 SelectObject(ddb_dc, old_bmp);
1612 static void test_GetDIBits(void)
1614 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1615 static const BYTE bmp_bits_1[16 * 2] =
1617 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1618 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1619 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1620 0xff,0xff, 0,0, 0xff,0xff, 0,0
1622 /* 4-bytes aligned 1-bit DIB data: 16x16 */
1623 static const BYTE dib_bits_1[16 * 4] =
1625 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1626 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1627 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1628 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1630 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1631 static const BYTE bmp_bits_24[16 * 16*3] =
1633 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1634 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1635 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1636 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1637 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1638 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1639 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1640 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1641 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1642 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1643 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1644 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1645 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1646 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1647 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1648 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1649 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1650 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1651 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1652 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1653 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1654 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1655 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1656 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1657 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1658 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1659 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1660 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1661 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1662 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1663 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1664 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1666 /* 4-bytes aligned 24-bit DIB data: 16x16 */
1667 static const BYTE dib_bits_24[16 * 16*3] =
1669 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1670 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1671 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1672 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1673 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1674 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1675 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1676 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1677 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1678 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1679 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1680 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1681 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1682 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1683 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1684 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1685 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1686 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1687 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1688 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1689 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1690 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1691 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1692 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1693 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1694 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1695 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1696 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1697 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1698 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1699 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1700 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1705 int i, bytes, lines;
1707 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1708 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1709 PALETTEENTRY pal_ents[20];
1713 /* 1-bit source bitmap data */
1714 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1715 ok(hbmp != 0, "CreateBitmap failed\n");
1717 memset(&bm, 0xAA, sizeof(bm));
1718 bytes = GetObject(hbmp, sizeof(bm), &bm);
1719 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1720 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1721 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1722 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1723 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1724 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1725 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1726 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1728 bytes = GetBitmapBits(hbmp, 0, NULL);
1729 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1730 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1731 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1732 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1734 /* retrieve 1-bit DIB data */
1735 memset(bi, 0, sizeof(*bi));
1736 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1737 bi->bmiHeader.biWidth = bm.bmWidth;
1738 bi->bmiHeader.biHeight = bm.bmHeight;
1739 bi->bmiHeader.biPlanes = 1;
1740 bi->bmiHeader.biBitCount = 1;
1741 bi->bmiHeader.biCompression = BI_RGB;
1742 bi->bmiHeader.biSizeImage = 0;
1743 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1744 SetLastError(0xdeadbeef);
1745 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1746 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1747 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1748 broken(GetLastError() == 0xdeadbeef), /* winnt */
1749 "wrong error %u\n", GetLastError());
1750 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1752 memset(buf, 0xAA, sizeof(buf));
1753 SetLastError(0xdeadbeef);
1754 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1755 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1756 lines, bm.bmHeight, GetLastError());
1757 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1759 /* the color table consists of black and white */
1760 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1761 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1762 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1763 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1764 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1765 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1766 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1767 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1768 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1769 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1770 for (i = 2; i < 256; i++)
1772 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1773 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1774 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1775 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1776 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1779 /* returned bits are DWORD aligned and upside down */
1780 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1782 /* Test the palette indices */
1783 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1784 SetLastError(0xdeadbeef);
1785 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1786 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1787 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1788 for (i = 2; i < 256; i++)
1789 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[1]);
1791 /* retrieve 24-bit DIB data */
1792 memset(bi, 0, sizeof(*bi));
1793 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1794 bi->bmiHeader.biWidth = bm.bmWidth;
1795 bi->bmiHeader.biHeight = bm.bmHeight;
1796 bi->bmiHeader.biPlanes = 1;
1797 bi->bmiHeader.biBitCount = 24;
1798 bi->bmiHeader.biCompression = BI_RGB;
1799 bi->bmiHeader.biSizeImage = 0;
1800 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1801 memset(buf, 0xAA, sizeof(buf));
1802 SetLastError(0xdeadbeef);
1803 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1804 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1805 lines, bm.bmHeight, GetLastError());
1806 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1808 /* the color table doesn't exist for 24-bit images */
1809 for (i = 0; i < 256; i++)
1811 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1812 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1813 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1814 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1815 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1818 /* returned bits are DWORD aligned and upside down */
1819 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1822 /* 24-bit source bitmap data */
1823 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1824 ok(hbmp != 0, "CreateBitmap failed\n");
1825 SetLastError(0xdeadbeef);
1826 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1827 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1828 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1829 lines, bm.bmHeight, GetLastError());
1831 memset(&bm, 0xAA, sizeof(bm));
1832 bytes = GetObject(hbmp, sizeof(bm), &bm);
1833 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1834 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1835 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1836 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1837 ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1838 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1839 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1840 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1842 bytes = GetBitmapBits(hbmp, 0, NULL);
1843 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
1844 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1845 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1846 bm.bmWidthBytes * bm.bmHeight, bytes);
1848 /* retrieve 1-bit DIB data */
1849 memset(bi, 0, sizeof(*bi));
1850 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1851 bi->bmiHeader.biWidth = bm.bmWidth;
1852 bi->bmiHeader.biHeight = bm.bmHeight;
1853 bi->bmiHeader.biPlanes = 1;
1854 bi->bmiHeader.biBitCount = 1;
1855 bi->bmiHeader.biCompression = BI_RGB;
1856 bi->bmiHeader.biSizeImage = 0;
1857 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1858 memset(buf, 0xAA, sizeof(buf));
1859 SetLastError(0xdeadbeef);
1860 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1861 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1862 lines, bm.bmHeight, GetLastError());
1863 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1865 /* the color table consists of black and white */
1866 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1867 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1868 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1869 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1870 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1871 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1872 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1873 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1874 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1875 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1876 for (i = 2; i < 256; i++)
1878 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1879 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1880 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1881 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1882 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1885 /* returned bits are DWORD aligned and upside down */
1886 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1888 /* Test the palette indices */
1889 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1890 SetLastError(0xdeadbeef);
1891 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1892 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1893 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1894 for (i = 2; i < 256; i++)
1895 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[i]);
1897 /* retrieve 4-bit DIB data */
1898 memset(bi, 0, sizeof(*bi));
1899 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1900 bi->bmiHeader.biWidth = bm.bmWidth;
1901 bi->bmiHeader.biHeight = bm.bmHeight;
1902 bi->bmiHeader.biPlanes = 1;
1903 bi->bmiHeader.biBitCount = 4;
1904 bi->bmiHeader.biCompression = BI_RGB;
1905 bi->bmiHeader.biSizeImage = 0;
1906 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1907 memset(buf, 0xAA, sizeof(buf));
1908 SetLastError(0xdeadbeef);
1909 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1910 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1911 lines, bm.bmHeight, GetLastError());
1913 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
1915 for (i = 0; i < 16; i++)
1918 int entry = i < 8 ? i : i + 4;
1920 if(entry == 7) entry = 12;
1921 else if(entry == 12) entry = 7;
1923 expect.rgbRed = pal_ents[entry].peRed;
1924 expect.rgbGreen = pal_ents[entry].peGreen;
1925 expect.rgbBlue = pal_ents[entry].peBlue;
1926 expect.rgbReserved = 0;
1928 ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
1929 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
1930 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
1931 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1932 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1935 /* retrieve 8-bit DIB data */
1936 memset(bi, 0, sizeof(*bi));
1937 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1938 bi->bmiHeader.biWidth = bm.bmWidth;
1939 bi->bmiHeader.biHeight = bm.bmHeight;
1940 bi->bmiHeader.biPlanes = 1;
1941 bi->bmiHeader.biBitCount = 8;
1942 bi->bmiHeader.biCompression = BI_RGB;
1943 bi->bmiHeader.biSizeImage = 0;
1944 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1945 memset(buf, 0xAA, sizeof(buf));
1946 SetLastError(0xdeadbeef);
1947 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1948 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1949 lines, bm.bmHeight, GetLastError());
1951 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
1953 for (i = 0; i < 256; i++)
1957 if (i < 10 || i >= 246)
1959 int entry = i < 10 ? i : i - 236;
1960 expect.rgbRed = pal_ents[entry].peRed;
1961 expect.rgbGreen = pal_ents[entry].peGreen;
1962 expect.rgbBlue = pal_ents[entry].peBlue;
1966 expect.rgbRed = (i & 0x07) << 5;
1967 expect.rgbGreen = (i & 0x38) << 2;
1968 expect.rgbBlue = i & 0xc0;
1970 expect.rgbReserved = 0;
1972 ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
1973 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
1974 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
1975 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1976 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1979 /* retrieve 24-bit DIB data */
1980 memset(bi, 0, sizeof(*bi));
1981 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1982 bi->bmiHeader.biWidth = bm.bmWidth;
1983 bi->bmiHeader.biHeight = bm.bmHeight;
1984 bi->bmiHeader.biPlanes = 1;
1985 bi->bmiHeader.biBitCount = 24;
1986 bi->bmiHeader.biCompression = BI_RGB;
1987 bi->bmiHeader.biSizeImage = 0;
1988 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1989 memset(buf, 0xAA, sizeof(buf));
1990 SetLastError(0xdeadbeef);
1991 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1992 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1993 lines, bm.bmHeight, GetLastError());
1994 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1996 /* the color table doesn't exist for 24-bit images */
1997 for (i = 0; i < 256; i++)
1999 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
2000 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
2001 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2002 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
2003 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
2006 /* returned bits are DWORD aligned and upside down */
2007 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2013 static void test_GetDIBits_BI_BITFIELDS(void)
2015 /* Try a screen resolution detection technique
2016 * from the September 1999 issue of Windows Developer's Journal
2017 * which seems to be in widespread use.
2018 * http://www.lesher.ws/highcolor.html
2019 * http://www.lesher.ws/vidfmt.c
2020 * It hinges on being able to retrieve the bitmaps
2021 * for the three primary colors in non-paletted 16 bit mode.
2023 char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
2025 LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
2026 DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
2032 memset(dibinfo, 0, sizeof(dibinfo_buf));
2033 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2036 ok(hdc != NULL, "GetDC failed?\n");
2037 hbm = CreateCompatibleBitmap(hdc, 1, 1);
2038 ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
2040 /* Call GetDIBits to fill in bmiHeader. */
2041 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2042 ok(ret == 1, "GetDIBits failed\n");
2043 if (dibinfo->bmiHeader.biBitCount > 8)
2045 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2046 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2047 "compression is %u (%d bpp)\n", dibinfo->bmiHeader.biCompression, dibinfo->bmiHeader.biBitCount );
2049 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2051 ok( !bitmasks[0], "red mask is set\n" );
2052 ok( !bitmasks[1], "green mask is set\n" );
2053 ok( !bitmasks[2], "blue mask is set\n" );
2055 /* test with NULL bits pointer and correct bpp */
2056 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2057 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2058 ok(ret == 1, "GetDIBits failed\n");
2060 ok( bitmasks[0] != 0, "red mask is not set\n" );
2061 ok( bitmasks[1] != 0, "green mask is not set\n" );
2062 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2063 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2065 /* test with valid bits pointer */
2066 memset(dibinfo, 0, sizeof(dibinfo_buf));
2067 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2068 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2069 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2070 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2071 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2072 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2074 ok( bitmasks[0] != 0, "red mask is not set\n" );
2075 ok( bitmasks[1] != 0, "green mask is not set\n" );
2076 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2077 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2079 /* now with bits and 0 lines */
2080 memset(dibinfo, 0, sizeof(dibinfo_buf));
2081 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2082 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2083 SetLastError(0xdeadbeef);
2084 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2085 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2087 ok( !bitmasks[0], "red mask is set\n" );
2088 ok( !bitmasks[1], "green mask is set\n" );
2089 ok( !bitmasks[2], "blue mask is set\n" );
2090 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2092 memset(bitmasks, 0, 3*sizeof(DWORD));
2093 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2094 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2095 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2097 ok( bitmasks[0] != 0, "red mask is not set\n" );
2098 ok( bitmasks[1] != 0, "green mask is not set\n" );
2099 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2100 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2103 else skip("bitmap in colortable mode, skipping BI_BITFIELDS tests\n");
2107 /* same thing now with a 32-bpp DIB section */
2109 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2110 dibinfo->bmiHeader.biWidth = 1;
2111 dibinfo->bmiHeader.biHeight = 1;
2112 dibinfo->bmiHeader.biPlanes = 1;
2113 dibinfo->bmiHeader.biBitCount = 32;
2114 dibinfo->bmiHeader.biCompression = BI_RGB;
2115 dibinfo->bmiHeader.biSizeImage = 0;
2116 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2117 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2118 dibinfo->bmiHeader.biClrUsed = 0;
2119 dibinfo->bmiHeader.biClrImportant = 0;
2120 bitmasks[0] = 0x0000ff;
2121 bitmasks[1] = 0x00ff00;
2122 bitmasks[2] = 0xff0000;
2123 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2124 ok( hbm != 0, "failed to create bitmap\n" );
2126 memset(dibinfo, 0, sizeof(dibinfo_buf));
2127 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2128 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2129 ok(ret == 1, "GetDIBits failed\n");
2130 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2132 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2133 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2134 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2135 ok( !bitmasks[0], "red mask is set\n" );
2136 ok( !bitmasks[1], "green mask is set\n" );
2137 ok( !bitmasks[2], "blue mask is set\n" );
2139 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2140 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2141 ok(ret == 1, "GetDIBits failed\n");
2142 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2143 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2144 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2145 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2146 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2148 ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
2149 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2150 ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
2152 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2156 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2157 dibinfo->bmiHeader.biWidth = 1;
2158 dibinfo->bmiHeader.biHeight = 1;
2159 dibinfo->bmiHeader.biPlanes = 1;
2160 dibinfo->bmiHeader.biBitCount = 32;
2161 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2162 dibinfo->bmiHeader.biSizeImage = 0;
2163 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2164 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2165 dibinfo->bmiHeader.biClrUsed = 0;
2166 dibinfo->bmiHeader.biClrImportant = 0;
2167 bitmasks[0] = 0x0000ff;
2168 bitmasks[1] = 0x00ff00;
2169 bitmasks[2] = 0xff0000;
2170 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2171 ok( hbm != 0, "failed to create bitmap\n" );
2175 memset(dibinfo, 0, sizeof(dibinfo_buf));
2176 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2177 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2178 ok(ret == 1, "GetDIBits failed\n");
2180 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
2181 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2182 ok( !bitmasks[0], "red mask is set\n" );
2183 ok( !bitmasks[1], "green mask is set\n" );
2184 ok( !bitmasks[2], "blue mask is set\n" );
2186 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2187 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2188 ok(ret == 1, "GetDIBits failed\n");
2189 ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
2190 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2191 ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
2192 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2197 /* 24-bpp DIB sections don't have bitfields */
2199 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2200 dibinfo->bmiHeader.biWidth = 1;
2201 dibinfo->bmiHeader.biHeight = 1;
2202 dibinfo->bmiHeader.biPlanes = 1;
2203 dibinfo->bmiHeader.biBitCount = 24;
2204 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2205 dibinfo->bmiHeader.biSizeImage = 0;
2206 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2207 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2208 dibinfo->bmiHeader.biClrUsed = 0;
2209 dibinfo->bmiHeader.biClrImportant = 0;
2210 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2211 ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
2212 dibinfo->bmiHeader.biCompression = BI_RGB;
2213 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2214 ok( hbm != 0, "failed to create bitmap\n" );
2216 memset(dibinfo, 0, sizeof(dibinfo_buf));
2217 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2218 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2219 ok(ret == 1, "GetDIBits failed\n");
2220 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2222 ok( dibinfo->bmiHeader.biCompression == BI_RGB,
2223 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2224 ok( !bitmasks[0], "red mask is set\n" );
2225 ok( !bitmasks[1], "green mask is set\n" );
2226 ok( !bitmasks[2], "blue mask is set\n" );
2228 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2229 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2230 ok(ret == 1, "GetDIBits failed\n");
2231 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2232 ok( !bitmasks[0], "red mask is set\n" );
2233 ok( !bitmasks[1], "green mask is set\n" );
2234 ok( !bitmasks[2], "blue mask is set\n" );
2235 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2238 ReleaseDC(NULL, hdc);
2241 static void test_select_object(void)
2244 HBITMAP hbm, hbm_old;
2246 DWORD depths[] = {8, 15, 16, 24, 32};
2251 ok(hdc != 0, "GetDC(0) failed\n");
2252 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2253 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2255 hbm_old = SelectObject(hdc, hbm);
2256 ok(hbm_old == 0, "SelectObject should fail\n");
2261 hdc = CreateCompatibleDC(0);
2262 ok(hdc != 0, "GetDC(0) failed\n");
2263 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2264 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2266 hbm_old = SelectObject(hdc, hbm);
2267 ok(hbm_old != 0, "SelectObject failed\n");
2268 hbm_old = SelectObject(hdc, hbm_old);
2269 ok(hbm_old == hbm, "SelectObject failed\n");
2273 /* test an 1-bpp bitmap */
2274 planes = GetDeviceCaps(hdc, PLANES);
2277 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
2278 ok(hbm != 0, "CreateBitmap failed\n");
2280 hbm_old = SelectObject(hdc, hbm);
2281 ok(hbm_old != 0, "SelectObject failed\n");
2282 hbm_old = SelectObject(hdc, hbm_old);
2283 ok(hbm_old == hbm, "SelectObject failed\n");
2287 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
2288 /* test a color bitmap to dc bpp matching */
2289 planes = GetDeviceCaps(hdc, PLANES);
2290 bpp = GetDeviceCaps(hdc, BITSPIXEL);
2292 hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
2293 ok(hbm != 0, "CreateBitmap failed\n");
2295 hbm_old = SelectObject(hdc, hbm);
2296 if(depths[i] == bpp ||
2297 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
2299 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
2300 SelectObject(hdc, hbm_old);
2302 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
2305 memset(&bm, 0xAA, sizeof(bm));
2306 bytes = GetObject(hbm, sizeof(bm), &bm);
2307 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2308 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2309 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
2310 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
2311 ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2312 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
2313 if(depths[i] == 15) {
2314 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
2316 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2318 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2326 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
2331 ret = GetObjectType(hbmp);
2332 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
2334 ret = GetObject(hbmp, 0, 0);
2335 ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
2337 memset(&bm, 0xDA, sizeof(bm));
2338 SetLastError(0xdeadbeef);
2339 ret = GetObject(hbmp, sizeof(bm), &bm);
2340 if (!ret) /* XP, only for curObj2 */ return;
2341 ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
2342 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2343 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2344 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2345 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2346 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2347 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2348 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2351 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2353 static void test_CreateBitmap(void)
2356 HDC screenDC = GetDC(0);
2357 HDC hdc = CreateCompatibleDC(screenDC);
2360 /* all of these are the stock monochrome bitmap */
2361 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2362 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2363 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2364 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2365 HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2366 HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2368 /* these 2 are not the stock monochrome bitmap */
2369 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2370 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2372 HBITMAP old1 = SelectObject(hdc, bm2);
2373 HBITMAP old2 = SelectObject(screenDC, bm3);
2374 SelectObject(hdc, old1);
2375 SelectObject(screenDC, old2);
2377 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2378 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2379 bm, bm1, bm4, bm5, curObj1, old1);
2380 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2382 ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
2383 ok(old2 == 0, "old2 %p\n", old2);
2385 test_mono_1x1_bmp(bm);
2386 test_mono_1x1_bmp(bm1);
2387 test_mono_1x1_bmp(bm2);
2388 test_mono_1x1_bmp(bm3);
2389 test_mono_1x1_bmp(bm4);
2390 test_mono_1x1_bmp(bm5);
2391 test_mono_1x1_bmp(old1);
2392 test_mono_1x1_bmp(curObj1);
2402 ReleaseDC(0, screenDC);
2404 /* show that Windows ignores the provided bm.bmWidthBytes */
2408 bmp.bmWidthBytes = 28;
2410 bmp.bmBitsPixel = 1;
2412 bm = CreateBitmapIndirect(&bmp);
2413 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2414 test_mono_1x1_bmp(bm);
2417 /* Test how the bmBitsPixel field is treated */
2418 for(i = 1; i <= 33; i++) {
2422 bmp.bmWidthBytes = 28;
2424 bmp.bmBitsPixel = i;
2426 SetLastError(0xdeadbeef);
2427 bm = CreateBitmapIndirect(&bmp);
2429 DWORD error = GetLastError();
2430 ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
2431 ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2435 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2436 GetObject(bm, sizeof(bmp), &bmp);
2443 } else if(i <= 16) {
2445 } else if(i <= 24) {
2447 } else if(i <= 32) {
2450 ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2451 i, bmp.bmBitsPixel, expect);
2456 static void test_bitmapinfoheadersize(void)
2463 memset(&bmi, 0, sizeof(BITMAPINFO));
2464 bmi.bmiHeader.biHeight = 100;
2465 bmi.bmiHeader.biWidth = 512;
2466 bmi.bmiHeader.biBitCount = 24;
2467 bmi.bmiHeader.biPlanes = 1;
2469 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2471 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2472 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2474 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2476 SetLastError(0xdeadbeef);
2477 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2478 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2481 bmi.bmiHeader.biSize++;
2483 SetLastError(0xdeadbeef);
2484 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2486 broken(!hdib), /* Win98, WinMe */
2487 "CreateDIBSection error %d\n", GetLastError());
2490 bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2492 SetLastError(0xdeadbeef);
2493 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2495 broken(!hdib), /* Win98, WinMe */
2496 "CreateDIBSection error %d\n", GetLastError());
2499 bmi.bmiHeader.biSize++;
2501 SetLastError(0xdeadbeef);
2502 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2504 broken(!hdib), /* Win98, WinMe */
2505 "CreateDIBSection error %d\n", GetLastError());
2508 bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2510 SetLastError(0xdeadbeef);
2511 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2512 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2515 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2517 SetLastError(0xdeadbeef);
2518 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2520 broken(!hdib), /* Win95 */
2521 "CreateDIBSection error %d\n", GetLastError());
2524 memset(&bci, 0, sizeof(BITMAPCOREINFO));
2525 bci.bmciHeader.bcHeight = 100;
2526 bci.bmciHeader.bcWidth = 512;
2527 bci.bmciHeader.bcBitCount = 24;
2528 bci.bmciHeader.bcPlanes = 1;
2530 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2532 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2533 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2535 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2537 SetLastError(0xdeadbeef);
2538 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2539 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2542 bci.bmciHeader.bcSize++;
2544 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2545 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2547 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2549 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2550 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2555 static void test_get16dibits(void)
2557 BYTE bits[4 * (16 / sizeof(BYTE))];
2559 HDC screen_dc = GetDC(NULL);
2562 int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2564 int overwritten_bytes = 0;
2566 memset(bits, 0, sizeof(bits));
2567 hbmp = CreateBitmap(2, 2, 1, 16, bits);
2568 ok(hbmp != NULL, "CreateBitmap failed\n");
2570 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2573 memset(info, '!', info_len);
2574 memset(info, 0, sizeof(info->bmiHeader));
2576 info->bmiHeader.biSize = sizeof(info->bmiHeader);
2577 info->bmiHeader.biWidth = 2;
2578 info->bmiHeader.biHeight = 2;
2579 info->bmiHeader.biPlanes = 1;
2580 info->bmiHeader.biCompression = BI_RGB;
2582 ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2583 ok(ret != 0, "GetDIBits failed got %d\n", ret);
2585 for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2587 overwritten_bytes++;
2588 ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2590 HeapFree(GetProcessHeap(), 0, info);
2592 ReleaseDC(NULL, screen_dc);
2595 static BOOL compare_buffers_no_alpha(UINT32 *a, UINT32 *b, int length)
2598 for(i = 0; i < length; i++)
2599 if((a[i] & 0x00FFFFFF) != (b[i] & 0x00FFFFFF))
2604 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2605 DWORD dwRop, UINT32 expected, int line)
2607 *srcBuffer = 0xFEDCBA98;
2608 *dstBuffer = 0x89ABCDEF;
2609 Rectangle(hdcSrc, 0, 0, 1, 1); /* A null operation to ensure dibs are coerced to X11 */
2610 BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
2611 ok(expected == *dstBuffer,
2612 "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2613 dwRop, expected, *dstBuffer, line);
2616 static void test_BitBlt(void)
2618 HBITMAP bmpDst, bmpSrc;
2619 HBITMAP oldDst, oldSrc;
2620 HDC hdcScreen, hdcDst, hdcSrc;
2621 UINT32 *dstBuffer, *srcBuffer;
2622 HBRUSH hBrush, hOldBrush;
2623 BITMAPINFO bitmapInfo;
2625 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2626 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2627 bitmapInfo.bmiHeader.biWidth = 1;
2628 bitmapInfo.bmiHeader.biHeight = 1;
2629 bitmapInfo.bmiHeader.biPlanes = 1;
2630 bitmapInfo.bmiHeader.biBitCount = 32;
2631 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2632 bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2634 hdcScreen = CreateCompatibleDC(0);
2635 hdcDst = CreateCompatibleDC(hdcScreen);
2636 hdcSrc = CreateCompatibleDC(hdcDst);
2638 /* Setup the destination dib section */
2639 bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
2641 oldDst = SelectObject(hdcDst, bmpDst);
2643 hBrush = CreateSolidBrush(0x012345678);
2644 hOldBrush = SelectObject(hdcDst, hBrush);
2646 /* Setup the source dib section */
2647 bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
2649 oldSrc = SelectObject(hdcSrc, bmpSrc);
2651 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2652 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2653 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2654 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2655 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2656 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2657 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2658 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2659 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2660 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2661 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2662 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2663 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2664 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2665 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2668 SelectObject(hdcSrc, oldSrc);
2669 DeleteObject(bmpSrc);
2672 SelectObject(hdcDst, hOldBrush);
2673 DeleteObject(hBrush);
2674 SelectObject(hdcDst, oldDst);
2675 DeleteObject(bmpDst);
2679 DeleteDC(hdcScreen);
2682 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2683 DWORD dwRop, UINT32 expected, int line)
2685 *srcBuffer = 0xFEDCBA98;
2686 *dstBuffer = 0x89ABCDEF;
2687 StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
2688 ok(expected == *dstBuffer,
2689 "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2690 dwRop, expected, *dstBuffer, line);
2693 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2694 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2695 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2696 UINT32 expected[4], UINT32 legacy_expected[4], int line)
2698 memset(dstBuffer, 0, 16);
2699 StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2700 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
2701 ok(memcmp(dstBuffer, expected, 16) == 0 ||
2702 broken(compare_buffers_no_alpha(dstBuffer, legacy_expected, 4)),
2703 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2704 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2705 expected[0], expected[1], expected[2], expected[3],
2706 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2707 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2708 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2711 static void test_StretchBlt(void)
2713 HBITMAP bmpDst, bmpSrc;
2714 HBITMAP oldDst, oldSrc;
2715 HDC hdcScreen, hdcDst, hdcSrc;
2716 UINT32 *dstBuffer, *srcBuffer;
2717 HBRUSH hBrush, hOldBrush;
2718 BITMAPINFO biDst, biSrc;
2719 UINT32 expected[4], legacy_expected[4];
2721 memset(&biDst, 0, sizeof(BITMAPINFO));
2722 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2723 biDst.bmiHeader.biWidth = 2;
2724 biDst.bmiHeader.biHeight = -2;
2725 biDst.bmiHeader.biPlanes = 1;
2726 biDst.bmiHeader.biBitCount = 32;
2727 biDst.bmiHeader.biCompression = BI_RGB;
2728 memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
2730 hdcScreen = CreateCompatibleDC(0);
2731 hdcDst = CreateCompatibleDC(hdcScreen);
2732 hdcSrc = CreateCompatibleDC(hdcDst);
2735 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2737 oldDst = SelectObject(hdcDst, bmpDst);
2739 bmpSrc = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&srcBuffer,
2741 oldSrc = SelectObject(hdcSrc, bmpSrc);
2743 hBrush = CreateSolidBrush(0x012345678);
2744 hOldBrush = SelectObject(hdcDst, hBrush);
2746 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2747 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2748 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2749 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2750 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2751 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2752 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2753 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2754 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2755 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2756 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2757 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2758 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2759 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2760 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2762 SelectObject(hdcDst, hOldBrush);
2763 DeleteObject(hBrush);
2765 /* Top-down to top-down tests */
2766 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2767 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
2769 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2770 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2771 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2772 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2774 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2775 expected[2] = 0x00000000, expected[3] = 0x00000000;
2776 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2777 0, 0, 1, 1, 0, 0, 1, 1, expected, expected, __LINE__);
2779 expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
2780 expected[2] = 0xCAFED00D, expected[3] = 0xCAFED00D;
2781 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2782 0, 0, 2, 2, 0, 0, 1, 1, expected, expected, __LINE__);
2784 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2785 expected[2] = 0x00000000, expected[3] = 0x00000000;
2786 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2787 0, 0, 1, 1, 0, 0, 2, 2, expected, expected, __LINE__);
2789 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2790 expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2791 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2792 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2794 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2795 expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2796 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2797 1, 1, -2, -2, 0, 0, 2, 2, expected, expected, __LINE__);
2799 /* This result seems broken. One might expect the following result:
2800 * 0xCAFED00D 0xFEEDFACE
2801 * 0xFEDCBA98 0x76543210
2803 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2804 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2805 legacy_expected[0] = 0xCAFED00D, legacy_expected[1] = 0x00000000;
2806 legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
2807 todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2808 1, 1, -2, -2, 1, 1, -2, -2, expected,
2809 legacy_expected, __LINE__);
2811 expected[0] = 0x00000000, expected[1] = 0x00000000;
2812 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
2813 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2814 1, 1, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2816 SelectObject(hdcDst, oldDst);
2817 DeleteObject(bmpDst);
2819 /* Top-down to bottom-up tests */
2820 biDst.bmiHeader.biHeight = 2;
2821 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2823 oldDst = SelectObject(hdcDst, bmpDst);
2825 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2826 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
2827 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2828 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2830 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2831 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2832 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2833 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2835 SelectObject(hdcSrc, oldSrc);
2836 DeleteObject(bmpSrc);
2838 /* Bottom-up to bottom-up tests */
2839 biSrc.bmiHeader.biHeight = 2;
2840 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2842 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2843 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
2844 oldSrc = SelectObject(hdcSrc, bmpSrc);
2846 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2847 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2848 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2849 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2851 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2852 expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2853 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2854 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2856 SelectObject(hdcDst, oldDst);
2857 DeleteObject(bmpDst);
2859 /* Bottom-up to top-down tests */
2860 biDst.bmiHeader.biHeight = -2;
2861 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2863 oldDst = SelectObject(hdcDst, bmpDst);
2865 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2866 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
2867 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2868 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2870 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2871 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2872 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2873 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2876 SelectObject(hdcSrc, oldSrc);
2877 DeleteObject(bmpSrc);
2880 SelectObject(hdcDst, oldDst);
2881 DeleteObject(bmpDst);
2884 DeleteDC(hdcScreen);
2887 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
2888 DWORD dwRop, UINT32 expected, int line)
2890 const UINT32 buffer[2] = { 0xFEDCBA98, 0 };
2891 BITMAPINFO bitmapInfo;
2893 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2894 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2895 bitmapInfo.bmiHeader.biWidth = 2;
2896 bitmapInfo.bmiHeader.biHeight = 1;
2897 bitmapInfo.bmiHeader.biPlanes = 1;
2898 bitmapInfo.bmiHeader.biBitCount = 32;
2899 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2900 bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer);
2902 *dstBuffer = 0x89ABCDEF;
2904 StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop);
2905 ok(expected == *dstBuffer,
2906 "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2907 dwRop, expected, *dstBuffer, line);
2910 static void check_StretchDIBits_stretch(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
2911 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2912 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2913 UINT32 expected[4], UINT32 legacy_expected[4], int line)
2915 BITMAPINFO bitmapInfo;
2917 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2918 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2919 bitmapInfo.bmiHeader.biWidth = 2;
2920 bitmapInfo.bmiHeader.biHeight = -2;
2921 bitmapInfo.bmiHeader.biPlanes = 1;
2922 bitmapInfo.bmiHeader.biBitCount = 32;
2923 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2925 memset(dstBuffer, 0, 16);
2926 StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2927 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2928 srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
2929 ok(memcmp(dstBuffer, expected, 16) == 0,
2930 "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2931 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2932 expected[0], expected[1], expected[2], expected[3],
2933 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2934 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2935 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2938 static void test_StretchDIBits(void)
2942 HDC hdcScreen, hdcDst;
2943 UINT32 *dstBuffer, srcBuffer[4];
2944 HBRUSH hBrush, hOldBrush;
2946 UINT32 expected[4], legacy_expected[4];
2948 memset(&biDst, 0, sizeof(BITMAPINFO));
2949 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2950 biDst.bmiHeader.biWidth = 2;
2951 biDst.bmiHeader.biHeight = -2;
2952 biDst.bmiHeader.biPlanes = 1;
2953 biDst.bmiHeader.biBitCount = 32;
2954 biDst.bmiHeader.biCompression = BI_RGB;
2956 hdcScreen = CreateCompatibleDC(0);
2957 hdcDst = CreateCompatibleDC(hdcScreen);
2960 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2962 oldDst = SelectObject(hdcDst, bmpDst);
2964 hBrush = CreateSolidBrush(0x012345678);
2965 hOldBrush = SelectObject(hdcDst, hBrush);
2967 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2968 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2969 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2970 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2971 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2972 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2973 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2974 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2975 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2976 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2977 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2978 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2979 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2980 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2981 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2983 SelectObject(hdcDst, hOldBrush);
2984 DeleteObject(hBrush);
2986 /* Top-down destination tests */
2987 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2988 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
2990 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2991 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2992 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2993 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2995 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2996 expected[2] = 0x00000000, expected[3] = 0x00000000;
2997 legacy_expected[0] = 0xFEDCBA98, legacy_expected[1] = 0x00000000;
2998 legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
2999 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3000 0, 0, 1, 1, 0, 0, 1, 1, expected, legacy_expected, __LINE__);
3002 expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
3003 expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
3004 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3005 0, 0, 2, 2, 0, 0, 1, 1, expected, expected, __LINE__);
3007 expected[0] = 0x42441000, expected[1] = 0x00000000;
3008 expected[2] = 0x00000000, expected[3] = 0x00000000;
3009 legacy_expected[0] = 0x00543210, legacy_expected[1] = 0x00000000;
3010 legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
3011 todo_wine check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3012 0, 0, 1, 1, 0, 0, 2, 2, expected, legacy_expected, __LINE__);
3014 expected[0] = 0x00000000, expected[1] = 0x00000000;
3015 expected[2] = 0x00000000, expected[3] = 0x00000000;
3016 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3017 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
3019 expected[0] = 0x00000000, expected[1] = 0x00000000;
3020 expected[2] = 0x00000000, expected[3] = 0x00000000;
3021 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3022 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
3024 expected[0] = 0x00000000, expected[1] = 0x00000000;
3025 expected[2] = 0x00000000, expected[3] = 0x00000000;
3026 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3027 1, 1, -2, -2, 1, 1, -2, -2, expected, expected, __LINE__);
3029 expected[0] = 0x00000000, expected[1] = 0x00000000;
3030 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
3031 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3032 1, 1, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
3034 SelectObject(hdcDst, oldDst);
3035 DeleteObject(bmpDst);
3037 /* Bottom up destination tests */
3038 biDst.bmiHeader.biHeight = 2;
3039 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3041 oldDst = SelectObject(hdcDst, bmpDst);
3043 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3044 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
3045 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3046 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
3049 SelectObject(hdcDst, oldDst);
3050 DeleteObject(bmpDst);
3053 DeleteDC(hdcScreen);
3056 static void test_GdiAlphaBlend(void)
3058 /* test out-of-bound parameters for GdiAlphaBlend */
3071 BLENDFUNCTION blend;
3073 if (!pGdiAlphaBlend)
3075 win_skip("GdiAlphaBlend() is not implemented\n");
3079 hdcNull = GetDC(NULL);
3080 hdcDst = CreateCompatibleDC(hdcNull);
3081 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
3082 hdcSrc = CreateCompatibleDC(hdcNull);
3084 memset(&bmi, 0, sizeof(bmi)); /* as of Wine 0.9.44 we require the src to be a DIB section */
3085 bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
3086 bmi.bmiHeader.biHeight = 20;
3087 bmi.bmiHeader.biWidth = 20;
3088 bmi.bmiHeader.biBitCount = 32;
3089 bmi.bmiHeader.biPlanes = 1;
3090 bmi.bmiHeader.biCompression = BI_RGB;
3091 bmpSrc = CreateDIBSection(hdcDst, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3092 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3094 oldDst = SelectObject(hdcDst, bmpDst);
3095 oldSrc = SelectObject(hdcSrc, bmpSrc);
3097 blend.BlendOp = AC_SRC_OVER;
3098 blend.BlendFlags = 0;
3099 blend.SourceConstantAlpha = 128;
3100 blend.AlphaFormat = 0;
3102 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend), TRUE, BOOL, "%d");
3103 SetLastError(0xdeadbeef);
3104 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), FALSE, BOOL, "%d");
3105 expect_eq(GetLastError(), ERROR_INVALID_PARAMETER, int, "%d");
3106 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), FALSE, BOOL, "%d");
3107 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend), FALSE, BOOL, "%d");
3108 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
3109 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
3111 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
3112 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), TRUE, BOOL, "%d");
3113 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), TRUE, BOOL, "%d");
3114 SetMapMode(hdcSrc, MM_ANISOTROPIC);
3115 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
3116 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend), TRUE, BOOL, "%d");
3117 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend), TRUE, BOOL, "%d");
3119 SetLastError(0xdeadbeef);
3120 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend), FALSE, BOOL, "%d");
3121 expect_eq(GetLastError(), 0xdeadbeef, int, "%d");
3123 SelectObject(hdcDst, oldDst);
3124 SelectObject(hdcSrc, oldSrc);
3125 DeleteObject(bmpSrc);
3126 DeleteObject(bmpDst);
3130 ReleaseDC(NULL, hdcNull);
3134 static void test_clipping(void)
3142 HDC hdcDst = CreateCompatibleDC( NULL );
3143 HDC hdcSrc = CreateCompatibleDC( NULL );
3145 BITMAPINFO bmpinfo={{0}};
3146 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3147 bmpinfo.bmiHeader.biWidth = 100;
3148 bmpinfo.bmiHeader.biHeight = 100;
3149 bmpinfo.bmiHeader.biPlanes = 1;
3150 bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3151 bmpinfo.bmiHeader.biCompression = BI_RGB;
3153 bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3154 ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3155 SelectObject( hdcDst, bmpDst );
3157 bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3158 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3159 SelectObject( hdcSrc, bmpSrc );
3161 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3162 ok(result, "BitBlt failed\n");
3164 hRgn = CreateRectRgn( 0,0,0,0 );
3165 SelectClipRgn( hdcDst, hRgn );
3167 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3168 ok(result, "BitBlt failed\n");
3170 DeleteObject( bmpDst );
3171 DeleteObject( bmpSrc );
3172 DeleteObject( hRgn );
3177 static void test_32bit_bitmap_blt(void)
3180 HBITMAP bmpSrc, bmpDst;
3181 HBITMAP oldSrc, oldDst;
3182 HDC hdcSrc, hdcDst, hdcScreen;
3184 DWORD colorSrc = 0x11223344;
3186 memset(&biDst, 0, sizeof(BITMAPINFO));
3187 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3188 biDst.bmiHeader.biWidth = 2;
3189 biDst.bmiHeader.biHeight = -2;
3190 biDst.bmiHeader.biPlanes = 1;
3191 biDst.bmiHeader.biBitCount = 32;
3192 biDst.bmiHeader.biCompression = BI_RGB;
3194 hdcScreen = CreateCompatibleDC(0);
3195 if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3197 DeleteDC(hdcScreen);
3198 trace("Skipping 32-bit DDB test\n");
3202 hdcSrc = CreateCompatibleDC(hdcScreen);
3203 bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3204 oldSrc = SelectObject(hdcSrc, bmpSrc);
3206 hdcDst = CreateCompatibleDC(hdcScreen);
3207 bmpDst = CreateDIBSection(hdcDst, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3208 oldDst = SelectObject(hdcDst, bmpDst);
3210 StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3211 ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3214 SelectObject(hdcDst, oldDst);
3215 DeleteObject(bmpDst);
3218 SelectObject(hdcSrc, oldSrc);
3219 DeleteObject(bmpSrc);
3222 DeleteDC(hdcScreen);
3226 * Used by test_GetDIBits_top_down to create the bitmap to test against.
3228 static void setup_picture(char *picture, int bpp)
3236 /*Set the first byte in each pixel to the index of that pixel.*/
3237 for (i = 0; i < 4; i++)
3238 picture[i * (bpp / 8)] = i;
3243 /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
3250 static void test_GetDIBits_top_down(int bpp)
3253 HBITMAP bmptb, bmpbt;
3259 memset( &bi, 0, sizeof(bi) );
3260 bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
3261 bi.bmiHeader.biWidth=2;
3262 bi.bmiHeader.biHeight=2;
3263 bi.bmiHeader.biPlanes=1;
3264 bi.bmiHeader.biBitCount=bpp;
3265 bi.bmiHeader.biCompression=BI_RGB;
3267 /*Get the device context for the screen.*/
3269 ok(hdc != NULL, "Could not get a handle to a device context.\n");
3271 /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
3272 bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3273 ok(bmpbt != NULL, "Could not create a DIB section.\n");
3274 /*Now that we have a pointer to the pixels, we write to them.*/
3275 setup_picture((char*)picture, bpp);
3276 /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
3277 bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
3278 bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3279 ok(bmptb != NULL, "Could not create a DIB section.\n");
3280 /*Write to this top to bottom bitmap.*/
3281 setup_picture((char*)picture, bpp);
3283 bi.bmiHeader.biWidth = 1;
3285 bi.bmiHeader.biHeight = 2;
3286 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3287 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3288 /*Check the first byte of the pixel.*/
3289 ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3290 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3291 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3292 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3293 /*Check second scanline.*/
3294 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3295 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3296 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3297 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3298 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3299 ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3300 /*Check both scanlines.*/
3301 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3302 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3303 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3304 ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3305 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3306 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3307 ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3308 ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3310 /*Make destination bitmap top-down.*/
3311 bi.bmiHeader.biHeight = -2;
3312 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3313 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3314 ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3315 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3316 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3317 ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3318 /*Check second scanline.*/
3319 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3320 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3321 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3322 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3323 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3324 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3325 /*Check both scanlines.*/
3326 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3327 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3328 ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3329 ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3330 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3331 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3332 ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3333 ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3335 DeleteObject(bmpbt);
3336 DeleteObject(bmptb);
3339 static void test_GetSetDIBits_rtl(void)
3342 HBITMAP bitmap, orig_bitmap;
3345 DWORD bits_1[8 * 8], bits_2[8 * 8];
3349 win_skip("Don't have SetLayout\n");
3353 hdc = GetDC( NULL );
3354 hdc_mem = CreateCompatibleDC( hdc );
3355 pSetLayout( hdc_mem, LAYOUT_LTR );
3357 bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
3358 orig_bitmap = SelectObject( hdc_mem, bitmap );
3359 SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
3360 SelectObject( hdc_mem, orig_bitmap );
3362 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3363 info.bmiHeader.biWidth = 8;
3364 info.bmiHeader.biHeight = 8;
3365 info.bmiHeader.biPlanes = 1;
3366 info.bmiHeader.biBitCount = 32;
3367 info.bmiHeader.biCompression = BI_RGB;
3369 /* First show that GetDIBits ignores the layout mode. */
3371 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3372 ok(ret == 8, "got %d\n", ret);
3373 ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
3375 pSetLayout( hdc_mem, LAYOUT_RTL );
3377 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3378 ok(ret == 8, "got %d\n", ret);
3380 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3382 /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
3383 followed by a GetDIBits and show that the bits remain unchanged. */
3385 pSetLayout( hdc_mem, LAYOUT_LTR );
3387 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3388 ok(ret == 8, "got %d\n", ret);
3389 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3390 ok(ret == 8, "got %d\n", ret);
3391 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3393 pSetLayout( hdc_mem, LAYOUT_RTL );
3395 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3396 ok(ret == 8, "got %d\n", ret);
3397 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3398 ok(ret == 8, "got %d\n", ret);
3399 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3401 DeleteObject( bitmap );
3402 DeleteDC( hdc_mem );
3403 ReleaseDC( NULL, hdc );
3406 static void test_GetDIBits_scanlines(void)
3408 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3409 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3411 HDC hdc = GetDC( NULL );
3413 DWORD data[128], inverted_bits[64];
3416 memset( info, 0, sizeof(bmi_buf) );
3418 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3419 info->bmiHeader.biWidth = 8;
3420 info->bmiHeader.biHeight = 8;
3421 info->bmiHeader.biPlanes = 1;
3422 info->bmiHeader.biBitCount = 32;
3423 info->bmiHeader.biCompression = BI_RGB;
3425 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3427 for (i = 0; i < 64; i++)
3430 inverted_bits[56 - (i & ~7) + (i & 7)] = i;
3435 memset( data, 0xaa, sizeof(data) );
3437 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3438 ok( ret == 8, "got %d\n", ret );
3439 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3440 memset( data, 0xaa, sizeof(data) );
3442 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3443 ok( ret == 5, "got %d\n", ret );
3444 ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
3445 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3446 memset( data, 0xaa, sizeof(data) );
3448 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3449 ok( ret == 7, "got %d\n", ret );
3450 ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
3451 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3452 memset( data, 0xaa, sizeof(data) );
3454 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3455 ok( ret == 1, "got %d\n", ret );
3456 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3457 memset( data, 0xaa, sizeof(data) );
3459 info->bmiHeader.biHeight = 16;
3460 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3461 ok( ret == 5, "got %d\n", ret );
3462 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3463 ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
3464 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3465 memset( data, 0xaa, sizeof(data) );
3467 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3468 ok( ret == 6, "got %d\n", ret );
3469 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3470 ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
3471 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3472 memset( data, 0xaa, sizeof(data) );
3474 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3475 ok( ret == 0, "got %d\n", ret );
3476 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3477 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3478 memset( data, 0xaa, sizeof(data) );
3480 info->bmiHeader.biHeight = 5;
3481 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3482 ok( ret == 2, "got %d\n", ret );
3483 ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
3484 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3485 memset( data, 0xaa, sizeof(data) );
3489 info->bmiHeader.biHeight = -8;
3490 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3491 ok( ret == 8, "got %d\n", ret );
3492 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3493 memset( data, 0xaa, sizeof(data) );
3495 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3496 ok( ret == 5, "got %d\n", ret );
3497 ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
3498 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3499 memset( data, 0xaa, sizeof(data) );
3501 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3502 ok( ret == 7, "got %d\n", ret );
3503 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3504 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3505 memset( data, 0xaa, sizeof(data) );
3507 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3508 ok( ret == 4, "got %d\n", ret );
3509 ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
3510 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3511 memset( data, 0xaa, sizeof(data) );
3513 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3514 ok( ret == 5, "got %d\n", ret );
3515 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3516 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3517 memset( data, 0xaa, sizeof(data) );
3519 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3520 ok( ret == 5, "got %d\n", ret );
3521 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3522 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3523 memset( data, 0xaa, sizeof(data) );
3525 info->bmiHeader.biHeight = -16;
3526 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3527 ok( ret == 8, "got %d\n", ret );
3528 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3529 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3530 memset( data, 0xaa, sizeof(data) );
3532 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3533 ok( ret == 5, "got %d\n", ret );
3534 ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
3535 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3536 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3537 memset( data, 0xaa, sizeof(data) );
3539 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3540 ok( ret == 8, "got %d\n", ret );
3541 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3542 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3543 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3544 memset( data, 0xaa, sizeof(data) );
3546 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3547 ok( ret == 8, "got %d\n", ret );
3548 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3549 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3550 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3551 memset( data, 0xaa, sizeof(data) );
3553 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3554 ok( ret == 7, "got %d\n", ret );
3555 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3556 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3557 memset( data, 0xaa, sizeof(data) );
3559 ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
3560 ok( ret == 1, "got %d\n", ret );
3561 for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3562 memset( data, 0xaa, sizeof(data) );
3564 info->bmiHeader.biHeight = -5;
3565 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3566 ok( ret == 2, "got %d\n", ret );
3567 ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
3568 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3569 memset( data, 0xaa, sizeof(data) );
3571 DeleteObject( dib );
3573 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3574 info->bmiHeader.biWidth = 8;
3575 info->bmiHeader.biHeight = -8;
3576 info->bmiHeader.biPlanes = 1;
3577 info->bmiHeader.biBitCount = 32;
3578 info->bmiHeader.biCompression = BI_RGB;
3580 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3582 for (i = 0; i < 64; i++) dib_bits[i] = i;
3586 info->bmiHeader.biHeight = -8;
3587 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3588 ok( ret == 8, "got %d\n", ret );
3589 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3590 memset( data, 0xaa, sizeof(data) );
3592 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3593 ok( ret == 5, "got %d\n", ret );
3594 ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
3595 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3596 memset( data, 0xaa, sizeof(data) );
3598 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3599 ok( ret == 7, "got %d\n", ret );
3600 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3601 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3602 memset( data, 0xaa, sizeof(data) );
3604 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3605 ok( ret == 4, "got %d\n", ret );
3606 ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
3607 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3608 memset( data, 0xaa, sizeof(data) );
3610 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3611 ok( ret == 5, "got %d\n", ret );
3612 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3613 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3614 memset( data, 0xaa, sizeof(data) );
3616 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3617 ok( ret == 5, "got %d\n", ret );
3618 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3619 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3620 memset( data, 0xaa, sizeof(data) );
3622 info->bmiHeader.biHeight = -16;
3623 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3624 ok( ret == 8, "got %d\n", ret );
3625 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3626 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3627 memset( data, 0xaa, sizeof(data) );
3629 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3630 ok( ret == 5, "got %d\n", ret );
3631 ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
3632 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3633 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3634 memset( data, 0xaa, sizeof(data) );
3636 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3637 ok( ret == 8, "got %d\n", ret );
3638 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3639 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3640 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3641 memset( data, 0xaa, sizeof(data) );
3643 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3644 ok( ret == 8, "got %d\n", ret );
3645 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3646 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3647 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3648 memset( data, 0xaa, sizeof(data) );
3650 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3651 ok( ret == 7, "got %d\n", ret );
3652 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3653 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3654 memset( data, 0xaa, sizeof(data) );
3656 info->bmiHeader.biHeight = -5;
3657 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3658 ok( ret == 2, "got %d\n", ret );
3659 ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
3660 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3661 memset( data, 0xaa, sizeof(data) );
3666 info->bmiHeader.biHeight = 8;
3668 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3669 ok( ret == 8, "got %d\n", ret );
3670 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3671 memset( data, 0xaa, sizeof(data) );
3673 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3674 ok( ret == 5, "got %d\n", ret );
3675 ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
3676 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3677 memset( data, 0xaa, sizeof(data) );
3679 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3680 ok( ret == 7, "got %d\n", ret );
3681 ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
3682 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3683 memset( data, 0xaa, sizeof(data) );
3685 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3686 ok( ret == 1, "got %d\n", ret );
3687 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3688 memset( data, 0xaa, sizeof(data) );
3690 info->bmiHeader.biHeight = 16;
3691 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3692 ok( ret == 5, "got %d\n", ret );
3693 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3694 ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
3695 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3696 memset( data, 0xaa, sizeof(data) );
3698 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3699 ok( ret == 6, "got %d\n", ret );
3700 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3701 ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
3702 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3703 memset( data, 0xaa, sizeof(data) );
3705 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3706 ok( ret == 0, "got %d\n", ret );
3707 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3708 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3709 memset( data, 0xaa, sizeof(data) );
3711 info->bmiHeader.biHeight = 5;
3712 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3713 ok( ret == 2, "got %d\n", ret );
3714 ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
3715 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3716 memset( data, 0xaa, sizeof(data) );
3718 DeleteObject( dib );
3720 ReleaseDC( NULL, hdc );
3724 static void test_SetDIBits(void)
3726 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3727 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3729 HDC hdc = GetDC( NULL );
3730 DWORD data[128], inverted_data[128];
3734 memset( info, 0, sizeof(bmi_buf) );
3736 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3737 info->bmiHeader.biWidth = 8;
3738 info->bmiHeader.biHeight = 8;
3739 info->bmiHeader.biPlanes = 1;
3740 info->bmiHeader.biBitCount = 32;
3741 info->bmiHeader.biCompression = BI_RGB;
3743 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3744 memset( dib_bits, 0xaa, 64 * 4 );
3746 for (i = 0; i < 128; i++)
3749 inverted_data[120 - (i & ~7) + (i & 7)] = i;
3754 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3755 ok( ret == 8, "got %d\n", ret );
3756 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
3757 memset( dib_bits, 0xaa, 64 * 4 );
3759 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3760 ok( ret == 5, "got %d\n", ret );
3761 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3762 ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
3763 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3764 memset( dib_bits, 0xaa, 64 * 4 );
3766 /* top of dst is aligned with startscans down for the top of the src.
3767 Then starting from the bottom of src, lines rows are copied across. */
3769 info->bmiHeader.biHeight = 16;
3770 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3771 ok( ret == 12, "got %d\n", ret );
3772 ok( !memcmp( dib_bits, data + 56, 40 * 4 ), "bits differ\n");
3773 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3774 memset( dib_bits, 0xaa, 64 * 4 );
3776 info->bmiHeader.biHeight = 5;
3777 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3778 ok( ret == 2, "got %d\n", ret );
3779 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3780 ok( !memcmp( dib_bits + 32, data, 16 * 4 ), "bits differ\n");
3781 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3782 memset( dib_bits, 0xaa, 64 * 4 );
3785 info->bmiHeader.biHeight = -8;
3786 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3787 ok( ret == 8, "got %d\n", ret );
3788 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3789 memset( dib_bits, 0xaa, 64 * 4 );
3791 /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
3792 we copy lines rows from the top of the src */
3794 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3795 ok( ret == 5, "got %d\n", ret );
3796 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3797 ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
3798 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3799 memset( dib_bits, 0xaa, 64 * 4 );
3801 info->bmiHeader.biHeight = -16;
3802 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3803 ok( ret == 12, "got %d\n", ret );
3804 ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
3805 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3806 memset( dib_bits, 0xaa, 64 * 4 );
3808 ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3809 ok( ret == 12, "got %d\n", ret );
3810 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3811 memset( dib_bits, 0xaa, 64 * 4 );
3813 ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3814 ok( ret == 12, "got %d\n", ret );
3815 ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
3816 memset( dib_bits, 0xaa, 64 * 4 );
3818 info->bmiHeader.biHeight = -5;
3819 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3820 ok( ret == 2, "got %d\n", ret );
3821 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3822 ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
3823 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3824 memset( dib_bits, 0xaa, 64 * 4 );
3826 DeleteObject( dib );
3828 info->bmiHeader.biHeight = -8;
3830 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3831 memset( dib_bits, 0xaa, 16 * 16 * 4 );
3835 /* like the t-d -> b-u case. */
3837 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3838 ok( ret == 8, "got %d\n", ret );
3839 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
3840 memset( dib_bits, 0xaa, 64 * 4 );
3842 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3843 ok( ret == 5, "got %d\n", ret );
3844 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3845 ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
3846 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3847 memset( dib_bits, 0xaa, 64 * 4 );
3849 info->bmiHeader.biHeight = -16;
3850 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3851 ok( ret == 12, "got %d\n", ret );
3852 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3853 ok( !memcmp( dib_bits + 24, data, 40 * 4 ), "bits differ\n");
3854 memset( dib_bits, 0xaa, 64 * 4 );
3856 info->bmiHeader.biHeight = -5;
3857 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3858 ok( ret == 2, "got %d\n", ret );
3859 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3860 ok( !memcmp( dib_bits + 16, data, 16 * 4 ), "bits differ\n");
3861 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3862 memset( dib_bits, 0xaa, 64 * 4 );
3865 /* like the b-u -> b-u case */
3867 info->bmiHeader.biHeight = 8;
3868 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3869 ok( ret == 8, "got %d\n", ret );
3870 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3871 memset( dib_bits, 0xaa, 64 * 4 );
3873 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3874 ok( ret == 5, "got %d\n", ret );
3875 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3876 ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
3877 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3878 memset( dib_bits, 0xaa, 64 * 4 );
3880 info->bmiHeader.biHeight = 16;
3881 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3882 ok( ret == 12, "got %d\n", ret );
3883 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3884 ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
3885 memset( dib_bits, 0xaa, 64 * 4 );
3887 info->bmiHeader.biHeight = 5;
3888 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3889 ok( ret == 2, "got %d\n", ret );
3890 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3891 ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
3892 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3893 memset( dib_bits, 0xaa, 64 * 4 );
3895 DeleteObject( dib );
3896 ReleaseDC( NULL, hdc );
3899 static void test_SetDIBits_RLE4(void)
3901 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3902 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3904 HDC hdc = GetDC( NULL );
3905 BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00, /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
3906 0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
3907 0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00, /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
3908 0x00, 0x02, 0x01, 0x02, 0x05, 0x87, /* dx=1, dy=2, 8, 7, 8, 7, 8 */
3909 0x00, 0x01 }; /* <eod> */
3912 DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
3913 0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
3914 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3915 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3916 0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
3917 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3918 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3919 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
3921 memset( info, 0, sizeof(bmi_buf) );
3923 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3924 info->bmiHeader.biWidth = 8;
3925 info->bmiHeader.biHeight = 8;
3926 info->bmiHeader.biPlanes = 1;
3927 info->bmiHeader.biBitCount = 32;
3928 info->bmiHeader.biCompression = BI_RGB;
3930 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3931 memset( dib_bits, 0xaa, 64 * 4 );
3933 info->bmiHeader.biBitCount = 4;
3934 info->bmiHeader.biCompression = BI_RLE4;
3935 info->bmiHeader.biSizeImage = sizeof(rle4_data);
3937 for (i = 0; i < 16; i++)
3939 info->bmiColors[i].rgbRed = i;
3940 info->bmiColors[i].rgbGreen = i;
3941 info->bmiColors[i].rgbBlue = i;
3942 info->bmiColors[i].rgbReserved = 0;
3945 ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
3946 ok( ret == 8, "got %d\n", ret );
3947 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
3948 memset( dib_bits, 0xaa, 64 * 4 );
3950 DeleteObject( dib );
3951 ReleaseDC( NULL, hdc );
3954 static void test_SetDIBits_RLE8(void)
3956 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3957 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3959 HDC hdc = GetDC( NULL );
3960 BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00, /* 2, 2, 2, f0, f0, f0, f0, <eol> */
3961 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
3962 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
3963 0x00, 0x01 }; /* <eod> */
3966 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
3967 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3968 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3969 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
3970 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3971 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3972 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3973 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
3974 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3975 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3976 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3977 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3978 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
3979 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3980 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3981 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
3983 memset( info, 0, sizeof(bmi_buf) );
3985 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3986 info->bmiHeader.biWidth = 8;
3987 info->bmiHeader.biHeight = 8;
3988 info->bmiHeader.biPlanes = 1;
3989 info->bmiHeader.biBitCount = 32;
3990 info->bmiHeader.biCompression = BI_RGB;
3992 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3993 memset( dib_bits, 0xaa, 64 * 4 );
3995 info->bmiHeader.biBitCount = 8;
3996 info->bmiHeader.biCompression = BI_RLE8;
3997 info->bmiHeader.biSizeImage = sizeof(rle8_data);
3999 for (i = 0; i < 256; i++)
4001 info->bmiColors[i].rgbRed = i;
4002 info->bmiColors[i].rgbGreen = i;
4003 info->bmiColors[i].rgbBlue = i;
4004 info->bmiColors[i].rgbReserved = 0;
4007 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4008 ok( ret == 8, "got %d\n", ret );
4009 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4010 memset( dib_bits, 0xaa, 64 * 4 );
4012 /* startscan and lines are ignored, unless lines == 0 */
4013 ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4014 ok( ret == 8, "got %d\n", ret );
4015 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4016 memset( dib_bits, 0xaa, 64 * 4 );
4018 ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4019 ok( ret == 8, "got %d\n", ret );
4020 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4021 memset( dib_bits, 0xaa, 64 * 4 );
4023 ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4024 ok( ret == 0, "got %d\n", ret );
4025 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4026 memset( dib_bits, 0xaa, 64 * 4 );
4028 /* reduce width to 4, left-hand side of dst is touched. */
4029 info->bmiHeader.biWidth = 4;
4030 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4031 ok( ret == 8, "got %d\n", ret );
4032 for (i = 0; i < 64; i++)
4034 DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4035 ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4037 memset( dib_bits, 0xaa, 64 * 4 );
4039 /* Show that the top lines are aligned by adjusting the height of the src */
4041 /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4042 info->bmiHeader.biWidth = 8;
4043 info->bmiHeader.biHeight = 4;
4044 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4045 ok( ret == 4, "got %d\n", ret );
4046 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4047 ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4048 memset( dib_bits, 0xaa, 64 * 4 );
4050 /* increase the height to 9 -> everything moves down one row. */
4051 info->bmiHeader.biHeight = 9;
4052 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4053 ok( ret == 9, "got %d\n", ret );
4054 ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4055 for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4056 memset( dib_bits, 0xaa, 64 * 4 );
4058 /* top-down compressed dibs are invalid */
4059 info->bmiHeader.biHeight = -8;
4060 SetLastError( 0xdeadbeef );
4061 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4062 ok( ret == 0, "got %d\n", ret );
4063 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4064 DeleteObject( dib );
4068 info->bmiHeader.biHeight = -8;
4069 info->bmiHeader.biBitCount = 32;
4070 info->bmiHeader.biCompression = BI_RGB;
4071 info->bmiHeader.biSizeImage = 0;
4073 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4074 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4076 info->bmiHeader.biHeight = 8;
4077 info->bmiHeader.biBitCount = 8;
4078 info->bmiHeader.biCompression = BI_RLE8;
4079 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4081 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4082 ok( ret == 8, "got %d\n", ret );
4083 ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4084 memset( dib_bits, 0xaa, 64 * 4 );
4086 info->bmiHeader.biHeight = 4;
4087 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4088 ok( ret == 4, "got %d\n", ret );
4089 ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4090 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4091 memset( dib_bits, 0xaa, 64 * 4 );
4093 info->bmiHeader.biHeight = 9;
4094 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4095 ok( ret == 9, "got %d\n", ret );
4096 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4097 ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4098 memset( dib_bits, 0xaa, 64 * 4 );
4100 DeleteObject( dib );
4102 ReleaseDC( NULL, hdc );
4109 hdll = GetModuleHandle("gdi32.dll");
4110 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
4111 pSetLayout = (void*)GetProcAddress(hdll, "SetLayout");
4113 test_createdibitmap();
4116 test_mono_dibsection();
4119 test_GetDIBits_selected_DIB(1);
4120 test_GetDIBits_selected_DIB(4);
4121 test_GetDIBits_selected_DIB(8);
4122 test_GetDIBits_selected_DDB(TRUE);
4123 test_GetDIBits_selected_DDB(FALSE);
4125 test_GetDIBits_BI_BITFIELDS();
4126 test_select_object();
4127 test_CreateBitmap();
4130 test_StretchDIBits();
4131 test_GdiAlphaBlend();
4132 test_32bit_bitmap_blt();
4133 test_bitmapinfoheadersize();
4136 test_GetDIBits_top_down(16);
4137 test_GetDIBits_top_down(24);
4138 test_GetDIBits_top_down(32);
4139 test_GetSetDIBits_rtl();
4140 test_GetDIBits_scanlines();
4142 test_SetDIBits_RLE4();
4143 test_SetDIBits_RLE8();