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 )
258 return ((width * bpp + 31) / 8) & ~3;
261 static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
267 INT ret, bm_width_bytes, dib_width_bytes;
270 ret = GetObject(hbm, sizeof(bm), &bm);
271 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
273 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
274 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
275 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
276 dib_width_bytes = DIB_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
277 bm_width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
278 if (bm.bmWidthBytes != dib_width_bytes) /* Win2k bug */
279 ok(bm.bmWidthBytes == bm_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, bm_width_bytes);
281 ok(bm.bmWidthBytes == dib_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, dib_width_bytes);
282 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
283 ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount);
284 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
286 buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);
288 /* GetBitmapBits returns not 32-bit aligned data */
289 SetLastError(0xdeadbeef);
290 ret = GetBitmapBits(hbm, 0, NULL);
291 ok(ret == bm_width_bytes * bm.bmHeight,
292 "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
294 memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
295 ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
296 ok(ret == bm_width_bytes * bm.bmHeight, "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
298 HeapFree(GetProcessHeap(), 0, buf);
300 /* test various buffer sizes for GetObject */
301 memset(&ds, 0xAA, sizeof(ds));
302 ret = GetObject(hbm, sizeof(*bma) * 2, bma);
303 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
304 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
305 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
306 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
308 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
309 ok(ret == 0, "%d != 0\n", ret);
311 ret = GetObject(hbm, 0, &bm);
312 ok(ret == 0, "%d != 0\n", ret);
314 ret = GetObject(hbm, 1, &bm);
315 ok(ret == 0, "%d != 0\n", ret);
317 /* test various buffer sizes for GetObject */
318 ret = GetObject(hbm, 0, NULL);
319 ok(ret == sizeof(bm), "wrong size %d\n", ret);
321 ret = GetObject(hbm, sizeof(*dsa) * 2, dsa);
322 ok(ret == sizeof(*dsa), "wrong size %d\n", ret);
324 memset(&ds, 0xAA, sizeof(ds));
325 ret = GetObject(hbm, sizeof(ds), &ds);
326 ok(ret == sizeof(ds), "wrong size %d\n", ret);
328 ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
329 if (ds.dsBm.bmWidthBytes != bm_width_bytes) /* Win2k bug */
330 ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%u != %u\n",
331 ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
332 ok(bmih->biSizeImage == 0, "%u != 0\n", bmih->biSizeImage);
333 ds.dsBmih.biSizeImage = 0;
335 ok(ds.dsBmih.biSize == bmih->biSize, "%u != %u\n", ds.dsBmih.biSize, bmih->biSize);
336 ok(ds.dsBmih.biWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
337 ok(ds.dsBmih.biHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
338 ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes);
339 ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount);
340 ok(ds.dsBmih.biCompression == bmih->biCompression ||
341 ((bmih->biBitCount == 32) && broken(ds.dsBmih.biCompression == BI_BITFIELDS)), /* nt4 sp1 and 2 */
342 "%u != %u\n", ds.dsBmih.biCompression, bmih->biCompression);
343 ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%u != %u\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
344 ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%d != %d\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
345 ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%d != %d\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);
347 memset(&ds, 0xAA, sizeof(ds));
348 ret = GetObject(hbm, sizeof(ds) - 4, &ds);
349 ok(ret == sizeof(ds.dsBm), "wrong size %d\n", ret);
350 ok(ds.dsBm.bmWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
351 ok(ds.dsBm.bmHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
352 ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);
354 ret = GetObject(hbm, 0, &ds);
355 ok(ret == 0, "%d != 0\n", ret);
357 ret = GetObject(hbm, 1, &ds);
358 ok(ret == 0, "%d != 0\n", ret);
361 #define test_color_todo(got, exp, txt, todo) \
362 if (!todo && got != exp && screen_depth < 24) { \
363 todo_wine ok(0, #txt " failed at %d-bit screen depth: got 0x%06x expected 0x%06x - skipping DIB tests\n", \
364 screen_depth, (UINT)got, (UINT)exp); \
366 } else if (todo) todo_wine { ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp); } \
367 else ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp) \
369 #define test_color(hdc, color, exp, todo_setp, todo_getp) \
372 c = SetPixel(hdc, 0, 0, color); \
373 test_color_todo(c, exp, SetPixel, todo_setp); \
374 c = GetPixel(hdc, 0, 0); \
375 test_color_todo(c, exp, GetPixel, todo_getp); \
378 static void test_dib_bits_access( HBITMAP hdib, void *bits )
380 MEMORY_BASIC_INFORMATION info;
381 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
383 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
385 char filename[MAX_PATH];
390 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
391 "VirtualQuery failed\n");
392 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
393 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
394 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
395 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
396 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
397 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
399 memset( pbmi, 0, sizeof(bmibuf) );
400 memset( data, 0xcc, sizeof(data) );
401 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
402 pbmi->bmiHeader.biHeight = 16;
403 pbmi->bmiHeader.biWidth = 16;
404 pbmi->bmiHeader.biBitCount = 32;
405 pbmi->bmiHeader.biPlanes = 1;
406 pbmi->bmiHeader.biCompression = BI_RGB;
410 ret = SetDIBits( hdc, hdib, 0, 16, data, pbmi, DIB_RGB_COLORS );
411 ok(ret == 16, "SetDIBits failed: expected 16 got %d\n", ret);
415 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
416 "VirtualQuery failed\n");
417 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
418 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
419 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
420 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
421 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
422 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
424 /* try writing protected bits to a file */
426 GetTempFileNameA( ".", "dib", 0, filename );
427 file = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
428 CREATE_ALWAYS, 0, 0 );
429 ok( file != INVALID_HANDLE_VALUE, "failed to open %s error %u\n", filename, GetLastError() );
430 ret = WriteFile( file, bits, 8192, &written, NULL );
431 ok( ret, "WriteFile failed error %u\n", GetLastError() );
432 if (ret) ok( written == 8192, "only wrote %u bytes\n", written );
434 DeleteFileA( filename );
437 static void test_dibsections(void)
439 HDC hdc, hdcmem, hdcmem2;
440 HBITMAP hdib, oldbm, hdib2, oldbm2;
441 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
442 char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
443 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
444 BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
450 char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
451 LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
454 HPALETTE hpal, oldpal;
459 MEMORY_BASIC_INFORMATION info;
462 screen_depth = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
464 memset(pbmi, 0, sizeof(bmibuf));
465 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
466 pbmi->bmiHeader.biHeight = 100;
467 pbmi->bmiHeader.biWidth = 512;
468 pbmi->bmiHeader.biBitCount = 24;
469 pbmi->bmiHeader.biPlanes = 1;
470 pbmi->bmiHeader.biCompression = BI_RGB;
472 SetLastError(0xdeadbeef);
474 /* invalid pointer for BITMAPINFO
475 (*bits should be NULL on error) */
476 bits = (BYTE*)0xdeadbeef;
477 hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
478 ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n");
480 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
481 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
482 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
483 ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
485 /* test the DIB memory */
486 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
487 "VirtualQuery failed\n");
488 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
489 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
490 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
491 ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
492 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
493 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
494 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
496 test_dib_bits_access( hdib, bits );
498 test_dib_info(hdib, bits, &pbmi->bmiHeader);
501 /* Test a top-down DIB. */
502 pbmi->bmiHeader.biHeight = -100;
503 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
504 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
505 test_dib_info(hdib, bits, &pbmi->bmiHeader);
508 pbmi->bmiHeader.biHeight = 100;
509 pbmi->bmiHeader.biBitCount = 8;
510 pbmi->bmiHeader.biCompression = BI_RLE8;
511 SetLastError(0xdeadbeef);
512 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
513 ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
514 ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
516 pbmi->bmiHeader.biBitCount = 16;
517 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
518 ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
519 ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
520 ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
521 SetLastError(0xdeadbeef);
522 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
523 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
525 /* test the DIB memory */
526 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
527 "VirtualQuery failed\n");
528 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
529 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
530 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
531 ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
532 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
533 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
534 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
536 test_dib_info(hdib, bits, &pbmi->bmiHeader);
539 memset(pbmi, 0, sizeof(bmibuf));
540 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
541 pbmi->bmiHeader.biHeight = 16;
542 pbmi->bmiHeader.biWidth = 16;
543 pbmi->bmiHeader.biBitCount = 1;
544 pbmi->bmiHeader.biPlanes = 1;
545 pbmi->bmiHeader.biCompression = BI_RGB;
546 pbmi->bmiColors[0].rgbRed = 0xff;
547 pbmi->bmiColors[0].rgbGreen = 0;
548 pbmi->bmiColors[0].rgbBlue = 0;
549 pbmi->bmiColors[1].rgbRed = 0;
550 pbmi->bmiColors[1].rgbGreen = 0;
551 pbmi->bmiColors[1].rgbBlue = 0xff;
553 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
554 ok(hdib != NULL, "CreateDIBSection failed\n");
555 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
556 ok(dibsec.dsBmih.biClrUsed == 2,
557 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
559 /* Test if the old BITMAPCOREINFO structure is supported */
561 pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
562 pbci->bmciHeader.bcBitCount = 0;
564 ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
565 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
566 ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
567 && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
568 "GetDIBits didn't fill in the BITMAPCOREHEADER structure properly\n");
570 ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
571 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
572 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
573 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
574 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
575 "The color table has not been translated to the old BITMAPCOREINFO format\n");
577 hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
578 ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
580 ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
581 ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
582 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
583 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
584 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
585 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
586 "The color table has not been translated to the old BITMAPCOREINFO format\n");
588 DeleteObject(hcoredib);
590 hdcmem = CreateCompatibleDC(hdc);
591 oldbm = SelectObject(hdcmem, hdib);
593 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
594 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
595 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
596 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
597 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
598 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
600 c0 = RGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen, pbmi->bmiColors[0].rgbBlue);
601 c1 = RGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen, pbmi->bmiColors[1].rgbBlue);
603 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
604 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
605 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
606 test_color(hdcmem, PALETTEINDEX(0), c0, 1, 1);
607 test_color(hdcmem, PALETTEINDEX(1), c0, 1, 1);
608 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
609 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen,
610 pbmi->bmiColors[0].rgbBlue), c0, 1, 1);
611 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen,
612 pbmi->bmiColors[1].rgbBlue), c1, 1, 1);
613 test_color(hdcmem, PALETTERGB(0, 0, 0), c0, 1, 1);
614 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
615 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1, 1, 1);
617 SelectObject(hdcmem, oldbm);
620 pbmi->bmiColors[0].rgbRed = 0xff;
621 pbmi->bmiColors[0].rgbGreen = 0xff;
622 pbmi->bmiColors[0].rgbBlue = 0xff;
623 pbmi->bmiColors[1].rgbRed = 0;
624 pbmi->bmiColors[1].rgbGreen = 0;
625 pbmi->bmiColors[1].rgbBlue = 0;
627 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
628 ok(hdib != NULL, "CreateDIBSection failed\n");
630 test_dib_info(hdib, bits, &pbmi->bmiHeader);
632 oldbm = SelectObject(hdcmem, hdib);
634 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
635 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
636 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
637 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
638 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
639 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
641 SelectObject(hdcmem, oldbm);
642 test_dib_info(hdib, bits, &pbmi->bmiHeader);
645 pbmi->bmiHeader.biBitCount = 4;
646 for (i = 0; i < 16; i++) {
647 pbmi->bmiColors[i].rgbRed = i;
648 pbmi->bmiColors[i].rgbGreen = 16-i;
649 pbmi->bmiColors[i].rgbBlue = 0;
651 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
652 ok(hdib != NULL, "CreateDIBSection failed\n");
653 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
654 ok(dibsec.dsBmih.biClrUsed == 16,
655 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
656 test_dib_info(hdib, bits, &pbmi->bmiHeader);
659 pbmi->bmiHeader.biBitCount = 8;
661 for (i = 0; i < 128; i++) {
662 pbmi->bmiColors[i].rgbRed = 255 - i * 2;
663 pbmi->bmiColors[i].rgbGreen = i * 2;
664 pbmi->bmiColors[i].rgbBlue = 0;
665 pbmi->bmiColors[255 - i].rgbRed = 0;
666 pbmi->bmiColors[255 - i].rgbGreen = i * 2;
667 pbmi->bmiColors[255 - i].rgbBlue = 255 - i * 2;
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 == 256,
673 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
675 oldbm = SelectObject(hdcmem, hdib);
677 for (i = 0; i < 256; i++) {
678 test_color(hdcmem, DIBINDEX(i),
679 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
680 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue),
681 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
684 SelectObject(hdcmem, oldbm);
685 test_dib_info(hdib, bits, &pbmi->bmiHeader);
688 pbmi->bmiHeader.biBitCount = 1;
690 /* Now create a palette and a palette indexed dib section */
691 memset(plogpal, 0, sizeof(logpalbuf));
692 plogpal->palVersion = 0x300;
693 plogpal->palNumEntries = 2;
694 plogpal->palPalEntry[0].peRed = 0xff;
695 plogpal->palPalEntry[0].peBlue = 0xff;
696 plogpal->palPalEntry[1].peGreen = 0xff;
698 index = (WORD*)pbmi->bmiColors;
701 hpal = CreatePalette(plogpal);
702 ok(hpal != NULL, "CreatePalette failed\n");
703 oldpal = SelectPalette(hdc, hpal, TRUE);
704 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
705 ok(hdib != NULL, "CreateDIBSection failed\n");
706 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
707 ok(dibsec.dsBmih.biClrUsed == 2, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
709 /* The colour table has already been grabbed from the dc, so we select back the
712 SelectPalette(hdc, oldpal, TRUE);
713 oldbm = SelectObject(hdcmem, hdib);
714 oldpal = SelectPalette(hdcmem, hpal, TRUE);
716 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
717 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
718 ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
719 rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
720 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
721 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
722 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
724 c0 = RGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen, plogpal->palPalEntry[0].peBlue);
725 c1 = RGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen, plogpal->palPalEntry[1].peBlue);
727 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
728 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
729 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
730 test_color(hdcmem, PALETTEINDEX(0), c0, 0, 1);
731 test_color(hdcmem, PALETTEINDEX(1), c1, 0, 1);
732 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
733 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen,
734 plogpal->palPalEntry[0].peBlue), c0, 1, 1);
735 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen,
736 plogpal->palPalEntry[1].peBlue), c1, 1, 1);
737 test_color(hdcmem, PALETTERGB(0, 0, 0), c1, 1, 1);
738 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
739 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0, 1, 1);
740 test_color(hdcmem, PALETTERGB(0, 1, 0), c1, 1, 1);
741 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1, 1, 1);
742 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0, 1, 1);
744 /* Bottom and 2nd row from top green, everything else magenta */
745 bits[0] = bits[1] = 0xff;
746 bits[13 * 4] = bits[13*4 + 1] = 0xff;
748 test_dib_info(hdib, bits, &pbmi->bmiHeader);
750 pbmi->bmiHeader.biBitCount = 32;
752 hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
753 ok(hdib2 != NULL, "CreateDIBSection failed\n");
754 hdcmem2 = CreateCompatibleDC(hdc);
755 oldbm2 = SelectObject(hdcmem2, hdib2);
757 BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
759 ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
760 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
762 SelectObject(hdcmem2, oldbm2);
763 test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
766 SelectObject(hdcmem, oldbm);
767 SelectPalette(hdcmem, oldpal, TRUE);
772 pbmi->bmiHeader.biBitCount = 8;
774 memset(plogpal, 0, sizeof(logpalbuf));
775 plogpal->palVersion = 0x300;
776 plogpal->palNumEntries = 256;
778 for (i = 0; i < 128; i++) {
779 plogpal->palPalEntry[i].peRed = 255 - i * 2;
780 plogpal->palPalEntry[i].peBlue = i * 2;
781 plogpal->palPalEntry[i].peGreen = 0;
782 plogpal->palPalEntry[255 - i].peRed = 0;
783 plogpal->palPalEntry[255 - i].peGreen = i * 2;
784 plogpal->palPalEntry[255 - i].peBlue = 255 - i * 2;
787 index = (WORD*)pbmi->bmiColors;
788 for (i = 0; i < 256; i++) {
792 hpal = CreatePalette(plogpal);
793 ok(hpal != NULL, "CreatePalette failed\n");
794 oldpal = SelectPalette(hdc, hpal, TRUE);
795 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
796 ok(hdib != NULL, "CreateDIBSection failed\n");
797 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
798 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
800 test_dib_info(hdib, bits, &pbmi->bmiHeader);
802 SelectPalette(hdc, oldpal, TRUE);
803 oldbm = SelectObject(hdcmem, hdib);
804 oldpal = SelectPalette(hdcmem, hpal, TRUE);
806 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
807 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
808 for (i = 0; i < 256; i++) {
809 ok(rgb[i].rgbRed == plogpal->palPalEntry[i].peRed &&
810 rgb[i].rgbBlue == plogpal->palPalEntry[i].peBlue &&
811 rgb[i].rgbGreen == plogpal->palPalEntry[i].peGreen,
812 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
813 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
816 for (i = 0; i < 256; i++) {
817 test_color(hdcmem, DIBINDEX(i),
818 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
819 test_color(hdcmem, PALETTEINDEX(i),
820 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
821 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue),
822 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
825 SelectPalette(hdcmem, oldpal, TRUE);
826 SelectObject(hdcmem, oldbm);
835 static void test_dib_formats(void)
837 char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256])];
838 BITMAPINFO *bi = (BITMAPINFO *)buffer;
841 int planes, bpp, compr;
845 BOOL expect_ok, todo;
848 memdc = CreateCompatibleDC( 0 );
849 hbmp = CreateCompatibleBitmap( hdc, 10, 10 );
851 memset( data, 0xaa, sizeof(data) );
853 for (bpp = 0; bpp <= 64; bpp++)
855 for (planes = 0; planes <= 64; planes++)
857 for (compr = 0; compr < 8; compr++)
864 case 24: expect_ok = (compr == BI_RGB); break;
866 case 32: expect_ok = (compr == BI_RGB || compr == BI_BITFIELDS); break;
867 default: expect_ok = FALSE; break;
869 todo = (compr == BI_BITFIELDS); /* wine doesn't like strange bitfields */
871 memset( bi, 0, sizeof(bi->bmiHeader) );
872 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
873 bi->bmiHeader.biWidth = 2;
874 bi->bmiHeader.biHeight = 2;
875 bi->bmiHeader.biPlanes = planes;
876 bi->bmiHeader.biBitCount = bpp;
877 bi->bmiHeader.biCompression = compr;
878 bi->bmiHeader.biSizeImage = 0;
879 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
880 ret = GetDIBits(hdc, hbmp, 0, 0, data, bi, DIB_RGB_COLORS);
881 if (expect_ok || (!bpp && compr != BI_JPEG && compr != BI_PNG) ||
882 (bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8))
883 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
885 ok( !ret || broken(!bpp && (compr == BI_JPEG || compr == BI_PNG)), /* nt4 */
886 "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
888 /* all functions check planes except GetDIBits with 0 lines */
889 if (!planes) expect_ok = FALSE;
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 );
934 todo_wine ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
936 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
940 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
941 "SetDIBitsToDevice succeeded for %u/%u/%u\n", bpp, planes, compr );
942 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
946 todo_wine ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
948 ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
952 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
953 "StretchDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
955 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
957 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
959 ok( !ret, "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
960 ok( bi->bmiHeader.biBitCount == bpp, "GetDIBits modified bpp %u/%u\n",
961 bpp, bi->bmiHeader.biBitCount );
963 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
964 bi->bmiHeader.biWidth = 2;
965 bi->bmiHeader.biHeight = 2;
966 bi->bmiHeader.biPlanes = planes;
967 bi->bmiHeader.biBitCount = bpp;
968 bi->bmiHeader.biCompression = compr;
969 bi->bmiHeader.biSizeImage = 1;
970 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
971 /* RLE allowed with valid biSizeImage */
972 if ((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)) expect_ok = TRUE;
974 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
978 todo_wine ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
980 ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
983 ok( !ret, "SetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
984 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
988 todo_wine ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
990 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
993 ok( !ret, "SetDIBitsToDevice succeeded for %u/%u/%u\n", bpp, planes, compr );
994 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
998 todo_wine ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
1000 ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
1003 ok( !ret, "StretchDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
1005 bi->bmiHeader.biSizeImage = 0;
1006 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1007 if (expect_ok || !bpp)
1008 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
1010 ok( !ret, "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
1015 memset( bi, 0, sizeof(bi->bmiHeader) );
1016 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1017 bi->bmiHeader.biWidth = 2;
1018 bi->bmiHeader.biHeight = 2;
1019 bi->bmiHeader.biPlanes = 1;
1020 bi->bmiHeader.biBitCount = 16;
1021 bi->bmiHeader.biCompression = BI_BITFIELDS;
1022 bi->bmiHeader.biSizeImage = 0;
1023 *(DWORD *)&bi->bmiColors[0] = 0;
1024 *(DWORD *)&bi->bmiColors[1] = 0;
1025 *(DWORD *)&bi->bmiColors[2] = 0;
1027 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1028 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1029 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1030 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1031 /* other functions don't check */
1032 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1033 ok( hdib != NULL, "CreateDIBitmap failed with null bitfields\n" );
1034 DeleteObject( hdib );
1035 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1036 todo_wine ok( ret, "SetDIBitsToDevice failed with null bitfields\n" );
1037 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1038 todo_wine ok( ret, "StretchDIBits failed with null bitfields\n" );
1039 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1040 ok( ret, "GetDIBits failed with null bitfields\n" );
1041 bi->bmiHeader.biPlanes = 1;
1042 bi->bmiHeader.biBitCount = 16;
1043 bi->bmiHeader.biCompression = BI_BITFIELDS;
1044 bi->bmiHeader.biSizeImage = 0;
1045 *(DWORD *)&bi->bmiColors[0] = 0;
1046 *(DWORD *)&bi->bmiColors[1] = 0;
1047 *(DWORD *)&bi->bmiColors[2] = 0;
1048 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1049 ok( ret, "GetDIBits failed with null bitfields\n" );
1051 /* all fields must be non-zero */
1052 *(DWORD *)&bi->bmiColors[0] = 3;
1053 *(DWORD *)&bi->bmiColors[1] = 0;
1054 *(DWORD *)&bi->bmiColors[2] = 7;
1055 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1056 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1057 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1058 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1060 /* garbage is ok though */
1061 *(DWORD *)&bi->bmiColors[0] = 0x55;
1062 *(DWORD *)&bi->bmiColors[1] = 0x44;
1063 *(DWORD *)&bi->bmiColors[2] = 0x33;
1064 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1065 ok( hdib != NULL, "CreateDIBSection failed with bad bitfields\n" );
1066 if (hdib) DeleteObject( hdib );
1067 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1068 todo_wine ok( ret, "SetDIBits failed with bad bitfields\n" );
1070 bi->bmiHeader.biWidth = -2;
1071 bi->bmiHeader.biHeight = 2;
1072 bi->bmiHeader.biBitCount = 32;
1073 bi->bmiHeader.biCompression = BI_RGB;
1074 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1075 ok( hdib == NULL, "CreateDIBSection succeeded with negative width\n" );
1076 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1077 ok( hdib == NULL, "CreateDIBitmap succeeded with negative width\n" );
1078 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1079 ok( !ret, "SetDIBits succeeded with negative width\n" );
1080 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1081 ok( !ret, "SetDIBitsToDevice succeeded with negative width\n" );
1082 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1083 ok( !ret, "StretchDIBits succeeded with negative width\n" );
1084 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1085 ok( !ret, "GetDIBits succeeded with negative width\n" );
1086 bi->bmiHeader.biWidth = -2;
1087 bi->bmiHeader.biHeight = 2;
1088 bi->bmiHeader.biBitCount = 32;
1089 bi->bmiHeader.biCompression = BI_RGB;
1090 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1091 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with negative width\n" );
1093 bi->bmiHeader.biWidth = 0;
1094 bi->bmiHeader.biHeight = 2;
1095 bi->bmiHeader.biBitCount = 32;
1096 bi->bmiHeader.biCompression = BI_RGB;
1097 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1098 ok( hdib == NULL, "CreateDIBSection succeeded with zero width\n" );
1099 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1100 ok( hdib != NULL, "CreateDIBitmap failed with zero width\n" );
1101 DeleteObject( hdib );
1102 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1103 ok( !ret || broken(ret), /* nt4 */ "SetDIBits succeeded with zero width\n" );
1104 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1105 ok( !ret || broken(ret), /* nt4 */ "SetDIBitsToDevice succeeded with zero width\n" );
1106 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1107 ok( !ret || broken(ret), /* nt4 */ "StretchDIBits succeeded with zero width\n" );
1108 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1109 ok( !ret, "GetDIBits succeeded with zero width\n" );
1110 bi->bmiHeader.biWidth = 0;
1111 bi->bmiHeader.biHeight = 2;
1112 bi->bmiHeader.biBitCount = 32;
1113 bi->bmiHeader.biCompression = BI_RGB;
1114 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1115 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero width\n" );
1117 bi->bmiHeader.biWidth = 2;
1118 bi->bmiHeader.biHeight = 0;
1119 bi->bmiHeader.biBitCount = 32;
1120 bi->bmiHeader.biCompression = BI_RGB;
1121 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1122 ok( hdib == NULL, "CreateDIBSection succeeded with zero height\n" );
1123 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1124 ok( hdib != NULL, "CreateDIBitmap failed with zero height\n" );
1125 DeleteObject( hdib );
1126 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1127 ok( !ret, "SetDIBits succeeded with zero height\n" );
1128 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1129 ok( !ret, "SetDIBitsToDevice succeeded with zero height\n" );
1130 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1131 ok( !ret, "StretchDIBits succeeded with zero height\n" );
1132 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1133 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1134 bi->bmiHeader.biWidth = 2;
1135 bi->bmiHeader.biHeight = 0;
1136 bi->bmiHeader.biBitCount = 32;
1137 bi->bmiHeader.biCompression = BI_RGB;
1138 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1139 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1142 DeleteObject( hbmp );
1143 ReleaseDC( 0, hdc );
1146 static void test_mono_dibsection(void)
1149 HBITMAP old_bm, mono_ds;
1150 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
1151 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
1158 memdc = CreateCompatibleDC(hdc);
1160 memset(pbmi, 0, sizeof(bmibuf));
1161 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
1162 pbmi->bmiHeader.biHeight = 10;
1163 pbmi->bmiHeader.biWidth = 10;
1164 pbmi->bmiHeader.biBitCount = 1;
1165 pbmi->bmiHeader.biPlanes = 1;
1166 pbmi->bmiHeader.biCompression = BI_RGB;
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;
1175 * First dib section is 'inverted' ie color[0] is white, color[1] is black
1178 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1179 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1180 old_bm = SelectObject(memdc, mono_ds);
1182 /* black border, white interior */
1183 Rectangle(memdc, 0, 0, 10, 10);
1184 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1185 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1187 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1189 memset(bits, 0, sizeof(bits));
1192 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1193 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1195 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1197 pbmi->bmiColors[0].rgbRed = 0x0;
1198 pbmi->bmiColors[0].rgbGreen = 0x0;
1199 pbmi->bmiColors[0].rgbBlue = 0x0;
1200 pbmi->bmiColors[1].rgbRed = 0xff;
1201 pbmi->bmiColors[1].rgbGreen = 0xff;
1202 pbmi->bmiColors[1].rgbBlue = 0xff;
1204 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1205 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1207 SelectObject(memdc, old_bm);
1208 DeleteObject(mono_ds);
1211 * Next dib section is 'normal' ie color[0] is black, color[1] is white
1214 pbmi->bmiColors[0].rgbRed = 0x0;
1215 pbmi->bmiColors[0].rgbGreen = 0x0;
1216 pbmi->bmiColors[0].rgbBlue = 0x0;
1217 pbmi->bmiColors[1].rgbRed = 0xff;
1218 pbmi->bmiColors[1].rgbGreen = 0xff;
1219 pbmi->bmiColors[1].rgbBlue = 0xff;
1221 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1222 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1223 old_bm = SelectObject(memdc, mono_ds);
1225 /* black border, white interior */
1226 Rectangle(memdc, 0, 0, 10, 10);
1227 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
1228 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
1230 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
1232 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1233 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1235 /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
1237 pbmi->bmiColors[0].rgbRed = 0xff;
1238 pbmi->bmiColors[0].rgbGreen = 0xff;
1239 pbmi->bmiColors[0].rgbBlue = 0xff;
1240 pbmi->bmiColors[1].rgbRed = 0x0;
1241 pbmi->bmiColors[1].rgbGreen = 0x0;
1242 pbmi->bmiColors[1].rgbBlue = 0x0;
1244 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1245 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1248 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
1251 pbmi->bmiColors[0].rgbRed = 0xff;
1252 pbmi->bmiColors[0].rgbGreen = 0xff;
1253 pbmi->bmiColors[0].rgbBlue = 0xff;
1254 pbmi->bmiColors[1].rgbRed = 0x0;
1255 pbmi->bmiColors[1].rgbGreen = 0x0;
1256 pbmi->bmiColors[1].rgbBlue = 0x0;
1257 num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors);
1258 ok(num == 2, "num = %d\n", num);
1260 /* black border, white interior */
1261 Rectangle(memdc, 0, 0, 10, 10);
1262 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1263 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1265 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1267 memset(bits, 0, sizeof(bits));
1270 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1271 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1273 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1275 pbmi->bmiColors[0].rgbRed = 0x0;
1276 pbmi->bmiColors[0].rgbGreen = 0x0;
1277 pbmi->bmiColors[0].rgbBlue = 0x0;
1278 pbmi->bmiColors[1].rgbRed = 0xff;
1279 pbmi->bmiColors[1].rgbGreen = 0xff;
1280 pbmi->bmiColors[1].rgbBlue = 0xff;
1282 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1283 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1285 SelectObject(memdc, old_bm);
1286 DeleteObject(mono_ds);
1289 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
1292 pbmi->bmiColors[0].rgbRed = 0xff;
1293 pbmi->bmiColors[0].rgbGreen = 0x0;
1294 pbmi->bmiColors[0].rgbBlue = 0x0;
1295 pbmi->bmiColors[1].rgbRed = 0xfe;
1296 pbmi->bmiColors[1].rgbGreen = 0x0;
1297 pbmi->bmiColors[1].rgbBlue = 0x0;
1299 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1300 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1301 old_bm = SelectObject(memdc, mono_ds);
1303 /* black border, white interior */
1304 Rectangle(memdc, 0, 0, 10, 10);
1305 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1306 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1308 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1310 pbmi->bmiColors[0].rgbRed = 0x0;
1311 pbmi->bmiColors[0].rgbGreen = 0x0;
1312 pbmi->bmiColors[0].rgbBlue = 0x0;
1313 pbmi->bmiColors[1].rgbRed = 0xff;
1314 pbmi->bmiColors[1].rgbGreen = 0xff;
1315 pbmi->bmiColors[1].rgbBlue = 0xff;
1317 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1318 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1320 /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
1322 pbmi->bmiColors[0].rgbRed = 0xff;
1323 pbmi->bmiColors[0].rgbGreen = 0xff;
1324 pbmi->bmiColors[0].rgbBlue = 0xff;
1325 pbmi->bmiColors[1].rgbRed = 0x0;
1326 pbmi->bmiColors[1].rgbGreen = 0x0;
1327 pbmi->bmiColors[1].rgbBlue = 0x0;
1329 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1330 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1332 SelectObject(memdc, old_bm);
1333 DeleteObject(mono_ds);
1339 static void test_bitmap(void)
1341 char buf[256], buf_cmp[256];
1342 HBITMAP hbmp, hbmp_old;
1348 hdc = CreateCompatibleDC(0);
1351 SetLastError(0xdeadbeef);
1352 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1355 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1356 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1357 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1362 SetLastError(0xdeadbeef);
1363 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1366 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1367 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1368 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1373 SetLastError(0xdeadbeef);
1374 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1375 ok(!hbmp, "CreateBitmap should fail\n");
1377 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1378 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1382 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1383 assert(hbmp != NULL);
1385 ret = GetObject(hbmp, sizeof(bm), &bm);
1386 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1388 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1389 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1390 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1391 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1392 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1393 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1394 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1396 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1397 assert(sizeof(buf) == sizeof(buf_cmp));
1399 ret = GetBitmapBits(hbmp, 0, NULL);
1400 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1402 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1403 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1405 memset(buf, 0xAA, sizeof(buf));
1406 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1407 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1408 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1410 hbmp_old = SelectObject(hdc, hbmp);
1412 ret = GetObject(hbmp, sizeof(bm), &bm);
1413 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1415 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1416 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1417 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1418 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1419 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1420 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1421 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1423 memset(buf, 0xAA, sizeof(buf));
1424 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1425 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1426 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1428 hbmp_old = SelectObject(hdc, hbmp_old);
1429 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1431 /* test various buffer sizes for GetObject */
1432 ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
1433 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1435 ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1436 ok(ret == 0, "%d != 0\n", ret);
1438 ret = GetObject(hbmp, 0, &bm);
1439 ok(ret == 0, "%d != 0\n", ret);
1441 ret = GetObject(hbmp, 1, &bm);
1442 ok(ret == 0, "%d != 0\n", ret);
1448 static void test_bmBits(void)
1454 memset(bits, 0, sizeof(bits));
1455 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1456 ok(hbmp != NULL, "CreateBitmap failed\n");
1458 memset(&bmp, 0xFF, sizeof(bmp));
1459 ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1460 "GetObject failed or returned a wrong structure size\n");
1461 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1466 static void test_GetDIBits_selected_DIB(UINT bpp)
1469 char bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1470 char bmibuf2[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1471 BITMAPINFO *info = (BITMAPINFO *)bmibuf;
1472 BITMAPINFO *info2 = (BITMAPINFO *)bmibuf2;
1475 UINT dib_size, dib32_size;
1482 /* Create a DIB section with a color table */
1484 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1485 info->bmiHeader.biWidth = 32;
1486 info->bmiHeader.biHeight = 32;
1487 info->bmiHeader.biPlanes = 1;
1488 info->bmiHeader.biBitCount = bpp;
1489 info->bmiHeader.biCompression = BI_RGB;
1490 info->bmiHeader.biXPelsPerMeter = 0;
1491 info->bmiHeader.biYPelsPerMeter = 0;
1492 info->bmiHeader.biClrUsed = 0;
1493 info->bmiHeader.biClrImportant = 0;
1495 for (i=0; i < (1u << bpp); i++)
1497 BYTE c = i * (1 << (8 - bpp));
1498 info->bmiColors[i].rgbRed = c;
1499 info->bmiColors[i].rgbGreen = c;
1500 info->bmiColors[i].rgbBlue = c;
1501 info->bmiColors[i].rgbReserved = 0;
1504 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1505 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1506 dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1508 /* Set the bits of the DIB section */
1509 for (i=0; i < dib_size; i++)
1511 ((BYTE *)bits)[i] = i % 256;
1514 /* Select the DIB into a DC */
1515 dib_dc = CreateCompatibleDC(NULL);
1516 old_bmp = SelectObject(dib_dc, dib);
1517 dc = CreateCompatibleDC(NULL);
1518 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
1520 /* Copy the DIB attributes but not the color table */
1521 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1523 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1524 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1526 /* Compare the color table and the bits */
1527 for (i=0; i < (1u << bpp); i++)
1528 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1529 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1530 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1531 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1532 "color table entry %d differs (bpp %d)\n", i, bpp );
1534 ok( !memcmp( bits, bits2, dib_size ), "bit mismatch (bpp %d)\n", bpp );
1536 /* Test various combinations of lines = 0 and bits2 = NULL */
1537 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1538 res = GetDIBits( dc, dib, 0, 0, bits2, info2, DIB_RGB_COLORS );
1539 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1540 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1541 "color table mismatch (bpp %d)\n", bpp );
1543 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1544 res = GetDIBits( dc, dib, 0, 0, NULL, info2, DIB_RGB_COLORS );
1545 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1546 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1547 "color table mismatch (bpp %d)\n", bpp );
1549 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1550 res = GetDIBits( dc, dib, 0, info->bmiHeader.biHeight, NULL, info2, DIB_RGB_COLORS );
1551 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1552 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1553 "color table mismatch (bpp %d)\n", bpp );
1555 /* Map into a 32bit-DIB */
1556 info2->bmiHeader.biBitCount = 32;
1557 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1558 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1560 /* Check if last pixel was set */
1561 pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
1562 ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
1564 HeapFree(GetProcessHeap(), 0, bits2);
1567 SelectObject(dib_dc, old_bmp);
1572 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1575 char bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1576 char bmibuf2[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1577 BITMAPINFO *info = (BITMAPINFO *)bmibuf;
1578 BITMAPINFO *info2 = (BITMAPINFO *)bmibuf2;
1588 width = height = 16;
1590 /* Create a DDB (device-dependent bitmap) */
1594 ddb = CreateBitmap(width, height, 1, 1, NULL);
1598 HDC screen_dc = GetDC(NULL);
1599 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1600 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1601 ReleaseDC(NULL, screen_dc);
1604 /* Set the pixels */
1605 ddb_dc = CreateCompatibleDC(NULL);
1606 old_bmp = SelectObject(ddb_dc, ddb);
1607 for (i = 0; i < width; i++)
1609 for (j=0; j < height; j++)
1611 BYTE c = (i * width + j) % 256;
1612 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1615 SelectObject(ddb_dc, old_bmp);
1617 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1618 info->bmiHeader.biWidth = width;
1619 info->bmiHeader.biHeight = height;
1620 info->bmiHeader.biPlanes = 1;
1621 info->bmiHeader.biBitCount = bpp;
1622 info->bmiHeader.biCompression = BI_RGB;
1624 dc = CreateCompatibleDC(NULL);
1626 /* Fill in biSizeImage */
1627 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1628 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1630 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1631 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1634 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1635 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1637 /* Copy the DIB attributes but not the color table */
1638 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1640 /* Select the DDB into another DC */
1641 old_bmp = SelectObject(ddb_dc, ddb);
1644 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1645 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1647 /* Compare the color table and the bits */
1650 for (i=0; i < (1u << bpp); i++)
1651 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1652 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1653 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1654 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1655 "color table entry %d differs (bpp %d)\n", i, bpp );
1658 ok( !memcmp( bits, bits2, info->bmiHeader.biSizeImage ), "bit mismatch (bpp %d)\n", bpp );
1660 /* Test the palette */
1661 if (info2->bmiHeader.biBitCount <= 8)
1663 WORD *colors = (WORD*)info2->bmiColors;
1665 /* Get the palette indices */
1666 res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1667 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1669 for (i = 0; i < (1 << info->bmiHeader.biBitCount); i++)
1670 ok( colors[i] == i, "%d: got %d (bpp %d)\n", i, colors[i], bpp );
1673 HeapFree(GetProcessHeap(), 0, bits2);
1674 HeapFree(GetProcessHeap(), 0, bits);
1677 SelectObject(ddb_dc, old_bmp);
1682 static void test_GetDIBits(void)
1684 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1685 static const BYTE bmp_bits_1[16 * 2] =
1687 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1688 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1689 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1690 0xff,0xff, 0,0, 0xff,0xff, 0,0
1692 /* 4-bytes aligned 1-bit DIB data: 16x16 */
1693 static const BYTE dib_bits_1[16 * 4] =
1695 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1696 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1697 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1698 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1700 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1701 static const BYTE bmp_bits_24[16 * 16*3] =
1703 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1704 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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1706 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1707 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1708 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1709 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1710 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1711 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1712 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1713 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1714 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1715 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1716 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1717 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1718 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1719 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1720 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1721 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1722 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1723 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1724 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1725 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1726 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1727 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1728 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1729 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1730 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1731 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1732 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1733 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1734 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1736 /* 4-bytes aligned 24-bit DIB data: 16x16 */
1737 static const BYTE dib_bits_24[16 * 16*3] =
1739 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1740 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1741 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1742 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1743 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1744 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1745 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1746 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1747 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1748 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1749 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1750 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1751 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1752 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1753 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1754 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1755 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1756 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1757 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1758 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1759 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1760 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1761 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1762 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1763 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1764 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1765 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1766 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1767 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1768 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1769 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1770 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1775 int i, bytes, lines;
1777 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1778 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1779 PALETTEENTRY pal_ents[20];
1783 /* 1-bit source bitmap data */
1784 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1785 ok(hbmp != 0, "CreateBitmap failed\n");
1787 memset(&bm, 0xAA, sizeof(bm));
1788 bytes = GetObject(hbmp, sizeof(bm), &bm);
1789 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1790 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1791 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1792 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1793 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1794 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1795 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1796 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1798 bytes = GetBitmapBits(hbmp, 0, NULL);
1799 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1800 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1801 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1802 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1804 /* retrieve 1-bit DIB data */
1805 memset(bi, 0, sizeof(*bi));
1806 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1807 bi->bmiHeader.biWidth = bm.bmWidth;
1808 bi->bmiHeader.biHeight = bm.bmHeight;
1809 bi->bmiHeader.biPlanes = 1;
1810 bi->bmiHeader.biBitCount = 1;
1811 bi->bmiHeader.biCompression = BI_RGB;
1812 bi->bmiHeader.biSizeImage = 0;
1813 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1814 SetLastError(0xdeadbeef);
1815 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1816 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1817 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1818 broken(GetLastError() == 0xdeadbeef), /* winnt */
1819 "wrong error %u\n", GetLastError());
1820 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1822 memset(buf, 0xAA, sizeof(buf));
1823 SetLastError(0xdeadbeef);
1824 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1825 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1826 lines, bm.bmHeight, GetLastError());
1827 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1829 /* the color table consists of black and white */
1830 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1831 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1832 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1833 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1834 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1835 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1836 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1837 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1838 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1839 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1840 for (i = 2; i < 256; i++)
1842 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1843 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1844 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1845 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1846 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1849 /* returned bits are DWORD aligned and upside down */
1850 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1852 /* Test the palette indices */
1853 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1854 SetLastError(0xdeadbeef);
1855 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1856 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1857 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1858 for (i = 2; i < 256; i++)
1859 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[1]);
1861 /* retrieve 24-bit DIB data */
1862 memset(bi, 0, sizeof(*bi));
1863 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1864 bi->bmiHeader.biWidth = bm.bmWidth;
1865 bi->bmiHeader.biHeight = bm.bmHeight;
1866 bi->bmiHeader.biPlanes = 1;
1867 bi->bmiHeader.biBitCount = 24;
1868 bi->bmiHeader.biCompression = BI_RGB;
1869 bi->bmiHeader.biSizeImage = 0;
1870 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1871 memset(buf, 0xAA, sizeof(buf));
1872 SetLastError(0xdeadbeef);
1873 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1874 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1875 lines, bm.bmHeight, GetLastError());
1876 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1878 /* the color table doesn't exist for 24-bit images */
1879 for (i = 0; i < 256; i++)
1881 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1882 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1883 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1884 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1885 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1888 /* returned bits are DWORD aligned and upside down */
1889 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1892 /* 24-bit source bitmap data */
1893 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1894 ok(hbmp != 0, "CreateBitmap failed\n");
1895 SetLastError(0xdeadbeef);
1896 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1897 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1898 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1899 lines, bm.bmHeight, GetLastError());
1901 memset(&bm, 0xAA, sizeof(bm));
1902 bytes = GetObject(hbmp, sizeof(bm), &bm);
1903 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1904 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1905 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1906 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1907 ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1908 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1909 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1910 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1912 bytes = GetBitmapBits(hbmp, 0, NULL);
1913 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
1914 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1915 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1916 bm.bmWidthBytes * bm.bmHeight, bytes);
1918 /* retrieve 1-bit DIB data */
1919 memset(bi, 0, sizeof(*bi));
1920 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1921 bi->bmiHeader.biWidth = bm.bmWidth;
1922 bi->bmiHeader.biHeight = bm.bmHeight;
1923 bi->bmiHeader.biPlanes = 1;
1924 bi->bmiHeader.biBitCount = 1;
1925 bi->bmiHeader.biCompression = BI_RGB;
1926 bi->bmiHeader.biSizeImage = 0;
1927 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1928 memset(buf, 0xAA, sizeof(buf));
1929 SetLastError(0xdeadbeef);
1930 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1931 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1932 lines, bm.bmHeight, GetLastError());
1933 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1935 /* the color table consists of black and white */
1936 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1937 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1938 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1939 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1940 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1941 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1942 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1943 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1944 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1945 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1946 for (i = 2; i < 256; i++)
1948 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1949 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1950 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1951 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1952 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1955 /* returned bits are DWORD aligned and upside down */
1956 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1958 /* Test the palette indices */
1959 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1960 SetLastError(0xdeadbeef);
1961 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1962 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1963 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1964 for (i = 2; i < 256; i++)
1965 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[i]);
1967 /* retrieve 4-bit DIB data */
1968 memset(bi, 0, sizeof(*bi));
1969 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1970 bi->bmiHeader.biWidth = bm.bmWidth;
1971 bi->bmiHeader.biHeight = bm.bmHeight;
1972 bi->bmiHeader.biPlanes = 1;
1973 bi->bmiHeader.biBitCount = 4;
1974 bi->bmiHeader.biCompression = BI_RGB;
1975 bi->bmiHeader.biSizeImage = 0;
1976 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1977 memset(buf, 0xAA, sizeof(buf));
1978 SetLastError(0xdeadbeef);
1979 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1980 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1981 lines, bm.bmHeight, GetLastError());
1983 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
1985 for (i = 0; i < 16; i++)
1988 int entry = i < 8 ? i : i + 4;
1990 if(entry == 7) entry = 12;
1991 else if(entry == 12) entry = 7;
1993 expect.rgbRed = pal_ents[entry].peRed;
1994 expect.rgbGreen = pal_ents[entry].peGreen;
1995 expect.rgbBlue = pal_ents[entry].peBlue;
1996 expect.rgbReserved = 0;
1998 ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
1999 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2000 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2001 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
2002 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
2005 /* retrieve 8-bit DIB data */
2006 memset(bi, 0, sizeof(*bi));
2007 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2008 bi->bmiHeader.biWidth = bm.bmWidth;
2009 bi->bmiHeader.biHeight = bm.bmHeight;
2010 bi->bmiHeader.biPlanes = 1;
2011 bi->bmiHeader.biBitCount = 8;
2012 bi->bmiHeader.biCompression = BI_RGB;
2013 bi->bmiHeader.biSizeImage = 0;
2014 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
2015 memset(buf, 0xAA, sizeof(buf));
2016 SetLastError(0xdeadbeef);
2017 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2018 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2019 lines, bm.bmHeight, GetLastError());
2021 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2023 for (i = 0; i < 256; i++)
2027 if (i < 10 || i >= 246)
2029 int entry = i < 10 ? i : i - 236;
2030 expect.rgbRed = pal_ents[entry].peRed;
2031 expect.rgbGreen = pal_ents[entry].peGreen;
2032 expect.rgbBlue = pal_ents[entry].peBlue;
2036 expect.rgbRed = (i & 0x07) << 5;
2037 expect.rgbGreen = (i & 0x38) << 2;
2038 expect.rgbBlue = i & 0xc0;
2040 expect.rgbReserved = 0;
2042 ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
2043 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2044 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2045 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
2046 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
2049 /* retrieve 24-bit DIB data */
2050 memset(bi, 0, sizeof(*bi));
2051 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2052 bi->bmiHeader.biWidth = bm.bmWidth;
2053 bi->bmiHeader.biHeight = bm.bmHeight;
2054 bi->bmiHeader.biPlanes = 1;
2055 bi->bmiHeader.biBitCount = 24;
2056 bi->bmiHeader.biCompression = BI_RGB;
2057 bi->bmiHeader.biSizeImage = 0;
2058 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
2059 memset(buf, 0xAA, sizeof(buf));
2060 SetLastError(0xdeadbeef);
2061 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2062 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2063 lines, bm.bmHeight, GetLastError());
2064 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2066 /* the color table doesn't exist for 24-bit images */
2067 for (i = 0; i < 256; i++)
2069 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
2070 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
2071 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2072 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
2073 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
2076 /* returned bits are DWORD aligned and upside down */
2077 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2083 static void test_GetDIBits_BI_BITFIELDS(void)
2085 /* Try a screen resolution detection technique
2086 * from the September 1999 issue of Windows Developer's Journal
2087 * which seems to be in widespread use.
2088 * http://www.lesher.ws/highcolor.html
2089 * http://www.lesher.ws/vidfmt.c
2090 * It hinges on being able to retrieve the bitmaps
2091 * for the three primary colors in non-paletted 16 bit mode.
2093 char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
2095 LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
2096 DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
2102 memset(dibinfo, 0, sizeof(dibinfo_buf));
2103 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2106 ok(hdc != NULL, "GetDC failed?\n");
2107 hbm = CreateCompatibleBitmap(hdc, 1, 1);
2108 ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
2110 /* Call GetDIBits to fill in bmiHeader. */
2111 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2112 ok(ret == 1, "GetDIBits failed\n");
2113 if (dibinfo->bmiHeader.biBitCount > 8)
2115 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2116 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2117 "compression is %u (%d bpp)\n", dibinfo->bmiHeader.biCompression, dibinfo->bmiHeader.biBitCount );
2119 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2121 ok( !bitmasks[0], "red mask is set\n" );
2122 ok( !bitmasks[1], "green mask is set\n" );
2123 ok( !bitmasks[2], "blue mask is set\n" );
2125 /* test with NULL bits pointer and correct bpp */
2126 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2127 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2128 ok(ret == 1, "GetDIBits failed\n");
2130 ok( bitmasks[0] != 0, "red mask is not set\n" );
2131 ok( bitmasks[1] != 0, "green mask is not set\n" );
2132 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2133 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2135 /* test with valid bits pointer */
2136 memset(dibinfo, 0, sizeof(dibinfo_buf));
2137 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2138 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2139 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2140 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2141 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2142 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2144 ok( bitmasks[0] != 0, "red mask is not set\n" );
2145 ok( bitmasks[1] != 0, "green mask is not set\n" );
2146 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2147 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2149 /* now with bits and 0 lines */
2150 memset(dibinfo, 0, sizeof(dibinfo_buf));
2151 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2152 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2153 SetLastError(0xdeadbeef);
2154 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2155 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2157 ok( !bitmasks[0], "red mask is set\n" );
2158 ok( !bitmasks[1], "green mask is set\n" );
2159 ok( !bitmasks[2], "blue mask is set\n" );
2160 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2162 memset(bitmasks, 0, 3*sizeof(DWORD));
2163 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2164 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2165 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2167 ok( bitmasks[0] != 0, "red mask is not set\n" );
2168 ok( bitmasks[1] != 0, "green mask is not set\n" );
2169 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2170 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2173 else skip("bitmap in colortable mode, skipping BI_BITFIELDS tests\n");
2177 /* same thing now with a 32-bpp DIB section */
2179 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2180 dibinfo->bmiHeader.biWidth = 1;
2181 dibinfo->bmiHeader.biHeight = 1;
2182 dibinfo->bmiHeader.biPlanes = 1;
2183 dibinfo->bmiHeader.biBitCount = 32;
2184 dibinfo->bmiHeader.biCompression = BI_RGB;
2185 dibinfo->bmiHeader.biSizeImage = 0;
2186 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2187 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2188 dibinfo->bmiHeader.biClrUsed = 0;
2189 dibinfo->bmiHeader.biClrImportant = 0;
2190 bitmasks[0] = 0x0000ff;
2191 bitmasks[1] = 0x00ff00;
2192 bitmasks[2] = 0xff0000;
2193 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2194 ok( hbm != 0, "failed to create bitmap\n" );
2196 memset(dibinfo, 0, sizeof(dibinfo_buf));
2197 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2198 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2199 ok(ret == 1, "GetDIBits failed\n");
2200 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2202 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2203 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2204 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2205 ok( !bitmasks[0], "red mask is set\n" );
2206 ok( !bitmasks[1], "green mask is set\n" );
2207 ok( !bitmasks[2], "blue mask is set\n" );
2209 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2210 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2211 ok(ret == 1, "GetDIBits failed\n");
2212 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2213 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2214 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2215 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2216 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2218 ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
2219 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2220 ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
2222 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2226 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2227 dibinfo->bmiHeader.biWidth = 1;
2228 dibinfo->bmiHeader.biHeight = 1;
2229 dibinfo->bmiHeader.biPlanes = 1;
2230 dibinfo->bmiHeader.biBitCount = 32;
2231 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2232 dibinfo->bmiHeader.biSizeImage = 0;
2233 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2234 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2235 dibinfo->bmiHeader.biClrUsed = 0;
2236 dibinfo->bmiHeader.biClrImportant = 0;
2237 bitmasks[0] = 0x0000ff;
2238 bitmasks[1] = 0x00ff00;
2239 bitmasks[2] = 0xff0000;
2240 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2241 ok( hbm != 0, "failed to create bitmap\n" );
2245 memset(dibinfo, 0, sizeof(dibinfo_buf));
2246 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2247 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2248 ok(ret == 1, "GetDIBits failed\n");
2250 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
2251 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2252 ok( !bitmasks[0], "red mask is set\n" );
2253 ok( !bitmasks[1], "green mask is set\n" );
2254 ok( !bitmasks[2], "blue mask is set\n" );
2256 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2257 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2258 ok(ret == 1, "GetDIBits failed\n");
2259 ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
2260 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2261 ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
2262 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2267 /* 24-bpp DIB sections don't have bitfields */
2269 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2270 dibinfo->bmiHeader.biWidth = 1;
2271 dibinfo->bmiHeader.biHeight = 1;
2272 dibinfo->bmiHeader.biPlanes = 1;
2273 dibinfo->bmiHeader.biBitCount = 24;
2274 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2275 dibinfo->bmiHeader.biSizeImage = 0;
2276 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2277 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2278 dibinfo->bmiHeader.biClrUsed = 0;
2279 dibinfo->bmiHeader.biClrImportant = 0;
2280 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2281 ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
2282 dibinfo->bmiHeader.biCompression = BI_RGB;
2283 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2284 ok( hbm != 0, "failed to create bitmap\n" );
2286 memset(dibinfo, 0, sizeof(dibinfo_buf));
2287 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2288 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2289 ok(ret == 1, "GetDIBits failed\n");
2290 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2292 ok( dibinfo->bmiHeader.biCompression == BI_RGB,
2293 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2294 ok( !bitmasks[0], "red mask is set\n" );
2295 ok( !bitmasks[1], "green mask is set\n" );
2296 ok( !bitmasks[2], "blue mask is set\n" );
2298 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2299 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2300 ok(ret == 1, "GetDIBits failed\n");
2301 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2302 ok( !bitmasks[0], "red mask is set\n" );
2303 ok( !bitmasks[1], "green mask is set\n" );
2304 ok( !bitmasks[2], "blue mask is set\n" );
2305 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2308 ReleaseDC(NULL, hdc);
2311 static void test_select_object(void)
2314 HBITMAP hbm, hbm_old;
2316 DWORD depths[] = {8, 15, 16, 24, 32};
2321 ok(hdc != 0, "GetDC(0) failed\n");
2322 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2323 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2325 hbm_old = SelectObject(hdc, hbm);
2326 ok(hbm_old == 0, "SelectObject should fail\n");
2331 hdc = CreateCompatibleDC(0);
2332 ok(hdc != 0, "GetDC(0) failed\n");
2333 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2334 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2336 hbm_old = SelectObject(hdc, hbm);
2337 ok(hbm_old != 0, "SelectObject failed\n");
2338 hbm_old = SelectObject(hdc, hbm_old);
2339 ok(hbm_old == hbm, "SelectObject failed\n");
2343 /* test an 1-bpp bitmap */
2344 planes = GetDeviceCaps(hdc, PLANES);
2347 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
2348 ok(hbm != 0, "CreateBitmap failed\n");
2350 hbm_old = SelectObject(hdc, hbm);
2351 ok(hbm_old != 0, "SelectObject failed\n");
2352 hbm_old = SelectObject(hdc, hbm_old);
2353 ok(hbm_old == hbm, "SelectObject failed\n");
2357 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
2358 /* test a color bitmap to dc bpp matching */
2359 planes = GetDeviceCaps(hdc, PLANES);
2360 bpp = GetDeviceCaps(hdc, BITSPIXEL);
2362 hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
2363 ok(hbm != 0, "CreateBitmap failed\n");
2365 hbm_old = SelectObject(hdc, hbm);
2366 if(depths[i] == bpp ||
2367 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
2369 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
2370 SelectObject(hdc, hbm_old);
2372 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
2375 memset(&bm, 0xAA, sizeof(bm));
2376 bytes = GetObject(hbm, sizeof(bm), &bm);
2377 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2378 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2379 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
2380 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
2381 ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2382 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
2383 if(depths[i] == 15) {
2384 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
2386 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2388 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2396 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
2401 ret = GetObjectType(hbmp);
2402 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
2404 ret = GetObject(hbmp, 0, 0);
2405 ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
2407 memset(&bm, 0xDA, sizeof(bm));
2408 SetLastError(0xdeadbeef);
2409 ret = GetObject(hbmp, sizeof(bm), &bm);
2410 if (!ret) /* XP, only for curObj2 */ return;
2411 ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
2412 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2413 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2414 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2415 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2416 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2417 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2418 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2421 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2423 static void test_CreateBitmap(void)
2426 HDC screenDC = GetDC(0);
2427 HDC hdc = CreateCompatibleDC(screenDC);
2430 /* all of these are the stock monochrome bitmap */
2431 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2432 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2433 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2434 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2435 HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2436 HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2438 /* these 2 are not the stock monochrome bitmap */
2439 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2440 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2442 HBITMAP old1 = SelectObject(hdc, bm2);
2443 HBITMAP old2 = SelectObject(screenDC, bm3);
2444 SelectObject(hdc, old1);
2445 SelectObject(screenDC, old2);
2447 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2448 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2449 bm, bm1, bm4, bm5, curObj1, old1);
2450 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2452 ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
2453 ok(old2 == 0, "old2 %p\n", old2);
2455 test_mono_1x1_bmp(bm);
2456 test_mono_1x1_bmp(bm1);
2457 test_mono_1x1_bmp(bm2);
2458 test_mono_1x1_bmp(bm3);
2459 test_mono_1x1_bmp(bm4);
2460 test_mono_1x1_bmp(bm5);
2461 test_mono_1x1_bmp(old1);
2462 test_mono_1x1_bmp(curObj1);
2472 ReleaseDC(0, screenDC);
2474 /* show that Windows ignores the provided bm.bmWidthBytes */
2478 bmp.bmWidthBytes = 28;
2480 bmp.bmBitsPixel = 1;
2482 bm = CreateBitmapIndirect(&bmp);
2483 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2484 test_mono_1x1_bmp(bm);
2487 /* Test how the bmBitsPixel field is treated */
2488 for(i = 1; i <= 33; i++) {
2492 bmp.bmWidthBytes = 28;
2494 bmp.bmBitsPixel = i;
2496 SetLastError(0xdeadbeef);
2497 bm = CreateBitmapIndirect(&bmp);
2499 DWORD error = GetLastError();
2500 ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
2501 ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2505 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2506 GetObject(bm, sizeof(bmp), &bmp);
2513 } else if(i <= 16) {
2515 } else if(i <= 24) {
2517 } else if(i <= 32) {
2520 ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2521 i, bmp.bmBitsPixel, expect);
2526 static void test_bitmapinfoheadersize(void)
2533 memset(&bmi, 0, sizeof(BITMAPINFO));
2534 bmi.bmiHeader.biHeight = 100;
2535 bmi.bmiHeader.biWidth = 512;
2536 bmi.bmiHeader.biBitCount = 24;
2537 bmi.bmiHeader.biPlanes = 1;
2539 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2541 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2542 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2544 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2546 SetLastError(0xdeadbeef);
2547 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2548 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2551 bmi.bmiHeader.biSize++;
2553 SetLastError(0xdeadbeef);
2554 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2556 broken(!hdib), /* Win98, WinMe */
2557 "CreateDIBSection error %d\n", GetLastError());
2560 bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2562 SetLastError(0xdeadbeef);
2563 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2565 broken(!hdib), /* Win98, WinMe */
2566 "CreateDIBSection error %d\n", GetLastError());
2569 bmi.bmiHeader.biSize++;
2571 SetLastError(0xdeadbeef);
2572 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2574 broken(!hdib), /* Win98, WinMe */
2575 "CreateDIBSection error %d\n", GetLastError());
2578 bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2580 SetLastError(0xdeadbeef);
2581 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2582 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2585 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2587 SetLastError(0xdeadbeef);
2588 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2590 broken(!hdib), /* Win95 */
2591 "CreateDIBSection error %d\n", GetLastError());
2594 memset(&bci, 0, sizeof(BITMAPCOREINFO));
2595 bci.bmciHeader.bcHeight = 100;
2596 bci.bmciHeader.bcWidth = 512;
2597 bci.bmciHeader.bcBitCount = 24;
2598 bci.bmciHeader.bcPlanes = 1;
2600 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2602 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2603 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2605 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2607 SetLastError(0xdeadbeef);
2608 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2609 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2612 bci.bmciHeader.bcSize++;
2614 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2615 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2617 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2619 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2620 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2625 static void test_get16dibits(void)
2627 BYTE bits[4 * (16 / sizeof(BYTE))];
2629 HDC screen_dc = GetDC(NULL);
2632 int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2634 int overwritten_bytes = 0;
2636 memset(bits, 0, sizeof(bits));
2637 hbmp = CreateBitmap(2, 2, 1, 16, bits);
2638 ok(hbmp != NULL, "CreateBitmap failed\n");
2640 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2643 memset(info, '!', info_len);
2644 memset(info, 0, sizeof(info->bmiHeader));
2646 info->bmiHeader.biSize = sizeof(info->bmiHeader);
2647 info->bmiHeader.biWidth = 2;
2648 info->bmiHeader.biHeight = 2;
2649 info->bmiHeader.biPlanes = 1;
2650 info->bmiHeader.biCompression = BI_RGB;
2652 ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2653 ok(ret != 0, "GetDIBits failed got %d\n", ret);
2655 for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2657 overwritten_bytes++;
2658 ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2660 HeapFree(GetProcessHeap(), 0, info);
2662 ReleaseDC(NULL, screen_dc);
2665 static BOOL compare_buffers_no_alpha(UINT32 *a, UINT32 *b, int length)
2668 for(i = 0; i < length; i++)
2669 if((a[i] & 0x00FFFFFF) != (b[i] & 0x00FFFFFF))
2674 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2675 DWORD dwRop, UINT32 expected, int line)
2677 *srcBuffer = 0xFEDCBA98;
2678 *dstBuffer = 0x89ABCDEF;
2679 Rectangle(hdcSrc, 0, 0, 1, 1); /* A null operation to ensure dibs are coerced to X11 */
2680 BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
2681 ok(expected == *dstBuffer,
2682 "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2683 dwRop, expected, *dstBuffer, line);
2686 static void test_BitBlt(void)
2688 HBITMAP bmpDst, bmpSrc;
2689 HBITMAP oldDst, oldSrc;
2690 HDC hdcScreen, hdcDst, hdcSrc;
2691 UINT32 *dstBuffer, *srcBuffer;
2692 HBRUSH hBrush, hOldBrush;
2693 BITMAPINFO bitmapInfo;
2695 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2696 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2697 bitmapInfo.bmiHeader.biWidth = 1;
2698 bitmapInfo.bmiHeader.biHeight = 1;
2699 bitmapInfo.bmiHeader.biPlanes = 1;
2700 bitmapInfo.bmiHeader.biBitCount = 32;
2701 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2702 bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2704 hdcScreen = CreateCompatibleDC(0);
2705 hdcDst = CreateCompatibleDC(hdcScreen);
2706 hdcSrc = CreateCompatibleDC(hdcDst);
2708 /* Setup the destination dib section */
2709 bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
2711 oldDst = SelectObject(hdcDst, bmpDst);
2713 hBrush = CreateSolidBrush(0x012345678);
2714 hOldBrush = SelectObject(hdcDst, hBrush);
2716 /* Setup the source dib section */
2717 bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
2719 oldSrc = SelectObject(hdcSrc, bmpSrc);
2721 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2722 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2723 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2724 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2725 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2726 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2727 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2728 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2729 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2730 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2731 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2732 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2733 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2734 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2735 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2738 SelectObject(hdcSrc, oldSrc);
2739 DeleteObject(bmpSrc);
2742 SelectObject(hdcDst, hOldBrush);
2743 DeleteObject(hBrush);
2744 SelectObject(hdcDst, oldDst);
2745 DeleteObject(bmpDst);
2749 DeleteDC(hdcScreen);
2752 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2753 DWORD dwRop, UINT32 expected, int line)
2755 *srcBuffer = 0xFEDCBA98;
2756 *dstBuffer = 0x89ABCDEF;
2757 StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
2758 ok(expected == *dstBuffer,
2759 "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2760 dwRop, expected, *dstBuffer, line);
2763 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2764 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2765 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2766 UINT32 expected[4], UINT32 legacy_expected[4], int line)
2768 memset(dstBuffer, 0, 16);
2769 StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2770 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
2771 ok(memcmp(dstBuffer, expected, 16) == 0 ||
2772 broken(compare_buffers_no_alpha(dstBuffer, legacy_expected, 4)),
2773 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2774 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2775 expected[0], expected[1], expected[2], expected[3],
2776 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2777 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2778 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2781 static void test_StretchBlt(void)
2783 HBITMAP bmpDst, bmpSrc;
2784 HBITMAP oldDst, oldSrc;
2785 HDC hdcScreen, hdcDst, hdcSrc;
2786 UINT32 *dstBuffer, *srcBuffer;
2787 HBRUSH hBrush, hOldBrush;
2788 BITMAPINFO biDst, biSrc;
2789 UINT32 expected[4], legacy_expected[4];
2791 memset(&biDst, 0, sizeof(BITMAPINFO));
2792 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2793 biDst.bmiHeader.biWidth = 2;
2794 biDst.bmiHeader.biHeight = -2;
2795 biDst.bmiHeader.biPlanes = 1;
2796 biDst.bmiHeader.biBitCount = 32;
2797 biDst.bmiHeader.biCompression = BI_RGB;
2798 memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
2800 hdcScreen = CreateCompatibleDC(0);
2801 hdcDst = CreateCompatibleDC(hdcScreen);
2802 hdcSrc = CreateCompatibleDC(hdcDst);
2805 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2807 oldDst = SelectObject(hdcDst, bmpDst);
2809 bmpSrc = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&srcBuffer,
2811 oldSrc = SelectObject(hdcSrc, bmpSrc);
2813 hBrush = CreateSolidBrush(0x012345678);
2814 hOldBrush = SelectObject(hdcDst, hBrush);
2816 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2817 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2818 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2819 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2820 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2821 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2822 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2823 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2824 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2825 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2826 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2827 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2828 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2829 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2830 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2832 SelectObject(hdcDst, hOldBrush);
2833 DeleteObject(hBrush);
2835 /* Top-down to top-down tests */
2836 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2837 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
2839 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2840 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2841 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2842 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2844 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2845 expected[2] = 0x00000000, expected[3] = 0x00000000;
2846 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2847 0, 0, 1, 1, 0, 0, 1, 1, expected, expected, __LINE__);
2849 expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
2850 expected[2] = 0xCAFED00D, expected[3] = 0xCAFED00D;
2851 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2852 0, 0, 2, 2, 0, 0, 1, 1, expected, expected, __LINE__);
2854 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2855 expected[2] = 0x00000000, expected[3] = 0x00000000;
2856 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2857 0, 0, 1, 1, 0, 0, 2, 2, expected, expected, __LINE__);
2859 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2860 expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2861 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2862 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2864 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2865 expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2866 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2867 1, 1, -2, -2, 0, 0, 2, 2, expected, expected, __LINE__);
2869 /* This result seems broken. One might expect the following result:
2870 * 0xCAFED00D 0xFEEDFACE
2871 * 0xFEDCBA98 0x76543210
2873 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2874 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2875 legacy_expected[0] = 0xCAFED00D, legacy_expected[1] = 0x00000000;
2876 legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
2877 todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2878 1, 1, -2, -2, 1, 1, -2, -2, expected,
2879 legacy_expected, __LINE__);
2881 expected[0] = 0x00000000, expected[1] = 0x00000000;
2882 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
2883 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2884 1, 1, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2886 SelectObject(hdcDst, oldDst);
2887 DeleteObject(bmpDst);
2889 /* Top-down to bottom-up tests */
2890 biDst.bmiHeader.biHeight = 2;
2891 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2893 oldDst = SelectObject(hdcDst, bmpDst);
2895 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2896 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
2897 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2898 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2900 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2901 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2902 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2903 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2905 SelectObject(hdcSrc, oldSrc);
2906 DeleteObject(bmpSrc);
2908 /* Bottom-up to bottom-up tests */
2909 biSrc.bmiHeader.biHeight = 2;
2910 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2912 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2913 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
2914 oldSrc = SelectObject(hdcSrc, bmpSrc);
2916 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2917 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2918 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2919 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2921 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2922 expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2923 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2924 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2926 SelectObject(hdcDst, oldDst);
2927 DeleteObject(bmpDst);
2929 /* Bottom-up to top-down tests */
2930 biDst.bmiHeader.biHeight = -2;
2931 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2933 oldDst = SelectObject(hdcDst, bmpDst);
2935 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2936 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
2937 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2938 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2940 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2941 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2942 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2943 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2946 SelectObject(hdcSrc, oldSrc);
2947 DeleteObject(bmpSrc);
2950 SelectObject(hdcDst, oldDst);
2951 DeleteObject(bmpDst);
2954 DeleteDC(hdcScreen);
2957 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
2958 DWORD dwRop, UINT32 expected, int line)
2960 const UINT32 buffer[2] = { 0xFEDCBA98, 0 };
2961 BITMAPINFO bitmapInfo;
2963 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2964 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2965 bitmapInfo.bmiHeader.biWidth = 2;
2966 bitmapInfo.bmiHeader.biHeight = 1;
2967 bitmapInfo.bmiHeader.biPlanes = 1;
2968 bitmapInfo.bmiHeader.biBitCount = 32;
2969 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2970 bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer);
2972 *dstBuffer = 0x89ABCDEF;
2974 StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop);
2975 ok(expected == *dstBuffer,
2976 "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2977 dwRop, expected, *dstBuffer, line);
2980 static void check_StretchDIBits_stretch(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
2981 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2982 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2983 UINT32 expected[4], UINT32 legacy_expected[4], int line)
2985 BITMAPINFO bitmapInfo;
2987 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2988 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2989 bitmapInfo.bmiHeader.biWidth = 2;
2990 bitmapInfo.bmiHeader.biHeight = -2;
2991 bitmapInfo.bmiHeader.biPlanes = 1;
2992 bitmapInfo.bmiHeader.biBitCount = 32;
2993 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2995 memset(dstBuffer, 0, 16);
2996 StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2997 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2998 srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
2999 ok(memcmp(dstBuffer, expected, 16) == 0,
3000 "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
3001 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
3002 expected[0], expected[1], expected[2], expected[3],
3003 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
3004 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3005 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
3008 static void test_StretchDIBits(void)
3012 HDC hdcScreen, hdcDst;
3013 UINT32 *dstBuffer, srcBuffer[4];
3014 HBRUSH hBrush, hOldBrush;
3016 UINT32 expected[4], legacy_expected[4];
3018 memset(&biDst, 0, sizeof(BITMAPINFO));
3019 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3020 biDst.bmiHeader.biWidth = 2;
3021 biDst.bmiHeader.biHeight = -2;
3022 biDst.bmiHeader.biPlanes = 1;
3023 biDst.bmiHeader.biBitCount = 32;
3024 biDst.bmiHeader.biCompression = BI_RGB;
3026 hdcScreen = CreateCompatibleDC(0);
3027 hdcDst = CreateCompatibleDC(hdcScreen);
3030 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3032 oldDst = SelectObject(hdcDst, bmpDst);
3034 hBrush = CreateSolidBrush(0x012345678);
3035 hOldBrush = SelectObject(hdcDst, hBrush);
3037 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3038 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3039 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3040 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3041 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3042 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3043 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3044 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3045 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3046 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3047 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3048 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3049 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3050 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3051 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3053 SelectObject(hdcDst, hOldBrush);
3054 DeleteObject(hBrush);
3056 /* Top-down destination tests */
3057 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3058 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
3060 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
3061 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
3062 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3063 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
3065 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3066 expected[2] = 0x00000000, expected[3] = 0x00000000;
3067 legacy_expected[0] = 0xFEDCBA98, legacy_expected[1] = 0x00000000;
3068 legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
3069 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3070 0, 0, 1, 1, 0, 0, 1, 1, expected, legacy_expected, __LINE__);
3072 expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
3073 expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
3074 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3075 0, 0, 2, 2, 0, 0, 1, 1, expected, expected, __LINE__);
3077 expected[0] = 0x42441000, expected[1] = 0x00000000;
3078 expected[2] = 0x00000000, expected[3] = 0x00000000;
3079 legacy_expected[0] = 0x00543210, legacy_expected[1] = 0x00000000;
3080 legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
3081 todo_wine check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3082 0, 0, 1, 1, 0, 0, 2, 2, expected, legacy_expected, __LINE__);
3084 expected[0] = 0x00000000, expected[1] = 0x00000000;
3085 expected[2] = 0x00000000, expected[3] = 0x00000000;
3086 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3087 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
3089 expected[0] = 0x00000000, expected[1] = 0x00000000;
3090 expected[2] = 0x00000000, expected[3] = 0x00000000;
3091 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3092 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
3094 expected[0] = 0x00000000, expected[1] = 0x00000000;
3095 expected[2] = 0x00000000, expected[3] = 0x00000000;
3096 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3097 1, 1, -2, -2, 1, 1, -2, -2, expected, expected, __LINE__);
3099 expected[0] = 0x00000000, expected[1] = 0x00000000;
3100 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
3101 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3102 1, 1, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
3104 SelectObject(hdcDst, oldDst);
3105 DeleteObject(bmpDst);
3107 /* Bottom up destination tests */
3108 biDst.bmiHeader.biHeight = 2;
3109 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3111 oldDst = SelectObject(hdcDst, bmpDst);
3113 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3114 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
3115 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3116 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
3119 SelectObject(hdcDst, oldDst);
3120 DeleteObject(bmpDst);
3123 DeleteDC(hdcScreen);
3126 static void test_GdiAlphaBlend(void)
3128 /* test out-of-bound parameters for GdiAlphaBlend */
3141 BLENDFUNCTION blend;
3143 if (!pGdiAlphaBlend)
3145 win_skip("GdiAlphaBlend() is not implemented\n");
3149 hdcNull = GetDC(NULL);
3150 hdcDst = CreateCompatibleDC(hdcNull);
3151 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
3152 hdcSrc = CreateCompatibleDC(hdcNull);
3154 memset(&bmi, 0, sizeof(bmi)); /* as of Wine 0.9.44 we require the src to be a DIB section */
3155 bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
3156 bmi.bmiHeader.biHeight = 20;
3157 bmi.bmiHeader.biWidth = 20;
3158 bmi.bmiHeader.biBitCount = 32;
3159 bmi.bmiHeader.biPlanes = 1;
3160 bmi.bmiHeader.biCompression = BI_RGB;
3161 bmpSrc = CreateDIBSection(hdcDst, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3162 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3164 oldDst = SelectObject(hdcDst, bmpDst);
3165 oldSrc = SelectObject(hdcSrc, bmpSrc);
3167 blend.BlendOp = AC_SRC_OVER;
3168 blend.BlendFlags = 0;
3169 blend.SourceConstantAlpha = 128;
3170 blend.AlphaFormat = 0;
3172 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend), TRUE, BOOL, "%d");
3173 SetLastError(0xdeadbeef);
3174 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), FALSE, BOOL, "%d");
3175 expect_eq(GetLastError(), ERROR_INVALID_PARAMETER, int, "%d");
3176 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), FALSE, BOOL, "%d");
3177 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend), FALSE, BOOL, "%d");
3178 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
3179 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
3181 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
3182 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), TRUE, BOOL, "%d");
3183 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), TRUE, BOOL, "%d");
3184 SetMapMode(hdcSrc, MM_ANISOTROPIC);
3185 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
3186 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend), TRUE, BOOL, "%d");
3187 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend), TRUE, BOOL, "%d");
3189 SetLastError(0xdeadbeef);
3190 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend), FALSE, BOOL, "%d");
3191 expect_eq(GetLastError(), 0xdeadbeef, int, "%d");
3193 SelectObject(hdcDst, oldDst);
3194 SelectObject(hdcSrc, oldSrc);
3195 DeleteObject(bmpSrc);
3196 DeleteObject(bmpDst);
3200 ReleaseDC(NULL, hdcNull);
3204 static void test_clipping(void)
3212 HDC hdcDst = CreateCompatibleDC( NULL );
3213 HDC hdcSrc = CreateCompatibleDC( NULL );
3215 BITMAPINFO bmpinfo={{0}};
3216 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3217 bmpinfo.bmiHeader.biWidth = 100;
3218 bmpinfo.bmiHeader.biHeight = 100;
3219 bmpinfo.bmiHeader.biPlanes = 1;
3220 bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3221 bmpinfo.bmiHeader.biCompression = BI_RGB;
3223 bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3224 ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3225 SelectObject( hdcDst, bmpDst );
3227 bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3228 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3229 SelectObject( hdcSrc, bmpSrc );
3231 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3232 ok(result, "BitBlt failed\n");
3234 hRgn = CreateRectRgn( 0,0,0,0 );
3235 SelectClipRgn( hdcDst, hRgn );
3237 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3238 ok(result, "BitBlt failed\n");
3240 DeleteObject( bmpDst );
3241 DeleteObject( bmpSrc );
3242 DeleteObject( hRgn );
3247 static void test_32bit_bitmap_blt(void)
3250 HBITMAP bmpSrc, bmpDst;
3251 HBITMAP oldSrc, oldDst;
3252 HDC hdcSrc, hdcDst, hdcScreen;
3254 DWORD colorSrc = 0x11223344;
3256 memset(&biDst, 0, sizeof(BITMAPINFO));
3257 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3258 biDst.bmiHeader.biWidth = 2;
3259 biDst.bmiHeader.biHeight = -2;
3260 biDst.bmiHeader.biPlanes = 1;
3261 biDst.bmiHeader.biBitCount = 32;
3262 biDst.bmiHeader.biCompression = BI_RGB;
3264 hdcScreen = CreateCompatibleDC(0);
3265 if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3267 DeleteDC(hdcScreen);
3268 trace("Skipping 32-bit DDB test\n");
3272 hdcSrc = CreateCompatibleDC(hdcScreen);
3273 bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3274 oldSrc = SelectObject(hdcSrc, bmpSrc);
3276 hdcDst = CreateCompatibleDC(hdcScreen);
3277 bmpDst = CreateDIBSection(hdcDst, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3278 oldDst = SelectObject(hdcDst, bmpDst);
3280 StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3281 ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3284 SelectObject(hdcDst, oldDst);
3285 DeleteObject(bmpDst);
3288 SelectObject(hdcSrc, oldSrc);
3289 DeleteObject(bmpSrc);
3292 DeleteDC(hdcScreen);
3296 * Used by test_GetDIBits_top_down to create the bitmap to test against.
3298 static void setup_picture(char *picture, int bpp)
3306 /*Set the first byte in each pixel to the index of that pixel.*/
3307 for (i = 0; i < 4; i++)
3308 picture[i * (bpp / 8)] = i;
3313 /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
3320 static void test_GetDIBits_top_down(int bpp)
3323 HBITMAP bmptb, bmpbt;
3329 memset( &bi, 0, sizeof(bi) );
3330 bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
3331 bi.bmiHeader.biWidth=2;
3332 bi.bmiHeader.biHeight=2;
3333 bi.bmiHeader.biPlanes=1;
3334 bi.bmiHeader.biBitCount=bpp;
3335 bi.bmiHeader.biCompression=BI_RGB;
3337 /*Get the device context for the screen.*/
3339 ok(hdc != NULL, "Could not get a handle to a device context.\n");
3341 /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
3342 bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3343 ok(bmpbt != NULL, "Could not create a DIB section.\n");
3344 /*Now that we have a pointer to the pixels, we write to them.*/
3345 setup_picture((char*)picture, bpp);
3346 /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
3347 bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
3348 bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3349 ok(bmptb != NULL, "Could not create a DIB section.\n");
3350 /*Write to this top to bottom bitmap.*/
3351 setup_picture((char*)picture, bpp);
3353 bi.bmiHeader.biWidth = 1;
3355 bi.bmiHeader.biHeight = 2;
3356 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3357 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3358 /*Check the first byte of the pixel.*/
3359 ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3360 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3361 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3362 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3363 /*Check second scanline.*/
3364 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3365 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3366 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3367 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3368 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3369 ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3370 /*Check both scanlines.*/
3371 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3372 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3373 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3374 ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3375 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3376 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3377 ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3378 ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3380 /*Make destination bitmap top-down.*/
3381 bi.bmiHeader.biHeight = -2;
3382 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3383 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3384 ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3385 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3386 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3387 ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3388 /*Check second scanline.*/
3389 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3390 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3391 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3392 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3393 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3394 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3395 /*Check both scanlines.*/
3396 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3397 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3398 ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3399 ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3400 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3401 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3402 ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3403 ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3405 DeleteObject(bmpbt);
3406 DeleteObject(bmptb);
3409 static void test_GetSetDIBits_rtl(void)
3412 HBITMAP bitmap, orig_bitmap;
3415 DWORD bits_1[8 * 8], bits_2[8 * 8];
3419 win_skip("Don't have SetLayout\n");
3423 hdc = GetDC( NULL );
3424 hdc_mem = CreateCompatibleDC( hdc );
3425 pSetLayout( hdc_mem, LAYOUT_LTR );
3427 bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
3428 orig_bitmap = SelectObject( hdc_mem, bitmap );
3429 SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
3430 SelectObject( hdc_mem, orig_bitmap );
3432 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3433 info.bmiHeader.biWidth = 8;
3434 info.bmiHeader.biHeight = 8;
3435 info.bmiHeader.biPlanes = 1;
3436 info.bmiHeader.biBitCount = 32;
3437 info.bmiHeader.biCompression = BI_RGB;
3439 /* First show that GetDIBits ignores the layout mode. */
3441 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3442 ok(ret == 8, "got %d\n", ret);
3443 ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
3445 pSetLayout( hdc_mem, LAYOUT_RTL );
3447 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3448 ok(ret == 8, "got %d\n", ret);
3450 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3452 /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
3453 followed by a GetDIBits and show that the bits remain unchanged. */
3455 pSetLayout( hdc_mem, LAYOUT_LTR );
3457 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3458 ok(ret == 8, "got %d\n", ret);
3459 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3460 ok(ret == 8, "got %d\n", ret);
3461 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3463 pSetLayout( hdc_mem, LAYOUT_RTL );
3465 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3466 ok(ret == 8, "got %d\n", ret);
3467 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3468 ok(ret == 8, "got %d\n", ret);
3469 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3471 DeleteObject( bitmap );
3472 DeleteDC( hdc_mem );
3473 ReleaseDC( NULL, hdc );
3476 static void test_GetDIBits_scanlines(void)
3478 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3479 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3481 HDC hdc = GetDC( NULL );
3483 DWORD data[128], inverted_bits[64];
3486 memset( info, 0, sizeof(bmi_buf) );
3488 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3489 info->bmiHeader.biWidth = 8;
3490 info->bmiHeader.biHeight = 8;
3491 info->bmiHeader.biPlanes = 1;
3492 info->bmiHeader.biBitCount = 32;
3493 info->bmiHeader.biCompression = BI_RGB;
3495 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3497 for (i = 0; i < 64; i++)
3500 inverted_bits[56 - (i & ~7) + (i & 7)] = i;
3505 memset( data, 0xaa, sizeof(data) );
3507 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3508 ok( ret == 8, "got %d\n", ret );
3509 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3510 memset( data, 0xaa, sizeof(data) );
3512 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3513 ok( ret == 5, "got %d\n", ret );
3514 ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
3515 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3516 memset( data, 0xaa, sizeof(data) );
3518 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3519 ok( ret == 7, "got %d\n", ret );
3520 ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
3521 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3522 memset( data, 0xaa, sizeof(data) );
3524 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3525 ok( ret == 1, "got %d\n", ret );
3526 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3527 memset( data, 0xaa, sizeof(data) );
3529 info->bmiHeader.biHeight = 16;
3530 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3531 ok( ret == 5, "got %d\n", ret );
3532 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3533 ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
3534 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3535 memset( data, 0xaa, sizeof(data) );
3537 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3538 ok( ret == 6, "got %d\n", ret );
3539 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3540 ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
3541 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3542 memset( data, 0xaa, sizeof(data) );
3544 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3545 ok( ret == 0, "got %d\n", ret );
3546 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3547 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3548 memset( data, 0xaa, sizeof(data) );
3550 info->bmiHeader.biHeight = 5;
3551 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3552 ok( ret == 2, "got %d\n", ret );
3553 ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
3554 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3555 memset( data, 0xaa, sizeof(data) );
3559 info->bmiHeader.biHeight = -8;
3560 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3561 ok( ret == 8, "got %d\n", ret );
3562 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3563 memset( data, 0xaa, sizeof(data) );
3565 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3566 ok( ret == 5, "got %d\n", ret );
3567 ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
3568 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3569 memset( data, 0xaa, sizeof(data) );
3571 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3572 ok( ret == 7, "got %d\n", ret );
3573 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3574 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3575 memset( data, 0xaa, sizeof(data) );
3577 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3578 ok( ret == 4, "got %d\n", ret );
3579 ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
3580 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3581 memset( data, 0xaa, sizeof(data) );
3583 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3584 ok( ret == 5, "got %d\n", ret );
3585 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3586 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3587 memset( data, 0xaa, sizeof(data) );
3589 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3590 ok( ret == 5, "got %d\n", ret );
3591 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3592 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3593 memset( data, 0xaa, sizeof(data) );
3595 info->bmiHeader.biHeight = -16;
3596 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3597 ok( ret == 8, "got %d\n", ret );
3598 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3599 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3600 memset( data, 0xaa, sizeof(data) );
3602 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3603 ok( ret == 5, "got %d\n", ret );
3604 ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
3605 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3606 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3607 memset( data, 0xaa, sizeof(data) );
3609 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3610 ok( ret == 8, "got %d\n", ret );
3611 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3612 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3613 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3614 memset( data, 0xaa, sizeof(data) );
3616 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3617 ok( ret == 8, "got %d\n", ret );
3618 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3619 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3620 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3621 memset( data, 0xaa, sizeof(data) );
3623 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3624 ok( ret == 7, "got %d\n", ret );
3625 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3626 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3627 memset( data, 0xaa, sizeof(data) );
3629 ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
3630 ok( ret == 1, "got %d\n", ret );
3631 for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3632 memset( data, 0xaa, sizeof(data) );
3634 info->bmiHeader.biHeight = -5;
3635 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3636 ok( ret == 2, "got %d\n", ret );
3637 ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
3638 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3639 memset( data, 0xaa, sizeof(data) );
3641 DeleteObject( dib );
3643 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3644 info->bmiHeader.biWidth = 8;
3645 info->bmiHeader.biHeight = -8;
3646 info->bmiHeader.biPlanes = 1;
3647 info->bmiHeader.biBitCount = 32;
3648 info->bmiHeader.biCompression = BI_RGB;
3650 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3652 for (i = 0; i < 64; i++) dib_bits[i] = i;
3656 info->bmiHeader.biHeight = -8;
3657 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3658 ok( ret == 8, "got %d\n", ret );
3659 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3660 memset( data, 0xaa, sizeof(data) );
3662 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3663 ok( ret == 5, "got %d\n", ret );
3664 ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
3665 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3666 memset( data, 0xaa, sizeof(data) );
3668 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3669 ok( ret == 7, "got %d\n", ret );
3670 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3671 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3672 memset( data, 0xaa, sizeof(data) );
3674 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3675 ok( ret == 4, "got %d\n", ret );
3676 ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
3677 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3678 memset( data, 0xaa, sizeof(data) );
3680 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3681 ok( ret == 5, "got %d\n", ret );
3682 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3683 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3684 memset( data, 0xaa, sizeof(data) );
3686 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3687 ok( ret == 5, "got %d\n", ret );
3688 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3689 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3690 memset( data, 0xaa, sizeof(data) );
3692 info->bmiHeader.biHeight = -16;
3693 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3694 ok( ret == 8, "got %d\n", ret );
3695 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3696 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3697 memset( data, 0xaa, sizeof(data) );
3699 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3700 ok( ret == 5, "got %d\n", ret );
3701 ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
3702 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3703 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3704 memset( data, 0xaa, sizeof(data) );
3706 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3707 ok( ret == 8, "got %d\n", ret );
3708 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3709 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3710 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3711 memset( data, 0xaa, sizeof(data) );
3713 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3714 ok( ret == 8, "got %d\n", ret );
3715 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3716 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3717 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3718 memset( data, 0xaa, sizeof(data) );
3720 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3721 ok( ret == 7, "got %d\n", ret );
3722 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3723 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3724 memset( data, 0xaa, sizeof(data) );
3726 info->bmiHeader.biHeight = -5;
3727 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3728 ok( ret == 2, "got %d\n", ret );
3729 ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
3730 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3731 memset( data, 0xaa, sizeof(data) );
3736 info->bmiHeader.biHeight = 8;
3738 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3739 ok( ret == 8, "got %d\n", ret );
3740 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3741 memset( data, 0xaa, sizeof(data) );
3743 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3744 ok( ret == 5, "got %d\n", ret );
3745 ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
3746 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3747 memset( data, 0xaa, sizeof(data) );
3749 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3750 ok( ret == 7, "got %d\n", ret );
3751 ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
3752 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3753 memset( data, 0xaa, sizeof(data) );
3755 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3756 ok( ret == 1, "got %d\n", ret );
3757 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3758 memset( data, 0xaa, sizeof(data) );
3760 info->bmiHeader.biHeight = 16;
3761 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3762 ok( ret == 5, "got %d\n", ret );
3763 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3764 ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
3765 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3766 memset( data, 0xaa, sizeof(data) );
3768 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3769 ok( ret == 6, "got %d\n", ret );
3770 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3771 ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
3772 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3773 memset( data, 0xaa, sizeof(data) );
3775 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3776 ok( ret == 0, "got %d\n", ret );
3777 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3778 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3779 memset( data, 0xaa, sizeof(data) );
3781 info->bmiHeader.biHeight = 5;
3782 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3783 ok( ret == 2, "got %d\n", ret );
3784 ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
3785 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3786 memset( data, 0xaa, sizeof(data) );
3788 DeleteObject( dib );
3790 ReleaseDC( NULL, hdc );
3794 static void test_SetDIBits(void)
3796 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3797 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3799 HDC hdc = GetDC( NULL );
3800 DWORD data[128], inverted_data[128];
3804 memset( info, 0, sizeof(bmi_buf) );
3806 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3807 info->bmiHeader.biWidth = 8;
3808 info->bmiHeader.biHeight = 8;
3809 info->bmiHeader.biPlanes = 1;
3810 info->bmiHeader.biBitCount = 32;
3811 info->bmiHeader.biCompression = BI_RGB;
3813 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3814 memset( dib_bits, 0xaa, 64 * 4 );
3816 for (i = 0; i < 128; i++)
3819 inverted_data[120 - (i & ~7) + (i & 7)] = i;
3824 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3825 ok( ret == 8, "got %d\n", ret );
3826 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
3827 memset( dib_bits, 0xaa, 64 * 4 );
3829 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3830 ok( ret == 5, "got %d\n", ret );
3831 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3832 ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
3833 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3834 memset( dib_bits, 0xaa, 64 * 4 );
3836 /* top of dst is aligned with startscans down for the top of the src.
3837 Then starting from the bottom of src, lines rows are copied across. */
3839 info->bmiHeader.biHeight = 16;
3840 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3841 ok( ret == 12, "got %d\n", ret );
3842 ok( !memcmp( dib_bits, data + 56, 40 * 4 ), "bits differ\n");
3843 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3844 memset( dib_bits, 0xaa, 64 * 4 );
3846 info->bmiHeader.biHeight = 5;
3847 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3848 ok( ret == 2, "got %d\n", ret );
3849 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3850 ok( !memcmp( dib_bits + 32, data, 16 * 4 ), "bits differ\n");
3851 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3852 memset( dib_bits, 0xaa, 64 * 4 );
3855 info->bmiHeader.biHeight = -8;
3856 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3857 ok( ret == 8, "got %d\n", ret );
3858 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3859 memset( dib_bits, 0xaa, 64 * 4 );
3861 /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
3862 we copy lines rows from the top of the src */
3864 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3865 ok( ret == 5, "got %d\n", ret );
3866 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3867 ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
3868 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3869 memset( dib_bits, 0xaa, 64 * 4 );
3871 info->bmiHeader.biHeight = -16;
3872 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3873 ok( ret == 12, "got %d\n", ret );
3874 ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
3875 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3876 memset( dib_bits, 0xaa, 64 * 4 );
3878 ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3879 ok( ret == 12, "got %d\n", ret );
3880 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3881 memset( dib_bits, 0xaa, 64 * 4 );
3883 ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3884 ok( ret == 12, "got %d\n", ret );
3885 ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
3886 memset( dib_bits, 0xaa, 64 * 4 );
3888 info->bmiHeader.biHeight = -5;
3889 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3890 ok( ret == 2, "got %d\n", ret );
3891 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3892 ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
3893 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3894 memset( dib_bits, 0xaa, 64 * 4 );
3896 DeleteObject( dib );
3898 info->bmiHeader.biHeight = -8;
3900 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3901 memset( dib_bits, 0xaa, 16 * 16 * 4 );
3905 /* like the t-d -> b-u case. */
3907 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3908 ok( ret == 8, "got %d\n", ret );
3909 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
3910 memset( dib_bits, 0xaa, 64 * 4 );
3912 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3913 ok( ret == 5, "got %d\n", ret );
3914 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3915 ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
3916 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3917 memset( dib_bits, 0xaa, 64 * 4 );
3919 info->bmiHeader.biHeight = -16;
3920 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3921 ok( ret == 12, "got %d\n", ret );
3922 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3923 ok( !memcmp( dib_bits + 24, data, 40 * 4 ), "bits differ\n");
3924 memset( dib_bits, 0xaa, 64 * 4 );
3926 info->bmiHeader.biHeight = -5;
3927 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3928 ok( ret == 2, "got %d\n", ret );
3929 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3930 ok( !memcmp( dib_bits + 16, data, 16 * 4 ), "bits differ\n");
3931 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3932 memset( dib_bits, 0xaa, 64 * 4 );
3935 /* like the b-u -> b-u case */
3937 info->bmiHeader.biHeight = 8;
3938 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3939 ok( ret == 8, "got %d\n", ret );
3940 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3941 memset( dib_bits, 0xaa, 64 * 4 );
3943 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3944 ok( ret == 5, "got %d\n", ret );
3945 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3946 ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
3947 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3948 memset( dib_bits, 0xaa, 64 * 4 );
3950 info->bmiHeader.biHeight = 16;
3951 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3952 ok( ret == 12, "got %d\n", ret );
3953 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3954 ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
3955 memset( dib_bits, 0xaa, 64 * 4 );
3957 info->bmiHeader.biHeight = 5;
3958 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3959 ok( ret == 2, "got %d\n", ret );
3960 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3961 ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
3962 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3963 memset( dib_bits, 0xaa, 64 * 4 );
3965 DeleteObject( dib );
3966 ReleaseDC( NULL, hdc );
3969 static void test_SetDIBits_RLE4(void)
3971 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3972 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3974 HDC hdc = GetDC( NULL );
3975 BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00, /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
3976 0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
3977 0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00, /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
3978 0x00, 0x02, 0x01, 0x02, 0x05, 0x87, /* dx=1, dy=2, 8, 7, 8, 7, 8 */
3979 0x00, 0x01 }; /* <eod> */
3982 DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
3983 0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
3984 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3985 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3986 0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
3987 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3988 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3989 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
3991 memset( info, 0, sizeof(bmi_buf) );
3993 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3994 info->bmiHeader.biWidth = 8;
3995 info->bmiHeader.biHeight = 8;
3996 info->bmiHeader.biPlanes = 1;
3997 info->bmiHeader.biBitCount = 32;
3998 info->bmiHeader.biCompression = BI_RGB;
4000 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4001 memset( dib_bits, 0xaa, 64 * 4 );
4003 info->bmiHeader.biBitCount = 4;
4004 info->bmiHeader.biCompression = BI_RLE4;
4005 info->bmiHeader.biSizeImage = sizeof(rle4_data);
4007 for (i = 0; i < 16; i++)
4009 info->bmiColors[i].rgbRed = i;
4010 info->bmiColors[i].rgbGreen = i;
4011 info->bmiColors[i].rgbBlue = i;
4012 info->bmiColors[i].rgbReserved = 0;
4015 ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
4016 ok( ret == 8, "got %d\n", ret );
4017 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
4018 memset( dib_bits, 0xaa, 64 * 4 );
4020 DeleteObject( dib );
4021 ReleaseDC( NULL, hdc );
4024 static void test_SetDIBits_RLE8(void)
4026 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
4027 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
4029 HDC hdc = GetDC( NULL );
4030 BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00, /* 2, 2, 2, f0, f0, f0, f0, <eol> */
4031 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4032 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4033 0x00, 0x01 }; /* <eod> */
4036 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4037 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4038 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4039 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4040 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4041 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4042 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4043 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4044 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4045 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4046 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4047 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4048 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4049 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4050 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4051 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4053 memset( info, 0, sizeof(bmi_buf) );
4055 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4056 info->bmiHeader.biWidth = 8;
4057 info->bmiHeader.biHeight = 8;
4058 info->bmiHeader.biPlanes = 1;
4059 info->bmiHeader.biBitCount = 32;
4060 info->bmiHeader.biCompression = BI_RGB;
4062 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4063 memset( dib_bits, 0xaa, 64 * 4 );
4065 info->bmiHeader.biBitCount = 8;
4066 info->bmiHeader.biCompression = BI_RLE8;
4067 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4069 for (i = 0; i < 256; i++)
4071 info->bmiColors[i].rgbRed = i;
4072 info->bmiColors[i].rgbGreen = i;
4073 info->bmiColors[i].rgbBlue = i;
4074 info->bmiColors[i].rgbReserved = 0;
4077 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4078 ok( ret == 8, "got %d\n", ret );
4079 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4080 memset( dib_bits, 0xaa, 64 * 4 );
4082 /* startscan and lines are ignored, unless lines == 0 */
4083 ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4084 ok( ret == 8, "got %d\n", ret );
4085 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4086 memset( dib_bits, 0xaa, 64 * 4 );
4088 ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4089 ok( ret == 8, "got %d\n", ret );
4090 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4091 memset( dib_bits, 0xaa, 64 * 4 );
4093 ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4094 ok( ret == 0, "got %d\n", ret );
4095 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4096 memset( dib_bits, 0xaa, 64 * 4 );
4098 /* reduce width to 4, left-hand side of dst is touched. */
4099 info->bmiHeader.biWidth = 4;
4100 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4101 ok( ret == 8, "got %d\n", ret );
4102 for (i = 0; i < 64; i++)
4104 DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4105 ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4107 memset( dib_bits, 0xaa, 64 * 4 );
4109 /* Show that the top lines are aligned by adjusting the height of the src */
4111 /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4112 info->bmiHeader.biWidth = 8;
4113 info->bmiHeader.biHeight = 4;
4114 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4115 ok( ret == 4, "got %d\n", ret );
4116 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4117 ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4118 memset( dib_bits, 0xaa, 64 * 4 );
4120 /* increase the height to 9 -> everything moves down one row. */
4121 info->bmiHeader.biHeight = 9;
4122 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4123 ok( ret == 9, "got %d\n", ret );
4124 ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4125 for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4126 memset( dib_bits, 0xaa, 64 * 4 );
4128 /* top-down compressed dibs are invalid */
4129 info->bmiHeader.biHeight = -8;
4130 SetLastError( 0xdeadbeef );
4131 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4132 ok( ret == 0, "got %d\n", ret );
4133 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4134 DeleteObject( dib );
4138 info->bmiHeader.biHeight = -8;
4139 info->bmiHeader.biBitCount = 32;
4140 info->bmiHeader.biCompression = BI_RGB;
4141 info->bmiHeader.biSizeImage = 0;
4143 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4144 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4146 info->bmiHeader.biHeight = 8;
4147 info->bmiHeader.biBitCount = 8;
4148 info->bmiHeader.biCompression = BI_RLE8;
4149 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4151 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4152 ok( ret == 8, "got %d\n", ret );
4153 ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4154 memset( dib_bits, 0xaa, 64 * 4 );
4156 info->bmiHeader.biHeight = 4;
4157 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4158 ok( ret == 4, "got %d\n", ret );
4159 ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4160 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4161 memset( dib_bits, 0xaa, 64 * 4 );
4163 info->bmiHeader.biHeight = 9;
4164 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4165 ok( ret == 9, "got %d\n", ret );
4166 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4167 ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4168 memset( dib_bits, 0xaa, 64 * 4 );
4170 DeleteObject( dib );
4172 ReleaseDC( NULL, hdc );
4175 static void test_SetDIBitsToDevice(void)
4177 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
4178 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
4180 HDC hdc = CreateCompatibleDC( 0 );
4181 DWORD data[128], inverted_data[128];
4185 memset( info, 0, sizeof(bmi_buf) );
4187 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4188 info->bmiHeader.biWidth = 8;
4189 info->bmiHeader.biHeight = 8;
4190 info->bmiHeader.biPlanes = 1;
4191 info->bmiHeader.biBitCount = 32;
4192 info->bmiHeader.biCompression = BI_RGB;
4194 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4195 memset( dib_bits, 0xaa, 64 * 4 );
4196 SelectObject( hdc, dib );
4198 for (i = 0; i < 128; i++)
4201 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4206 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4207 ok( ret == 8, "got %d\n", ret );
4208 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4209 memset( dib_bits, 0xaa, 64 * 4 );
4211 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4212 ok( ret == 5, "got %d\n", ret );
4213 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4214 for (i = 8; i < 48; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4215 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4216 memset( dib_bits, 0xaa, 64 * 4 );
4218 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 3, 1, 5, data, info, DIB_RGB_COLORS );
4219 ok( ret == 5, "got %d\n", ret );
4220 for (i = 0; i < 24; i++) ok( dib_bits[i] == data[i + 16], "%d: got %08x\n", i, dib_bits[i] );
4221 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4222 memset( dib_bits, 0xaa, 64 * 4 );
4224 info->bmiHeader.biHeight = 16;
4225 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4226 ok( ret == 7, "got %d\n", ret );
4227 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4228 for (i = 8; i < 64; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4229 memset( dib_bits, 0xaa, 64 * 4 );
4231 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 8, 0, 6, 1, 12, data, info, DIB_RGB_COLORS );
4232 ok( ret == 12, "got %d\n", ret );
4233 for (i = 0; i < 40; i++) ok( dib_bits[i] == data[i + 56], "%d: got %08x\n", i, dib_bits[i] );
4234 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4235 memset( dib_bits, 0xaa, 64 * 4 );
4237 ret = SetDIBitsToDevice( hdc, 0, -4, 8, 8, 0, 3, 1, 12, data, info, DIB_RGB_COLORS );
4238 ok( ret == 10, "got %d\n", ret );
4239 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4240 for (i = 32; i < 64; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4241 memset( dib_bits, 0xaa, 64 * 4 );
4243 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, -3, 1, 12, data, info, DIB_RGB_COLORS );
4244 ok( ret == 4, "got %d\n", ret );
4245 for (i = 0; i < 32; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4246 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4247 memset( dib_bits, 0xaa, 64 * 4 );
4249 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 5, 0, -2, 1, 12, data, info, DIB_RGB_COLORS );
4250 ok( ret == 2, "got %d\n", ret );
4251 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4252 for (i = 32; i < 48; i++) ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4253 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4254 memset( dib_bits, 0xaa, 64 * 4 );
4256 info->bmiHeader.biHeight = 5;
4257 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 2, 2, data, info, DIB_RGB_COLORS );
4258 ok( ret == 2, "got %d\n", ret );
4259 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4260 for (i = 16; i < 32; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4261 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4262 memset( dib_bits, 0xaa, 64 * 4 );
4264 ret = SetDIBitsToDevice( hdc, 3, 3, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4265 ok( ret == 3, "got %d\n", ret );
4266 for (i = 0; i < 64; i++)
4267 if (i == 27 || i == 28 || i == 35 || i == 36)
4268 ok( dib_bits[i] == data[i - 18], "%d: got %08x\n", i, dib_bits[i] );
4270 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4271 memset( dib_bits, 0xaa, 64 * 4 );
4273 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4274 ok( ret == 5, "got %d\n", ret );
4275 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4276 memset( dib_bits, 0xaa, 64 * 4 );
4278 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4279 ok( ret == 0, "got %d\n", ret );
4280 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4281 memset( dib_bits, 0xaa, 64 * 4 );
4283 SetMapMode( hdc, MM_ANISOTROPIC );
4284 SetWindowExtEx( hdc, 3, 3, NULL );
4285 ret = SetDIBitsToDevice( hdc, 2, 2, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4286 ok( ret == 3, "got %d\n", ret );
4287 for (i = 0; i < 64; i++)
4288 if (i == 41 || i == 42 || i == 49 || i == 50)
4289 ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4291 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4292 memset( dib_bits, 0xaa, 64 * 4 );
4294 SetWindowExtEx( hdc, -1, -1, NULL );
4295 ret = SetDIBitsToDevice( hdc, 2, 2, 4, 4, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4296 ok( ret == 4, "got %d\n", ret );
4297 for (i = 0; i < 64; i++)
4298 if (i == 48 || i == 49 || i == 56 || i == 57)
4299 ok( dib_bits[i] == data[i - 37], "%d: got %08x\n", i, dib_bits[i] );
4301 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4302 memset( dib_bits, 0xaa, 64 * 4 );
4303 SetMapMode( hdc, MM_TEXT );
4307 pSetLayout( hdc, LAYOUT_RTL );
4308 ret = SetDIBitsToDevice( hdc, 1, 2, 3, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4309 ok( ret == 3, "got %d\n", ret );
4310 for (i = 0; i < 64; i++)
4311 if (i == 36 || i == 37 || i == 38 || i == 44 || i == 45 || i == 46)
4312 ok( dib_bits[i] == data[i - 27], "%d: got %08x\n", i, dib_bits[i] );
4314 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4315 memset( dib_bits, 0xaa, 64 * 4 );
4316 pSetLayout( hdc, LAYOUT_LTR );
4320 info->bmiHeader.biHeight = -8;
4321 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4322 ok( ret == 8, "got %d\n", ret );
4323 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4324 memset( dib_bits, 0xaa, 64 * 4 );
4326 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4327 ok( ret == 5, "got %d\n", ret );
4328 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4329 for (i = 8; i < 48; i++) ok( dib_bits[i] == inverted_data[i + 80], "%d: got %08x\n", i, dib_bits[i] );
4330 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4331 memset( dib_bits, 0xaa, 64 * 4 );
4333 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 4, 1, 5, data, info, DIB_RGB_COLORS );
4334 ok( ret == 5, "got %d\n", ret );
4335 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4336 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4337 memset( dib_bits, 0xaa, 64 * 4 );
4339 info->bmiHeader.biHeight = -16;
4340 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4341 ok( ret == 12, "got %d\n", ret );
4342 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4343 for (i = 8; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4344 memset( dib_bits, 0xaa, 64 * 4 );
4346 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, 7, 1, 12, data, info, DIB_RGB_COLORS );
4347 ok( ret == 12, "got %d\n", ret );
4348 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4349 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4350 memset( dib_bits, 0xaa, 64 * 4 );
4352 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 4, 12, data, info, DIB_RGB_COLORS );
4353 ok( ret == 12, "got %d\n", ret );
4354 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4355 for (i = 32; i < 64; i++) ok( dib_bits[i] == inverted_data[i], "%d: got %08x\n", i, dib_bits[i] );
4356 memset( dib_bits, 0xaa, 64 * 4 );
4358 ret = SetDIBitsToDevice( hdc, 0, -3, 8, 8, 0, 2, 4, 12, data, info, DIB_RGB_COLORS );
4359 ok( ret == 12, "got %d\n", ret );
4360 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4361 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4362 memset( dib_bits, 0xaa, 64 * 4 );
4364 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, -2, 4, 12, data, info, DIB_RGB_COLORS );
4365 ok( ret == 12, "got %d\n", ret );
4366 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4367 for (i = 24; i < 40; i++) ok( dib_bits[i] == inverted_data[i + 8], "%d: got %08x\n", i, dib_bits[i] );
4368 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4369 memset( dib_bits, 0xaa, 64 * 4 );
4371 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 5, 12, data, info, DIB_RGB_COLORS );
4372 ok( ret == 12, "got %d\n", ret );
4373 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4374 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4375 memset( dib_bits, 0xaa, 64 * 4 );
4377 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4378 ok( ret == 12, "got %d\n", ret );
4379 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4380 memset( dib_bits, 0xaa, 64 * 4 );
4382 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -2, -4, 0, 12, data, info, DIB_RGB_COLORS );
4383 ok( ret == 12, "got %d\n", ret );
4384 for (i = 0; i < 64; i++)
4385 if (i == 31 || i == 39 || i == 47 || i == 55 || i == 63)
4386 ok( dib_bits[i] == inverted_data[i + 1], "%d: got %08x\n", i, dib_bits[i] );
4388 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4389 memset( dib_bits, 0xaa, 64 * 4 );
4391 info->bmiHeader.biHeight = -5;
4392 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4393 ok( ret == 2, "got %d\n", ret );
4394 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4395 for (i = 8; i < 24; i++) ok( dib_bits[i] == inverted_data[i + 104], "%d: got %08x\n", i, dib_bits[i] );
4396 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4397 memset( dib_bits, 0xaa, 64 * 4 );
4399 ret = SetDIBitsToDevice( hdc, 5, 4, 2, 2, 6, 3, 1, 5, data, info, DIB_RGB_COLORS );
4400 ok( ret == 5, "got %d\n", ret );
4401 for (i = 0; i < 64; i++)
4402 if (i == 21 || i == 22 || i == 29 || i == 30)
4403 ok( dib_bits[i] == inverted_data[i + 89], "%d: got %08x\n", i, dib_bits[i] );
4405 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4406 memset( dib_bits, 0xaa, 64 * 4 );
4408 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4409 ok( ret == 5, "got %d\n", ret );
4410 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4411 memset( dib_bits, 0xaa, 64 * 4 );
4413 info->bmiHeader.biHeight = -8;
4415 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4416 DeleteObject( SelectObject( hdc, dib ));
4417 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4421 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4422 ok( ret == 8, "got %d\n", ret );
4423 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4424 memset( dib_bits, 0xaa, 64 * 4 );
4426 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4427 ok( ret == 5, "got %d\n", ret );
4428 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4429 for (i = 16; i < 56; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4430 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4431 memset( dib_bits, 0xaa, 64 * 4 );
4433 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 3, 0, 2, 1, 5, data, info, DIB_RGB_COLORS );
4434 ok( ret == 5, "got %d\n", ret );
4435 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4436 for (i = 24; i < 48; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4437 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4438 memset( dib_bits, 0xaa, 64 * 4 );
4440 info->bmiHeader.biHeight = -16;
4441 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4442 ok( ret == 12, "got %d\n", ret );
4443 for (i = 0; i < 56; i++) ok( dib_bits[i] == data[i + 40], "%d: got %08x\n", i, dib_bits[i] );
4444 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4445 memset( dib_bits, 0xaa, 64 * 4 );
4447 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -1, -8, 0, 12, data, info, DIB_RGB_COLORS );
4448 ok( ret == 12, "got %d\n", ret );
4449 for (i = 0; i < 64; i++)
4450 if (i == 6 || i == 7)
4451 ok( dib_bits[i] == data[i + 82], "%d: got %08x\n", i, dib_bits[i] );
4453 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4454 memset( dib_bits, 0xaa, 64 * 4 );
4456 info->bmiHeader.biHeight = -5;
4457 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4458 ok( ret == 2, "got %d\n", ret );
4459 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4460 for (i = 40; i < 56; i++) ok( dib_bits[i] == data[i - 40], "%d: got %08x\n", i, dib_bits[i] );
4461 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4462 memset( dib_bits, 0xaa, 64 * 4 );
4464 ret = SetDIBitsToDevice( hdc, 7, 2, 8, 8, 1, 0, 0, 5, data, info, DIB_RGB_COLORS );
4465 ok( ret == 5, "got %d\n", ret );
4466 for (i = 0; i < 64; i++)
4467 if (i == 47 || i == 55 || i == 63)
4468 ok( dib_bits[i] == data[i - 46], "%d: got %08x\n", i, dib_bits[i] );
4470 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4471 memset( dib_bits, 0xaa, 64 * 4 );
4473 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4474 ok( ret == 5, "got %d\n", ret );
4475 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4476 memset( dib_bits, 0xaa, 64 * 4 );
4480 info->bmiHeader.biHeight = 8;
4481 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4482 ok( ret == 8, "got %d\n", ret );
4483 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4484 memset( dib_bits, 0xaa, 64 * 4 );
4486 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4487 ok( ret == 5, "got %d\n", ret );
4488 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4489 for (i = 16; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4490 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4491 memset( dib_bits, 0xaa, 64 * 4 );
4493 info->bmiHeader.biHeight = 16;
4494 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4495 ok( ret == 7, "got %d\n", ret );
4496 for (i = 0; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4497 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4498 memset( dib_bits, 0xaa, 64 * 4 );
4500 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, 0, -4, 1, 12, data, info, DIB_RGB_COLORS );
4501 ok( ret == 3, "got %d\n", ret );
4502 for (i = 0; i < 64; i++)
4503 if ((i >= 36 && i <= 39) || (i >= 44 && i <= 47) || (i >= 52 && i <= 55))
4504 ok( dib_bits[i] == inverted_data[i + 68], "%d: got %08x\n", i, dib_bits[i] );
4506 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4507 memset( dib_bits, 0xaa, 64 * 4 );
4509 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, -30, -30, 1, 12, data, info, DIB_RGB_COLORS );
4510 ok( ret == 0, "got %d\n", ret );
4511 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4512 memset( dib_bits, 0xaa, 64 * 4 );
4514 ret = SetDIBitsToDevice( hdc, 5, -5, 8, 16, -2, -4, 4, 12, data, info, DIB_RGB_COLORS );
4515 ok( ret == 8, "got %d\n", ret );
4516 for (i = 0; i < 64; i++)
4517 if (i == 7 || i == 15 || i == 23)
4518 ok( dib_bits[i] == inverted_data[i + 97], "%d: got %08x\n", i, dib_bits[i] );
4520 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4521 memset( dib_bits, 0xaa, 64 * 4 );
4523 info->bmiHeader.biHeight = 5;
4524 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4525 ok( ret == 2, "got %d\n", ret );
4526 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4527 for (i = 40; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4528 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4529 memset( dib_bits, 0xaa, 64 * 4 );
4531 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4532 ok( ret == 5, "got %d\n", ret );
4533 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4534 memset( dib_bits, 0xaa, 64 * 4 );
4537 DeleteObject( dib );
4540 static void test_SetDIBitsToDevice_RLE8(void)
4542 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
4543 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
4545 HDC hdc = CreateCompatibleDC( 0 );
4546 BYTE rle8_data[20] = { 0x04, 0x02, 0x03, 0xf0, 0x00, 0x00, /* 2, 2, 2, 2, f0, f0, f0, <eol> */
4547 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4548 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4549 0x00, 0x01 }; /* <eod> */
4552 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4553 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4554 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4555 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4556 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4557 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4558 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4559 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4560 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4561 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4562 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4563 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4564 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4565 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4566 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4567 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4569 memset( info, 0, sizeof(bmi_buf) );
4571 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4572 info->bmiHeader.biWidth = 8;
4573 info->bmiHeader.biHeight = 8;
4574 info->bmiHeader.biPlanes = 1;
4575 info->bmiHeader.biBitCount = 32;
4576 info->bmiHeader.biCompression = BI_RGB;
4578 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4579 memset( dib_bits, 0xaa, 64 * 4 );
4580 SelectObject( hdc, dib );
4582 info->bmiHeader.biBitCount = 8;
4583 info->bmiHeader.biCompression = BI_RLE8;
4584 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4586 for (i = 0; i < 256; i++)
4588 info->bmiColors[i].rgbRed = i;
4589 info->bmiColors[i].rgbGreen = i;
4590 info->bmiColors[i].rgbBlue = i;
4591 info->bmiColors[i].rgbReserved = 0;
4594 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4595 ok( ret == 8, "got %d\n", ret );
4596 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4597 memset( dib_bits, 0xaa, 64 * 4 );
4599 /* startscan and lines are ignored, unless lines == 0 */
4600 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4601 ok( ret == 8, "got %d\n", ret );
4602 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4603 memset( dib_bits, 0xaa, 64 * 4 );
4605 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4606 ok( ret == 8, "got %d\n", ret );
4607 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4608 memset( dib_bits, 0xaa, 64 * 4 );
4610 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4611 ok( ret == 0, "got %d\n", ret );
4612 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4613 memset( dib_bits, 0xaa, 64 * 4 );
4615 info->bmiHeader.biWidth = 2;
4616 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4617 ok( ret == 8, "got %d\n", ret );
4618 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4619 memset( dib_bits, 0xaa, 64 * 4 );
4621 info->bmiHeader.biWidth = 8;
4622 info->bmiHeader.biHeight = 2;
4623 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4624 ok( ret == 2, "got %d\n", ret );
4625 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4626 memset( dib_bits, 0xaa, 64 * 4 );
4628 info->bmiHeader.biHeight = 9;
4629 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4630 ok( ret == 9, "got %d\n", ret );
4631 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4632 memset( dib_bits, 0xaa, 64 * 4 );
4634 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4635 ok( ret == 9, "got %d\n", ret );
4636 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4637 memset( dib_bits, 0xaa, 64 * 4 );
4639 info->bmiHeader.biHeight = 8;
4640 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 9, rle8_data, info, DIB_RGB_COLORS );
4641 ok( ret == 8, "got %d\n", ret );
4642 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4643 memset( dib_bits, 0xaa, 64 * 4 );
4645 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4646 ok( ret == 8, "got %d\n", ret );
4647 for (i = 0; i < 40; i++) ok( dib_bits[i] == bottom_up[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4648 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4649 memset( dib_bits, 0xaa, 64 * 4 );
4651 ret = SetDIBitsToDevice( hdc, 0, 3, 4, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4652 ok( ret == 8, "got %d\n", ret );
4653 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4654 for (i = 8; i < 40; i++)
4655 if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4656 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4657 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4658 memset( dib_bits, 0xaa, 64 * 4 );
4660 ret = SetDIBitsToDevice( hdc, 3, 3, 8, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4661 ok( ret == 8, "got %d\n", ret );
4662 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4663 for (i = 8; i < 40; i++)
4664 if ((i & 7) < 3) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4665 else ok( dib_bits[i] == bottom_up[i - 11], "%d: got %08x\n", i, dib_bits[i] );
4666 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4667 memset( dib_bits, 0xaa, 64 * 4 );
4669 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 4, 2, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4670 ok( ret == 8, "got %d\n", ret );
4671 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4672 for (i = 8; i < 40; i++)
4673 if ((i & 7) < 2) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4674 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4675 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4676 memset( dib_bits, 0xaa, 64 * 4 );
4678 info->bmiHeader.biWidth = 37;
4679 info->bmiHeader.biHeight = 37;
4680 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
4681 ok( ret == 37, "got %d\n", ret );
4682 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4683 for (i = 24; i < 64; i++)
4684 if (i == 52) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
4685 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4686 else ok( dib_bits[i] == bottom_up[i - 20], "%d: got %08x\n", i, dib_bits[i] );
4687 memset( dib_bits, 0xaa, 64 * 4 );
4689 /* top-down compressed dibs are invalid */
4690 info->bmiHeader.biWidth = 8;
4691 info->bmiHeader.biHeight = -8;
4692 SetLastError( 0xdeadbeef );
4693 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4694 ok( ret == 0, "got %d\n", ret );
4695 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4699 info->bmiHeader.biHeight = -8;
4700 info->bmiHeader.biBitCount = 32;
4701 info->bmiHeader.biCompression = BI_RGB;
4702 info->bmiHeader.biSizeImage = 0;
4704 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4705 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4706 DeleteObject( SelectObject( hdc, dib ));
4708 info->bmiHeader.biHeight = 8;
4709 info->bmiHeader.biBitCount = 8;
4710 info->bmiHeader.biCompression = BI_RLE8;
4711 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4713 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4714 ok( ret == 8, "got %d\n", ret );
4715 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4716 memset( dib_bits, 0xaa, 64 * 4 );
4718 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4719 ok( ret == 8, "got %d\n", ret );
4720 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4721 memset( dib_bits, 0xaa, 64 * 4 );
4723 info->bmiHeader.biHeight = 4;
4724 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4725 ok( ret == 4, "got %d\n", ret );
4726 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4727 memset( dib_bits, 0xaa, 64 * 4 );
4729 info->bmiHeader.biHeight = 9;
4730 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4731 ok( ret == 9, "got %d\n", ret );
4732 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4733 memset( dib_bits, 0xaa, 64 * 4 );
4735 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4736 ok( ret == 9, "got %d\n", ret );
4737 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4738 memset( dib_bits, 0xaa, 64 * 4 );
4740 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 6, 2, 2, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4741 ok( ret == 9, "got %d\n", ret );
4742 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4743 for (i = 24; i < 64; i++) ok( dib_bits[i] == top_down[i - 24], "%d: got %08x\n", i, dib_bits[i] );
4744 memset( dib_bits, 0xaa, 64 * 4 );
4746 info->bmiHeader.biWidth = 37;
4747 info->bmiHeader.biHeight = 37;
4748 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
4749 ok( ret == 37, "got %d\n", ret );
4750 for (i = 0; i < 40; i++)
4751 if (i == 12) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
4752 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4753 else ok( dib_bits[i] == top_down[i + 28], "%d: got %08x\n", i, dib_bits[i] );
4754 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4755 memset( dib_bits, 0xaa, 64 * 4 );
4758 DeleteObject( dib );
4765 hdll = GetModuleHandle("gdi32.dll");
4766 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
4767 pSetLayout = (void*)GetProcAddress(hdll, "SetLayout");
4769 test_createdibitmap();
4772 test_mono_dibsection();
4775 test_GetDIBits_selected_DIB(1);
4776 test_GetDIBits_selected_DIB(4);
4777 test_GetDIBits_selected_DIB(8);
4778 test_GetDIBits_selected_DDB(TRUE);
4779 test_GetDIBits_selected_DDB(FALSE);
4781 test_GetDIBits_BI_BITFIELDS();
4782 test_select_object();
4783 test_CreateBitmap();
4786 test_StretchDIBits();
4787 test_GdiAlphaBlend();
4788 test_32bit_bitmap_blt();
4789 test_bitmapinfoheadersize();
4792 test_GetDIBits_top_down(16);
4793 test_GetDIBits_top_down(24);
4794 test_GetDIBits_top_down(32);
4795 test_GetSetDIBits_rtl();
4796 test_GetDIBits_scanlines();
4798 test_SetDIBits_RLE4();
4799 test_SetDIBits_RLE8();
4800 test_SetDIBitsToDevice();
4801 test_SetDIBitsToDevice_RLE8();