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 );
932 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
935 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
936 "SetDIBitsToDevice succeeded for %u/%u/%u\n", bpp, planes, compr );
937 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
941 todo_wine ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
943 ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
947 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
948 "StretchDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
950 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
952 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
954 ok( !ret, "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
955 ok( bi->bmiHeader.biBitCount == bpp, "GetDIBits modified bpp %u/%u\n",
956 bpp, bi->bmiHeader.biBitCount );
958 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
959 bi->bmiHeader.biWidth = 2;
960 bi->bmiHeader.biHeight = 2;
961 bi->bmiHeader.biPlanes = planes;
962 bi->bmiHeader.biBitCount = bpp;
963 bi->bmiHeader.biCompression = compr;
964 bi->bmiHeader.biSizeImage = 1;
965 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
966 /* RLE allowed with valid biSizeImage */
967 if ((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)) expect_ok = TRUE;
969 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
973 todo_wine ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
975 ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
978 ok( !ret, "SetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
979 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
981 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
983 ok( !ret, "SetDIBitsToDevice succeeded for %u/%u/%u\n", bpp, planes, compr );
984 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
988 todo_wine ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
990 ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
993 ok( !ret, "StretchDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
995 bi->bmiHeader.biSizeImage = 0;
996 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
997 if (expect_ok || !bpp)
998 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
1000 ok( !ret, "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
1005 memset( bi, 0, sizeof(bi->bmiHeader) );
1006 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1007 bi->bmiHeader.biWidth = 2;
1008 bi->bmiHeader.biHeight = 2;
1009 bi->bmiHeader.biPlanes = 1;
1010 bi->bmiHeader.biBitCount = 16;
1011 bi->bmiHeader.biCompression = BI_BITFIELDS;
1012 bi->bmiHeader.biSizeImage = 0;
1013 *(DWORD *)&bi->bmiColors[0] = 0;
1014 *(DWORD *)&bi->bmiColors[1] = 0;
1015 *(DWORD *)&bi->bmiColors[2] = 0;
1017 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1018 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1019 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1020 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1021 /* other functions don't check */
1022 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1023 ok( hdib != NULL, "CreateDIBitmap failed with null bitfields\n" );
1024 DeleteObject( hdib );
1025 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1026 ok( ret, "SetDIBitsToDevice failed with null bitfields\n" );
1027 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1028 todo_wine ok( ret, "StretchDIBits failed with null bitfields\n" );
1029 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1030 ok( ret, "GetDIBits failed with null bitfields\n" );
1031 bi->bmiHeader.biPlanes = 1;
1032 bi->bmiHeader.biBitCount = 16;
1033 bi->bmiHeader.biCompression = BI_BITFIELDS;
1034 bi->bmiHeader.biSizeImage = 0;
1035 *(DWORD *)&bi->bmiColors[0] = 0;
1036 *(DWORD *)&bi->bmiColors[1] = 0;
1037 *(DWORD *)&bi->bmiColors[2] = 0;
1038 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1039 ok( ret, "GetDIBits failed with null bitfields\n" );
1041 /* all fields must be non-zero */
1042 *(DWORD *)&bi->bmiColors[0] = 3;
1043 *(DWORD *)&bi->bmiColors[1] = 0;
1044 *(DWORD *)&bi->bmiColors[2] = 7;
1045 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1046 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1047 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1048 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1050 /* garbage is ok though */
1051 *(DWORD *)&bi->bmiColors[0] = 0x55;
1052 *(DWORD *)&bi->bmiColors[1] = 0x44;
1053 *(DWORD *)&bi->bmiColors[2] = 0x33;
1054 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1055 ok( hdib != NULL, "CreateDIBSection failed with bad bitfields\n" );
1056 if (hdib) DeleteObject( hdib );
1057 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1058 todo_wine ok( ret, "SetDIBits failed with bad bitfields\n" );
1060 bi->bmiHeader.biWidth = -2;
1061 bi->bmiHeader.biHeight = 2;
1062 bi->bmiHeader.biBitCount = 32;
1063 bi->bmiHeader.biCompression = BI_RGB;
1064 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1065 ok( hdib == NULL, "CreateDIBSection succeeded with negative width\n" );
1066 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1067 ok( hdib == NULL, "CreateDIBitmap succeeded with negative width\n" );
1068 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1069 ok( !ret, "SetDIBits succeeded with negative width\n" );
1070 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1071 ok( !ret, "SetDIBitsToDevice succeeded with negative width\n" );
1072 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1073 ok( !ret, "StretchDIBits succeeded with negative width\n" );
1074 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1075 ok( !ret, "GetDIBits succeeded with negative width\n" );
1076 bi->bmiHeader.biWidth = -2;
1077 bi->bmiHeader.biHeight = 2;
1078 bi->bmiHeader.biBitCount = 32;
1079 bi->bmiHeader.biCompression = BI_RGB;
1080 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1081 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with negative width\n" );
1083 bi->bmiHeader.biWidth = 0;
1084 bi->bmiHeader.biHeight = 2;
1085 bi->bmiHeader.biBitCount = 32;
1086 bi->bmiHeader.biCompression = BI_RGB;
1087 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1088 ok( hdib == NULL, "CreateDIBSection succeeded with zero width\n" );
1089 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1090 ok( hdib != NULL, "CreateDIBitmap failed with zero width\n" );
1091 DeleteObject( hdib );
1092 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1093 ok( !ret || broken(ret), /* nt4 */ "SetDIBits succeeded with zero width\n" );
1094 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1095 ok( !ret || broken(ret), /* nt4 */ "SetDIBitsToDevice succeeded with zero width\n" );
1096 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1097 ok( !ret || broken(ret), /* nt4 */ "StretchDIBits succeeded with zero width\n" );
1098 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1099 ok( !ret, "GetDIBits succeeded with zero width\n" );
1100 bi->bmiHeader.biWidth = 0;
1101 bi->bmiHeader.biHeight = 2;
1102 bi->bmiHeader.biBitCount = 32;
1103 bi->bmiHeader.biCompression = BI_RGB;
1104 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1105 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero width\n" );
1107 bi->bmiHeader.biWidth = 2;
1108 bi->bmiHeader.biHeight = 0;
1109 bi->bmiHeader.biBitCount = 32;
1110 bi->bmiHeader.biCompression = BI_RGB;
1111 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1112 ok( hdib == NULL, "CreateDIBSection succeeded with zero height\n" );
1113 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1114 ok( hdib != NULL, "CreateDIBitmap failed with zero height\n" );
1115 DeleteObject( hdib );
1116 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1117 ok( !ret, "SetDIBits succeeded with zero height\n" );
1118 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1119 ok( !ret, "SetDIBitsToDevice succeeded with zero height\n" );
1120 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1121 ok( !ret, "StretchDIBits succeeded with zero height\n" );
1122 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1123 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1124 bi->bmiHeader.biWidth = 2;
1125 bi->bmiHeader.biHeight = 0;
1126 bi->bmiHeader.biBitCount = 32;
1127 bi->bmiHeader.biCompression = BI_RGB;
1128 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1129 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1132 DeleteObject( hbmp );
1133 ReleaseDC( 0, hdc );
1136 static void test_mono_dibsection(void)
1139 HBITMAP old_bm, mono_ds;
1140 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
1141 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
1148 memdc = CreateCompatibleDC(hdc);
1150 memset(pbmi, 0, sizeof(bmibuf));
1151 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
1152 pbmi->bmiHeader.biHeight = 10;
1153 pbmi->bmiHeader.biWidth = 10;
1154 pbmi->bmiHeader.biBitCount = 1;
1155 pbmi->bmiHeader.biPlanes = 1;
1156 pbmi->bmiHeader.biCompression = BI_RGB;
1157 pbmi->bmiColors[0].rgbRed = 0xff;
1158 pbmi->bmiColors[0].rgbGreen = 0xff;
1159 pbmi->bmiColors[0].rgbBlue = 0xff;
1160 pbmi->bmiColors[1].rgbRed = 0x0;
1161 pbmi->bmiColors[1].rgbGreen = 0x0;
1162 pbmi->bmiColors[1].rgbBlue = 0x0;
1165 * First dib section is 'inverted' ie color[0] is white, color[1] is black
1168 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1169 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1170 old_bm = SelectObject(memdc, mono_ds);
1172 /* black border, white interior */
1173 Rectangle(memdc, 0, 0, 10, 10);
1174 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1175 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1177 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1179 memset(bits, 0, sizeof(bits));
1182 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1183 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1185 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1187 pbmi->bmiColors[0].rgbRed = 0x0;
1188 pbmi->bmiColors[0].rgbGreen = 0x0;
1189 pbmi->bmiColors[0].rgbBlue = 0x0;
1190 pbmi->bmiColors[1].rgbRed = 0xff;
1191 pbmi->bmiColors[1].rgbGreen = 0xff;
1192 pbmi->bmiColors[1].rgbBlue = 0xff;
1194 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1195 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1197 SelectObject(memdc, old_bm);
1198 DeleteObject(mono_ds);
1201 * Next dib section is 'normal' ie color[0] is black, color[1] is white
1204 pbmi->bmiColors[0].rgbRed = 0x0;
1205 pbmi->bmiColors[0].rgbGreen = 0x0;
1206 pbmi->bmiColors[0].rgbBlue = 0x0;
1207 pbmi->bmiColors[1].rgbRed = 0xff;
1208 pbmi->bmiColors[1].rgbGreen = 0xff;
1209 pbmi->bmiColors[1].rgbBlue = 0xff;
1211 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1212 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1213 old_bm = SelectObject(memdc, mono_ds);
1215 /* black border, white interior */
1216 Rectangle(memdc, 0, 0, 10, 10);
1217 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
1218 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
1220 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
1222 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1223 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1225 /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
1227 pbmi->bmiColors[0].rgbRed = 0xff;
1228 pbmi->bmiColors[0].rgbGreen = 0xff;
1229 pbmi->bmiColors[0].rgbBlue = 0xff;
1230 pbmi->bmiColors[1].rgbRed = 0x0;
1231 pbmi->bmiColors[1].rgbGreen = 0x0;
1232 pbmi->bmiColors[1].rgbBlue = 0x0;
1234 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1235 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1238 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
1241 pbmi->bmiColors[0].rgbRed = 0xff;
1242 pbmi->bmiColors[0].rgbGreen = 0xff;
1243 pbmi->bmiColors[0].rgbBlue = 0xff;
1244 pbmi->bmiColors[1].rgbRed = 0x0;
1245 pbmi->bmiColors[1].rgbGreen = 0x0;
1246 pbmi->bmiColors[1].rgbBlue = 0x0;
1247 num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors);
1248 ok(num == 2, "num = %d\n", num);
1250 /* black border, white interior */
1251 Rectangle(memdc, 0, 0, 10, 10);
1252 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1253 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1255 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1257 memset(bits, 0, sizeof(bits));
1260 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1261 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1263 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1265 pbmi->bmiColors[0].rgbRed = 0x0;
1266 pbmi->bmiColors[0].rgbGreen = 0x0;
1267 pbmi->bmiColors[0].rgbBlue = 0x0;
1268 pbmi->bmiColors[1].rgbRed = 0xff;
1269 pbmi->bmiColors[1].rgbGreen = 0xff;
1270 pbmi->bmiColors[1].rgbBlue = 0xff;
1272 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1273 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1275 SelectObject(memdc, old_bm);
1276 DeleteObject(mono_ds);
1279 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
1282 pbmi->bmiColors[0].rgbRed = 0xff;
1283 pbmi->bmiColors[0].rgbGreen = 0x0;
1284 pbmi->bmiColors[0].rgbBlue = 0x0;
1285 pbmi->bmiColors[1].rgbRed = 0xfe;
1286 pbmi->bmiColors[1].rgbGreen = 0x0;
1287 pbmi->bmiColors[1].rgbBlue = 0x0;
1289 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1290 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1291 old_bm = SelectObject(memdc, mono_ds);
1293 /* black border, white interior */
1294 Rectangle(memdc, 0, 0, 10, 10);
1295 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1296 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1298 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1300 pbmi->bmiColors[0].rgbRed = 0x0;
1301 pbmi->bmiColors[0].rgbGreen = 0x0;
1302 pbmi->bmiColors[0].rgbBlue = 0x0;
1303 pbmi->bmiColors[1].rgbRed = 0xff;
1304 pbmi->bmiColors[1].rgbGreen = 0xff;
1305 pbmi->bmiColors[1].rgbBlue = 0xff;
1307 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1308 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1310 /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
1312 pbmi->bmiColors[0].rgbRed = 0xff;
1313 pbmi->bmiColors[0].rgbGreen = 0xff;
1314 pbmi->bmiColors[0].rgbBlue = 0xff;
1315 pbmi->bmiColors[1].rgbRed = 0x0;
1316 pbmi->bmiColors[1].rgbGreen = 0x0;
1317 pbmi->bmiColors[1].rgbBlue = 0x0;
1319 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1320 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1322 SelectObject(memdc, old_bm);
1323 DeleteObject(mono_ds);
1329 static void test_bitmap(void)
1331 char buf[256], buf_cmp[256];
1332 HBITMAP hbmp, hbmp_old;
1338 hdc = CreateCompatibleDC(0);
1341 SetLastError(0xdeadbeef);
1342 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1345 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1346 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1347 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1352 SetLastError(0xdeadbeef);
1353 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1356 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1357 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1358 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1363 SetLastError(0xdeadbeef);
1364 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1365 ok(!hbmp, "CreateBitmap should fail\n");
1367 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1368 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1372 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1373 assert(hbmp != NULL);
1375 ret = GetObject(hbmp, sizeof(bm), &bm);
1376 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1378 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1379 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1380 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1381 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1382 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1383 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1384 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1386 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1387 assert(sizeof(buf) == sizeof(buf_cmp));
1389 ret = GetBitmapBits(hbmp, 0, NULL);
1390 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1392 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1393 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1395 memset(buf, 0xAA, sizeof(buf));
1396 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1397 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1398 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1400 hbmp_old = SelectObject(hdc, hbmp);
1402 ret = GetObject(hbmp, sizeof(bm), &bm);
1403 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1405 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1406 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1407 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1408 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1409 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1410 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1411 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1413 memset(buf, 0xAA, sizeof(buf));
1414 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1415 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1416 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1418 hbmp_old = SelectObject(hdc, hbmp_old);
1419 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1421 /* test various buffer sizes for GetObject */
1422 ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
1423 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1425 ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1426 ok(ret == 0, "%d != 0\n", ret);
1428 ret = GetObject(hbmp, 0, &bm);
1429 ok(ret == 0, "%d != 0\n", ret);
1431 ret = GetObject(hbmp, 1, &bm);
1432 ok(ret == 0, "%d != 0\n", ret);
1438 static void test_bmBits(void)
1444 memset(bits, 0, sizeof(bits));
1445 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1446 ok(hbmp != NULL, "CreateBitmap failed\n");
1448 memset(&bmp, 0xFF, sizeof(bmp));
1449 ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1450 "GetObject failed or returned a wrong structure size\n");
1451 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1456 static void test_GetDIBits_selected_DIB(UINT bpp)
1459 char bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1460 char bmibuf2[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1461 BITMAPINFO *info = (BITMAPINFO *)bmibuf;
1462 BITMAPINFO *info2 = (BITMAPINFO *)bmibuf2;
1465 UINT dib_size, dib32_size;
1472 /* Create a DIB section with a color table */
1474 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1475 info->bmiHeader.biWidth = 32;
1476 info->bmiHeader.biHeight = 32;
1477 info->bmiHeader.biPlanes = 1;
1478 info->bmiHeader.biBitCount = bpp;
1479 info->bmiHeader.biCompression = BI_RGB;
1480 info->bmiHeader.biXPelsPerMeter = 0;
1481 info->bmiHeader.biYPelsPerMeter = 0;
1482 info->bmiHeader.biClrUsed = 0;
1483 info->bmiHeader.biClrImportant = 0;
1485 for (i=0; i < (1u << bpp); i++)
1487 BYTE c = i * (1 << (8 - bpp));
1488 info->bmiColors[i].rgbRed = c;
1489 info->bmiColors[i].rgbGreen = c;
1490 info->bmiColors[i].rgbBlue = c;
1491 info->bmiColors[i].rgbReserved = 0;
1494 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1495 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1496 dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1498 /* Set the bits of the DIB section */
1499 for (i=0; i < dib_size; i++)
1501 ((BYTE *)bits)[i] = i % 256;
1504 /* Select the DIB into a DC */
1505 dib_dc = CreateCompatibleDC(NULL);
1506 old_bmp = SelectObject(dib_dc, dib);
1507 dc = CreateCompatibleDC(NULL);
1508 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
1510 /* Copy the DIB attributes but not the color table */
1511 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1513 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1514 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1516 /* Compare the color table and the bits */
1517 for (i=0; i < (1u << bpp); i++)
1518 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1519 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1520 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1521 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1522 "color table entry %d differs (bpp %d)\n", i, bpp );
1524 ok( !memcmp( bits, bits2, dib_size ), "bit mismatch (bpp %d)\n", bpp );
1526 /* Test various combinations of lines = 0 and bits2 = NULL */
1527 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1528 res = GetDIBits( dc, dib, 0, 0, bits2, info2, DIB_RGB_COLORS );
1529 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1530 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1531 "color table mismatch (bpp %d)\n", bpp );
1533 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1534 res = GetDIBits( dc, dib, 0, 0, NULL, info2, DIB_RGB_COLORS );
1535 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1536 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1537 "color table mismatch (bpp %d)\n", bpp );
1539 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1540 res = GetDIBits( dc, dib, 0, info->bmiHeader.biHeight, NULL, info2, DIB_RGB_COLORS );
1541 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1542 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1543 "color table mismatch (bpp %d)\n", bpp );
1545 /* Map into a 32bit-DIB */
1546 info2->bmiHeader.biBitCount = 32;
1547 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1548 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1550 /* Check if last pixel was set */
1551 pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
1552 ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
1554 HeapFree(GetProcessHeap(), 0, bits2);
1557 SelectObject(dib_dc, old_bmp);
1562 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1565 char bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1566 char bmibuf2[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1567 BITMAPINFO *info = (BITMAPINFO *)bmibuf;
1568 BITMAPINFO *info2 = (BITMAPINFO *)bmibuf2;
1578 width = height = 16;
1580 /* Create a DDB (device-dependent bitmap) */
1584 ddb = CreateBitmap(width, height, 1, 1, NULL);
1588 HDC screen_dc = GetDC(NULL);
1589 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1590 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1591 ReleaseDC(NULL, screen_dc);
1594 /* Set the pixels */
1595 ddb_dc = CreateCompatibleDC(NULL);
1596 old_bmp = SelectObject(ddb_dc, ddb);
1597 for (i = 0; i < width; i++)
1599 for (j=0; j < height; j++)
1601 BYTE c = (i * width + j) % 256;
1602 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1605 SelectObject(ddb_dc, old_bmp);
1607 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1608 info->bmiHeader.biWidth = width;
1609 info->bmiHeader.biHeight = height;
1610 info->bmiHeader.biPlanes = 1;
1611 info->bmiHeader.biBitCount = bpp;
1612 info->bmiHeader.biCompression = BI_RGB;
1614 dc = CreateCompatibleDC(NULL);
1616 /* Fill in biSizeImage */
1617 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1618 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1620 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1621 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1624 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1625 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1627 /* Copy the DIB attributes but not the color table */
1628 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1630 /* Select the DDB into another DC */
1631 old_bmp = SelectObject(ddb_dc, ddb);
1634 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1635 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1637 /* Compare the color table and the bits */
1640 for (i=0; i < (1u << bpp); i++)
1641 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1642 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1643 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1644 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1645 "color table entry %d differs (bpp %d)\n", i, bpp );
1648 ok( !memcmp( bits, bits2, info->bmiHeader.biSizeImage ), "bit mismatch (bpp %d)\n", bpp );
1650 /* Test the palette */
1651 if (info2->bmiHeader.biBitCount <= 8)
1653 WORD *colors = (WORD*)info2->bmiColors;
1655 /* Get the palette indices */
1656 res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1657 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1659 for (i = 0; i < (1 << info->bmiHeader.biBitCount); i++)
1660 ok( colors[i] == i, "%d: got %d (bpp %d)\n", i, colors[i], bpp );
1663 HeapFree(GetProcessHeap(), 0, bits2);
1664 HeapFree(GetProcessHeap(), 0, bits);
1667 SelectObject(ddb_dc, old_bmp);
1672 static void test_GetDIBits(void)
1674 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1675 static const BYTE bmp_bits_1[16 * 2] =
1677 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1678 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1679 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1680 0xff,0xff, 0,0, 0xff,0xff, 0,0
1682 /* 4-bytes aligned 1-bit DIB data: 16x16 */
1683 static const BYTE dib_bits_1[16 * 4] =
1685 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1686 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1687 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1688 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1690 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1691 static const BYTE bmp_bits_24[16 * 16*3] =
1693 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1694 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1695 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1696 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1697 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1698 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1699 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1700 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1701 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1702 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1703 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1704 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1705 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1706 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1707 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1708 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1709 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1710 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1711 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1712 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1713 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1714 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1715 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1716 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1717 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1718 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1719 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1720 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1721 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1722 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1723 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1724 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 /* 4-bytes aligned 24-bit DIB data: 16x16 */
1727 static const BYTE dib_bits_24[16 * 16*3] =
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,
1735 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1736 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1737 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1738 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1739 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1740 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1741 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1742 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1743 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1744 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1745 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1746 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1747 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1748 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1749 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1750 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1751 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1752 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1753 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1754 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1755 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1756 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1757 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1758 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1759 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1760 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1765 int i, bytes, lines;
1767 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1768 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1769 PALETTEENTRY pal_ents[20];
1773 /* 1-bit source bitmap data */
1774 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1775 ok(hbmp != 0, "CreateBitmap failed\n");
1777 memset(&bm, 0xAA, sizeof(bm));
1778 bytes = GetObject(hbmp, sizeof(bm), &bm);
1779 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1780 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1781 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1782 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1783 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1784 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1785 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1786 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1788 bytes = GetBitmapBits(hbmp, 0, NULL);
1789 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1790 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1791 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1792 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1794 /* retrieve 1-bit DIB data */
1795 memset(bi, 0, sizeof(*bi));
1796 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1797 bi->bmiHeader.biWidth = bm.bmWidth;
1798 bi->bmiHeader.biHeight = bm.bmHeight;
1799 bi->bmiHeader.biPlanes = 1;
1800 bi->bmiHeader.biBitCount = 1;
1801 bi->bmiHeader.biCompression = BI_RGB;
1802 bi->bmiHeader.biSizeImage = 0;
1803 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1804 SetLastError(0xdeadbeef);
1805 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1806 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1807 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1808 broken(GetLastError() == 0xdeadbeef), /* winnt */
1809 "wrong error %u\n", GetLastError());
1810 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1812 memset(buf, 0xAA, sizeof(buf));
1813 SetLastError(0xdeadbeef);
1814 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1815 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1816 lines, bm.bmHeight, GetLastError());
1817 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1819 /* the color table consists of black and white */
1820 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1821 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1822 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1823 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1824 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1825 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1826 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1827 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1828 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1829 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1830 for (i = 2; i < 256; i++)
1832 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1833 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1834 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1835 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1836 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1839 /* returned bits are DWORD aligned and upside down */
1840 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1842 /* Test the palette indices */
1843 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1844 SetLastError(0xdeadbeef);
1845 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1846 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1847 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1848 for (i = 2; i < 256; i++)
1849 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[1]);
1851 /* retrieve 24-bit DIB data */
1852 memset(bi, 0, sizeof(*bi));
1853 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1854 bi->bmiHeader.biWidth = bm.bmWidth;
1855 bi->bmiHeader.biHeight = bm.bmHeight;
1856 bi->bmiHeader.biPlanes = 1;
1857 bi->bmiHeader.biBitCount = 24;
1858 bi->bmiHeader.biCompression = BI_RGB;
1859 bi->bmiHeader.biSizeImage = 0;
1860 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1861 memset(buf, 0xAA, sizeof(buf));
1862 SetLastError(0xdeadbeef);
1863 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1864 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1865 lines, bm.bmHeight, GetLastError());
1866 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1868 /* the color table doesn't exist for 24-bit images */
1869 for (i = 0; i < 256; i++)
1871 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1872 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1873 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1874 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1875 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1878 /* returned bits are DWORD aligned and upside down */
1879 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1882 /* 24-bit source bitmap data */
1883 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1884 ok(hbmp != 0, "CreateBitmap failed\n");
1885 SetLastError(0xdeadbeef);
1886 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1887 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1888 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1889 lines, bm.bmHeight, GetLastError());
1891 memset(&bm, 0xAA, sizeof(bm));
1892 bytes = GetObject(hbmp, sizeof(bm), &bm);
1893 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1894 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1895 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1896 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1897 ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1898 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1899 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1900 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1902 bytes = GetBitmapBits(hbmp, 0, NULL);
1903 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
1904 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1905 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1906 bm.bmWidthBytes * bm.bmHeight, bytes);
1908 /* retrieve 1-bit DIB data */
1909 memset(bi, 0, sizeof(*bi));
1910 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1911 bi->bmiHeader.biWidth = bm.bmWidth;
1912 bi->bmiHeader.biHeight = bm.bmHeight;
1913 bi->bmiHeader.biPlanes = 1;
1914 bi->bmiHeader.biBitCount = 1;
1915 bi->bmiHeader.biCompression = BI_RGB;
1916 bi->bmiHeader.biSizeImage = 0;
1917 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1918 memset(buf, 0xAA, sizeof(buf));
1919 SetLastError(0xdeadbeef);
1920 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1921 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1922 lines, bm.bmHeight, GetLastError());
1923 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1925 /* the color table consists of black and white */
1926 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1927 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1928 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1929 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1930 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1931 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1932 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1933 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1934 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1935 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1936 for (i = 2; i < 256; i++)
1938 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1939 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1940 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1941 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1942 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1945 /* returned bits are DWORD aligned and upside down */
1946 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1948 /* Test the palette indices */
1949 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1950 SetLastError(0xdeadbeef);
1951 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1952 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1953 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1954 for (i = 2; i < 256; i++)
1955 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[i]);
1957 /* retrieve 4-bit DIB data */
1958 memset(bi, 0, sizeof(*bi));
1959 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1960 bi->bmiHeader.biWidth = bm.bmWidth;
1961 bi->bmiHeader.biHeight = bm.bmHeight;
1962 bi->bmiHeader.biPlanes = 1;
1963 bi->bmiHeader.biBitCount = 4;
1964 bi->bmiHeader.biCompression = BI_RGB;
1965 bi->bmiHeader.biSizeImage = 0;
1966 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1967 memset(buf, 0xAA, sizeof(buf));
1968 SetLastError(0xdeadbeef);
1969 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1970 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1971 lines, bm.bmHeight, GetLastError());
1973 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
1975 for (i = 0; i < 16; i++)
1978 int entry = i < 8 ? i : i + 4;
1980 if(entry == 7) entry = 12;
1981 else if(entry == 12) entry = 7;
1983 expect.rgbRed = pal_ents[entry].peRed;
1984 expect.rgbGreen = pal_ents[entry].peGreen;
1985 expect.rgbBlue = pal_ents[entry].peBlue;
1986 expect.rgbReserved = 0;
1988 ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
1989 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
1990 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
1991 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1992 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1995 /* retrieve 8-bit DIB data */
1996 memset(bi, 0, sizeof(*bi));
1997 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1998 bi->bmiHeader.biWidth = bm.bmWidth;
1999 bi->bmiHeader.biHeight = bm.bmHeight;
2000 bi->bmiHeader.biPlanes = 1;
2001 bi->bmiHeader.biBitCount = 8;
2002 bi->bmiHeader.biCompression = BI_RGB;
2003 bi->bmiHeader.biSizeImage = 0;
2004 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
2005 memset(buf, 0xAA, sizeof(buf));
2006 SetLastError(0xdeadbeef);
2007 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2008 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2009 lines, bm.bmHeight, GetLastError());
2011 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2013 for (i = 0; i < 256; i++)
2017 if (i < 10 || i >= 246)
2019 int entry = i < 10 ? i : i - 236;
2020 expect.rgbRed = pal_ents[entry].peRed;
2021 expect.rgbGreen = pal_ents[entry].peGreen;
2022 expect.rgbBlue = pal_ents[entry].peBlue;
2026 expect.rgbRed = (i & 0x07) << 5;
2027 expect.rgbGreen = (i & 0x38) << 2;
2028 expect.rgbBlue = i & 0xc0;
2030 expect.rgbReserved = 0;
2032 ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
2033 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2034 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2035 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
2036 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
2039 /* retrieve 24-bit DIB data */
2040 memset(bi, 0, sizeof(*bi));
2041 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2042 bi->bmiHeader.biWidth = bm.bmWidth;
2043 bi->bmiHeader.biHeight = bm.bmHeight;
2044 bi->bmiHeader.biPlanes = 1;
2045 bi->bmiHeader.biBitCount = 24;
2046 bi->bmiHeader.biCompression = BI_RGB;
2047 bi->bmiHeader.biSizeImage = 0;
2048 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
2049 memset(buf, 0xAA, sizeof(buf));
2050 SetLastError(0xdeadbeef);
2051 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2052 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2053 lines, bm.bmHeight, GetLastError());
2054 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2056 /* the color table doesn't exist for 24-bit images */
2057 for (i = 0; i < 256; i++)
2059 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
2060 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
2061 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2062 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
2063 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
2066 /* returned bits are DWORD aligned and upside down */
2067 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2073 static void test_GetDIBits_BI_BITFIELDS(void)
2075 /* Try a screen resolution detection technique
2076 * from the September 1999 issue of Windows Developer's Journal
2077 * which seems to be in widespread use.
2078 * http://www.lesher.ws/highcolor.html
2079 * http://www.lesher.ws/vidfmt.c
2080 * It hinges on being able to retrieve the bitmaps
2081 * for the three primary colors in non-paletted 16 bit mode.
2083 char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
2085 LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
2086 DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
2092 memset(dibinfo, 0, sizeof(dibinfo_buf));
2093 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2096 ok(hdc != NULL, "GetDC failed?\n");
2097 hbm = CreateCompatibleBitmap(hdc, 1, 1);
2098 ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
2100 /* Call GetDIBits to fill in bmiHeader. */
2101 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2102 ok(ret == 1, "GetDIBits failed\n");
2103 if (dibinfo->bmiHeader.biBitCount > 8)
2105 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2106 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2107 "compression is %u (%d bpp)\n", dibinfo->bmiHeader.biCompression, dibinfo->bmiHeader.biBitCount );
2109 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2111 ok( !bitmasks[0], "red mask is set\n" );
2112 ok( !bitmasks[1], "green mask is set\n" );
2113 ok( !bitmasks[2], "blue mask is set\n" );
2115 /* test with NULL bits pointer and correct bpp */
2116 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2117 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2118 ok(ret == 1, "GetDIBits failed\n");
2120 ok( bitmasks[0] != 0, "red mask is not set\n" );
2121 ok( bitmasks[1] != 0, "green mask is not set\n" );
2122 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2123 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2125 /* test with valid bits pointer */
2126 memset(dibinfo, 0, sizeof(dibinfo_buf));
2127 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2128 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2129 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2130 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2131 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2132 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2134 ok( bitmasks[0] != 0, "red mask is not set\n" );
2135 ok( bitmasks[1] != 0, "green mask is not set\n" );
2136 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2137 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2139 /* now with bits and 0 lines */
2140 memset(dibinfo, 0, sizeof(dibinfo_buf));
2141 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2142 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2143 SetLastError(0xdeadbeef);
2144 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2145 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2147 ok( !bitmasks[0], "red mask is set\n" );
2148 ok( !bitmasks[1], "green mask is set\n" );
2149 ok( !bitmasks[2], "blue mask is set\n" );
2150 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2152 memset(bitmasks, 0, 3*sizeof(DWORD));
2153 dibinfo->bmiHeader.biSizeImage = 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] != 0, "red mask is not set\n" );
2158 ok( bitmasks[1] != 0, "green mask is not set\n" );
2159 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2160 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2163 else skip("bitmap in colortable mode, skipping BI_BITFIELDS tests\n");
2167 /* same thing now with a 32-bpp DIB section */
2169 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2170 dibinfo->bmiHeader.biWidth = 1;
2171 dibinfo->bmiHeader.biHeight = 1;
2172 dibinfo->bmiHeader.biPlanes = 1;
2173 dibinfo->bmiHeader.biBitCount = 32;
2174 dibinfo->bmiHeader.biCompression = BI_RGB;
2175 dibinfo->bmiHeader.biSizeImage = 0;
2176 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2177 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2178 dibinfo->bmiHeader.biClrUsed = 0;
2179 dibinfo->bmiHeader.biClrImportant = 0;
2180 bitmasks[0] = 0x0000ff;
2181 bitmasks[1] = 0x00ff00;
2182 bitmasks[2] = 0xff0000;
2183 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2184 ok( hbm != 0, "failed to create bitmap\n" );
2186 memset(dibinfo, 0, sizeof(dibinfo_buf));
2187 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2188 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2189 ok(ret == 1, "GetDIBits failed\n");
2190 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2192 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2193 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2194 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2195 ok( !bitmasks[0], "red mask is set\n" );
2196 ok( !bitmasks[1], "green mask is set\n" );
2197 ok( !bitmasks[2], "blue mask is set\n" );
2199 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2200 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2201 ok(ret == 1, "GetDIBits failed\n");
2202 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2203 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2204 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2205 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2206 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2208 ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
2209 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2210 ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
2212 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2216 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2217 dibinfo->bmiHeader.biWidth = 1;
2218 dibinfo->bmiHeader.biHeight = 1;
2219 dibinfo->bmiHeader.biPlanes = 1;
2220 dibinfo->bmiHeader.biBitCount = 32;
2221 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2222 dibinfo->bmiHeader.biSizeImage = 0;
2223 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2224 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2225 dibinfo->bmiHeader.biClrUsed = 0;
2226 dibinfo->bmiHeader.biClrImportant = 0;
2227 bitmasks[0] = 0x0000ff;
2228 bitmasks[1] = 0x00ff00;
2229 bitmasks[2] = 0xff0000;
2230 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2231 ok( hbm != 0, "failed to create bitmap\n" );
2235 memset(dibinfo, 0, sizeof(dibinfo_buf));
2236 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2237 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2238 ok(ret == 1, "GetDIBits failed\n");
2240 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
2241 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2242 ok( !bitmasks[0], "red mask is set\n" );
2243 ok( !bitmasks[1], "green mask is set\n" );
2244 ok( !bitmasks[2], "blue mask is set\n" );
2246 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2247 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2248 ok(ret == 1, "GetDIBits failed\n");
2249 ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
2250 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2251 ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
2252 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2257 /* 24-bpp DIB sections don't have bitfields */
2259 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2260 dibinfo->bmiHeader.biWidth = 1;
2261 dibinfo->bmiHeader.biHeight = 1;
2262 dibinfo->bmiHeader.biPlanes = 1;
2263 dibinfo->bmiHeader.biBitCount = 24;
2264 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2265 dibinfo->bmiHeader.biSizeImage = 0;
2266 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2267 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2268 dibinfo->bmiHeader.biClrUsed = 0;
2269 dibinfo->bmiHeader.biClrImportant = 0;
2270 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2271 ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
2272 dibinfo->bmiHeader.biCompression = BI_RGB;
2273 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2274 ok( hbm != 0, "failed to create bitmap\n" );
2276 memset(dibinfo, 0, sizeof(dibinfo_buf));
2277 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2278 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2279 ok(ret == 1, "GetDIBits failed\n");
2280 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2282 ok( dibinfo->bmiHeader.biCompression == BI_RGB,
2283 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2284 ok( !bitmasks[0], "red mask is set\n" );
2285 ok( !bitmasks[1], "green mask is set\n" );
2286 ok( !bitmasks[2], "blue mask is set\n" );
2288 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2289 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2290 ok(ret == 1, "GetDIBits failed\n");
2291 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2292 ok( !bitmasks[0], "red mask is set\n" );
2293 ok( !bitmasks[1], "green mask is set\n" );
2294 ok( !bitmasks[2], "blue mask is set\n" );
2295 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2298 ReleaseDC(NULL, hdc);
2301 static void test_select_object(void)
2304 HBITMAP hbm, hbm_old;
2306 DWORD depths[] = {8, 15, 16, 24, 32};
2311 ok(hdc != 0, "GetDC(0) failed\n");
2312 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2313 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2315 hbm_old = SelectObject(hdc, hbm);
2316 ok(hbm_old == 0, "SelectObject should fail\n");
2321 hdc = CreateCompatibleDC(0);
2322 ok(hdc != 0, "GetDC(0) failed\n");
2323 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2324 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2326 hbm_old = SelectObject(hdc, hbm);
2327 ok(hbm_old != 0, "SelectObject failed\n");
2328 hbm_old = SelectObject(hdc, hbm_old);
2329 ok(hbm_old == hbm, "SelectObject failed\n");
2333 /* test an 1-bpp bitmap */
2334 planes = GetDeviceCaps(hdc, PLANES);
2337 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
2338 ok(hbm != 0, "CreateBitmap failed\n");
2340 hbm_old = SelectObject(hdc, hbm);
2341 ok(hbm_old != 0, "SelectObject failed\n");
2342 hbm_old = SelectObject(hdc, hbm_old);
2343 ok(hbm_old == hbm, "SelectObject failed\n");
2347 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
2348 /* test a color bitmap to dc bpp matching */
2349 planes = GetDeviceCaps(hdc, PLANES);
2350 bpp = GetDeviceCaps(hdc, BITSPIXEL);
2352 hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
2353 ok(hbm != 0, "CreateBitmap failed\n");
2355 hbm_old = SelectObject(hdc, hbm);
2356 if(depths[i] == bpp ||
2357 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
2359 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
2360 SelectObject(hdc, hbm_old);
2362 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
2365 memset(&bm, 0xAA, sizeof(bm));
2366 bytes = GetObject(hbm, sizeof(bm), &bm);
2367 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2368 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2369 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
2370 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
2371 ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2372 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
2373 if(depths[i] == 15) {
2374 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
2376 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2378 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2386 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
2391 ret = GetObjectType(hbmp);
2392 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
2394 ret = GetObject(hbmp, 0, 0);
2395 ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
2397 memset(&bm, 0xDA, sizeof(bm));
2398 SetLastError(0xdeadbeef);
2399 ret = GetObject(hbmp, sizeof(bm), &bm);
2400 if (!ret) /* XP, only for curObj2 */ return;
2401 ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
2402 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2403 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2404 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2405 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2406 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2407 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2408 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2411 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2413 static void test_CreateBitmap(void)
2416 HDC screenDC = GetDC(0);
2417 HDC hdc = CreateCompatibleDC(screenDC);
2420 /* all of these are the stock monochrome bitmap */
2421 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2422 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2423 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2424 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2425 HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2426 HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2428 /* these 2 are not the stock monochrome bitmap */
2429 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2430 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2432 HBITMAP old1 = SelectObject(hdc, bm2);
2433 HBITMAP old2 = SelectObject(screenDC, bm3);
2434 SelectObject(hdc, old1);
2435 SelectObject(screenDC, old2);
2437 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2438 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2439 bm, bm1, bm4, bm5, curObj1, old1);
2440 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2442 ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
2443 ok(old2 == 0, "old2 %p\n", old2);
2445 test_mono_1x1_bmp(bm);
2446 test_mono_1x1_bmp(bm1);
2447 test_mono_1x1_bmp(bm2);
2448 test_mono_1x1_bmp(bm3);
2449 test_mono_1x1_bmp(bm4);
2450 test_mono_1x1_bmp(bm5);
2451 test_mono_1x1_bmp(old1);
2452 test_mono_1x1_bmp(curObj1);
2462 ReleaseDC(0, screenDC);
2464 /* show that Windows ignores the provided bm.bmWidthBytes */
2468 bmp.bmWidthBytes = 28;
2470 bmp.bmBitsPixel = 1;
2472 bm = CreateBitmapIndirect(&bmp);
2473 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2474 test_mono_1x1_bmp(bm);
2477 /* Test how the bmBitsPixel field is treated */
2478 for(i = 1; i <= 33; i++) {
2482 bmp.bmWidthBytes = 28;
2484 bmp.bmBitsPixel = i;
2486 SetLastError(0xdeadbeef);
2487 bm = CreateBitmapIndirect(&bmp);
2489 DWORD error = GetLastError();
2490 ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
2491 ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2495 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2496 GetObject(bm, sizeof(bmp), &bmp);
2503 } else if(i <= 16) {
2505 } else if(i <= 24) {
2507 } else if(i <= 32) {
2510 ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2511 i, bmp.bmBitsPixel, expect);
2516 static void test_bitmapinfoheadersize(void)
2523 memset(&bmi, 0, sizeof(BITMAPINFO));
2524 bmi.bmiHeader.biHeight = 100;
2525 bmi.bmiHeader.biWidth = 512;
2526 bmi.bmiHeader.biBitCount = 24;
2527 bmi.bmiHeader.biPlanes = 1;
2529 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2531 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2532 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2534 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2536 SetLastError(0xdeadbeef);
2537 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2538 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2541 bmi.bmiHeader.biSize++;
2543 SetLastError(0xdeadbeef);
2544 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2546 broken(!hdib), /* Win98, WinMe */
2547 "CreateDIBSection error %d\n", GetLastError());
2550 bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2552 SetLastError(0xdeadbeef);
2553 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2555 broken(!hdib), /* Win98, WinMe */
2556 "CreateDIBSection error %d\n", GetLastError());
2559 bmi.bmiHeader.biSize++;
2561 SetLastError(0xdeadbeef);
2562 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2564 broken(!hdib), /* Win98, WinMe */
2565 "CreateDIBSection error %d\n", GetLastError());
2568 bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2570 SetLastError(0xdeadbeef);
2571 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2572 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2575 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2577 SetLastError(0xdeadbeef);
2578 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2580 broken(!hdib), /* Win95 */
2581 "CreateDIBSection error %d\n", GetLastError());
2584 memset(&bci, 0, sizeof(BITMAPCOREINFO));
2585 bci.bmciHeader.bcHeight = 100;
2586 bci.bmciHeader.bcWidth = 512;
2587 bci.bmciHeader.bcBitCount = 24;
2588 bci.bmciHeader.bcPlanes = 1;
2590 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2592 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2593 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2595 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2597 SetLastError(0xdeadbeef);
2598 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2599 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2602 bci.bmciHeader.bcSize++;
2604 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2605 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2607 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2609 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2610 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2615 static void test_get16dibits(void)
2617 BYTE bits[4 * (16 / sizeof(BYTE))];
2619 HDC screen_dc = GetDC(NULL);
2622 int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2624 int overwritten_bytes = 0;
2626 memset(bits, 0, sizeof(bits));
2627 hbmp = CreateBitmap(2, 2, 1, 16, bits);
2628 ok(hbmp != NULL, "CreateBitmap failed\n");
2630 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2633 memset(info, '!', info_len);
2634 memset(info, 0, sizeof(info->bmiHeader));
2636 info->bmiHeader.biSize = sizeof(info->bmiHeader);
2637 info->bmiHeader.biWidth = 2;
2638 info->bmiHeader.biHeight = 2;
2639 info->bmiHeader.biPlanes = 1;
2640 info->bmiHeader.biCompression = BI_RGB;
2642 ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2643 ok(ret != 0, "GetDIBits failed got %d\n", ret);
2645 for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2647 overwritten_bytes++;
2648 ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2650 HeapFree(GetProcessHeap(), 0, info);
2652 ReleaseDC(NULL, screen_dc);
2655 static BOOL compare_buffers_no_alpha(UINT32 *a, UINT32 *b, int length)
2658 for(i = 0; i < length; i++)
2659 if((a[i] & 0x00FFFFFF) != (b[i] & 0x00FFFFFF))
2664 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2665 DWORD dwRop, UINT32 expected, int line)
2667 *srcBuffer = 0xFEDCBA98;
2668 *dstBuffer = 0x89ABCDEF;
2669 Rectangle(hdcSrc, 0, 0, 1, 1); /* A null operation to ensure dibs are coerced to X11 */
2670 BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
2671 ok(expected == *dstBuffer,
2672 "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2673 dwRop, expected, *dstBuffer, line);
2676 static void test_BitBlt(void)
2678 HBITMAP bmpDst, bmpSrc;
2679 HBITMAP oldDst, oldSrc;
2680 HDC hdcScreen, hdcDst, hdcSrc;
2681 UINT32 *dstBuffer, *srcBuffer;
2682 HBRUSH hBrush, hOldBrush;
2683 BITMAPINFO bitmapInfo;
2685 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2686 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2687 bitmapInfo.bmiHeader.biWidth = 1;
2688 bitmapInfo.bmiHeader.biHeight = 1;
2689 bitmapInfo.bmiHeader.biPlanes = 1;
2690 bitmapInfo.bmiHeader.biBitCount = 32;
2691 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2692 bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2694 hdcScreen = CreateCompatibleDC(0);
2695 hdcDst = CreateCompatibleDC(hdcScreen);
2696 hdcSrc = CreateCompatibleDC(hdcDst);
2698 /* Setup the destination dib section */
2699 bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
2701 oldDst = SelectObject(hdcDst, bmpDst);
2703 hBrush = CreateSolidBrush(0x012345678);
2704 hOldBrush = SelectObject(hdcDst, hBrush);
2706 /* Setup the source dib section */
2707 bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
2709 oldSrc = SelectObject(hdcSrc, bmpSrc);
2711 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2712 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2713 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2714 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2715 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2716 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2717 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2718 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2719 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2720 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2721 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2722 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2723 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2724 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2725 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2728 SelectObject(hdcSrc, oldSrc);
2729 DeleteObject(bmpSrc);
2732 SelectObject(hdcDst, hOldBrush);
2733 DeleteObject(hBrush);
2734 SelectObject(hdcDst, oldDst);
2735 DeleteObject(bmpDst);
2739 DeleteDC(hdcScreen);
2742 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2743 DWORD dwRop, UINT32 expected, int line)
2745 *srcBuffer = 0xFEDCBA98;
2746 *dstBuffer = 0x89ABCDEF;
2747 StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
2748 ok(expected == *dstBuffer,
2749 "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2750 dwRop, expected, *dstBuffer, line);
2753 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2754 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2755 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2756 UINT32 expected[4], UINT32 legacy_expected[4], int line)
2758 memset(dstBuffer, 0, 16);
2759 StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2760 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
2761 ok(memcmp(dstBuffer, expected, 16) == 0 ||
2762 broken(compare_buffers_no_alpha(dstBuffer, legacy_expected, 4)),
2763 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2764 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2765 expected[0], expected[1], expected[2], expected[3],
2766 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2767 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2768 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2771 static void test_StretchBlt(void)
2773 HBITMAP bmpDst, bmpSrc;
2774 HBITMAP oldDst, oldSrc;
2775 HDC hdcScreen, hdcDst, hdcSrc;
2776 UINT32 *dstBuffer, *srcBuffer;
2777 HBRUSH hBrush, hOldBrush;
2778 BITMAPINFO biDst, biSrc;
2779 UINT32 expected[4], legacy_expected[4];
2781 memset(&biDst, 0, sizeof(BITMAPINFO));
2782 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2783 biDst.bmiHeader.biWidth = 2;
2784 biDst.bmiHeader.biHeight = -2;
2785 biDst.bmiHeader.biPlanes = 1;
2786 biDst.bmiHeader.biBitCount = 32;
2787 biDst.bmiHeader.biCompression = BI_RGB;
2788 memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
2790 hdcScreen = CreateCompatibleDC(0);
2791 hdcDst = CreateCompatibleDC(hdcScreen);
2792 hdcSrc = CreateCompatibleDC(hdcDst);
2795 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2797 oldDst = SelectObject(hdcDst, bmpDst);
2799 bmpSrc = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&srcBuffer,
2801 oldSrc = SelectObject(hdcSrc, bmpSrc);
2803 hBrush = CreateSolidBrush(0x012345678);
2804 hOldBrush = SelectObject(hdcDst, hBrush);
2806 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2807 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2808 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2809 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2810 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2811 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2812 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2813 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2814 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2815 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2816 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2817 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2818 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2819 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2820 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2822 SelectObject(hdcDst, hOldBrush);
2823 DeleteObject(hBrush);
2825 /* Top-down to top-down tests */
2826 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2827 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
2829 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2830 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2831 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2832 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2834 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2835 expected[2] = 0x00000000, expected[3] = 0x00000000;
2836 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2837 0, 0, 1, 1, 0, 0, 1, 1, expected, expected, __LINE__);
2839 expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
2840 expected[2] = 0xCAFED00D, expected[3] = 0xCAFED00D;
2841 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2842 0, 0, 2, 2, 0, 0, 1, 1, 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, 2, 2, expected, expected, __LINE__);
2849 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2850 expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2851 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2852 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2854 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2855 expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2856 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2857 1, 1, -2, -2, 0, 0, 2, 2, expected, expected, __LINE__);
2859 /* This result seems broken. One might expect the following result:
2860 * 0xCAFED00D 0xFEEDFACE
2861 * 0xFEDCBA98 0x76543210
2863 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2864 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2865 legacy_expected[0] = 0xCAFED00D, legacy_expected[1] = 0x00000000;
2866 legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
2867 todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2868 1, 1, -2, -2, 1, 1, -2, -2, expected,
2869 legacy_expected, __LINE__);
2871 expected[0] = 0x00000000, expected[1] = 0x00000000;
2872 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
2873 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2874 1, 1, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2876 SelectObject(hdcDst, oldDst);
2877 DeleteObject(bmpDst);
2879 /* Top-down to bottom-up tests */
2880 biDst.bmiHeader.biHeight = 2;
2881 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2883 oldDst = SelectObject(hdcDst, bmpDst);
2885 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2886 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
2887 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2888 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2890 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2891 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2892 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2893 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2895 SelectObject(hdcSrc, oldSrc);
2896 DeleteObject(bmpSrc);
2898 /* Bottom-up to bottom-up tests */
2899 biSrc.bmiHeader.biHeight = 2;
2900 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2902 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2903 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
2904 oldSrc = SelectObject(hdcSrc, bmpSrc);
2906 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2907 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2908 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2909 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2911 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2912 expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2913 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2914 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2916 SelectObject(hdcDst, oldDst);
2917 DeleteObject(bmpDst);
2919 /* Bottom-up to top-down tests */
2920 biDst.bmiHeader.biHeight = -2;
2921 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2923 oldDst = SelectObject(hdcDst, bmpDst);
2925 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2926 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
2927 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2928 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2930 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2931 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2932 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2933 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2936 SelectObject(hdcSrc, oldSrc);
2937 DeleteObject(bmpSrc);
2940 SelectObject(hdcDst, oldDst);
2941 DeleteObject(bmpDst);
2944 DeleteDC(hdcScreen);
2947 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
2948 DWORD dwRop, UINT32 expected, int line)
2950 const UINT32 buffer[2] = { 0xFEDCBA98, 0 };
2951 BITMAPINFO bitmapInfo;
2953 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2954 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2955 bitmapInfo.bmiHeader.biWidth = 2;
2956 bitmapInfo.bmiHeader.biHeight = 1;
2957 bitmapInfo.bmiHeader.biPlanes = 1;
2958 bitmapInfo.bmiHeader.biBitCount = 32;
2959 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2960 bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer);
2962 *dstBuffer = 0x89ABCDEF;
2964 StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop);
2965 ok(expected == *dstBuffer,
2966 "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2967 dwRop, expected, *dstBuffer, line);
2970 static void check_StretchDIBits_stretch(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
2971 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2972 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2973 UINT32 expected[4], UINT32 legacy_expected[4], int line)
2975 BITMAPINFO bitmapInfo;
2977 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2978 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2979 bitmapInfo.bmiHeader.biWidth = 2;
2980 bitmapInfo.bmiHeader.biHeight = -2;
2981 bitmapInfo.bmiHeader.biPlanes = 1;
2982 bitmapInfo.bmiHeader.biBitCount = 32;
2983 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2985 memset(dstBuffer, 0, 16);
2986 StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2987 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2988 srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
2989 ok(memcmp(dstBuffer, expected, 16) == 0,
2990 "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2991 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2992 expected[0], expected[1], expected[2], expected[3],
2993 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2994 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2995 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2998 static void test_StretchDIBits(void)
3002 HDC hdcScreen, hdcDst;
3003 UINT32 *dstBuffer, srcBuffer[4];
3004 HBRUSH hBrush, hOldBrush;
3006 UINT32 expected[4], legacy_expected[4];
3008 memset(&biDst, 0, sizeof(BITMAPINFO));
3009 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3010 biDst.bmiHeader.biWidth = 2;
3011 biDst.bmiHeader.biHeight = -2;
3012 biDst.bmiHeader.biPlanes = 1;
3013 biDst.bmiHeader.biBitCount = 32;
3014 biDst.bmiHeader.biCompression = BI_RGB;
3016 hdcScreen = CreateCompatibleDC(0);
3017 hdcDst = CreateCompatibleDC(hdcScreen);
3020 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3022 oldDst = SelectObject(hdcDst, bmpDst);
3024 hBrush = CreateSolidBrush(0x012345678);
3025 hOldBrush = SelectObject(hdcDst, hBrush);
3027 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3028 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3029 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3030 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3031 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3032 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3033 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3034 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3035 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3036 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3037 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3038 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3039 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3040 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3041 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3043 SelectObject(hdcDst, hOldBrush);
3044 DeleteObject(hBrush);
3046 /* Top-down destination tests */
3047 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3048 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
3050 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
3051 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
3052 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3053 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
3055 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3056 expected[2] = 0x00000000, expected[3] = 0x00000000;
3057 legacy_expected[0] = 0xFEDCBA98, legacy_expected[1] = 0x00000000;
3058 legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
3059 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3060 0, 0, 1, 1, 0, 0, 1, 1, expected, legacy_expected, __LINE__);
3062 expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
3063 expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
3064 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3065 0, 0, 2, 2, 0, 0, 1, 1, expected, expected, __LINE__);
3067 expected[0] = 0x42441000, expected[1] = 0x00000000;
3068 expected[2] = 0x00000000, expected[3] = 0x00000000;
3069 legacy_expected[0] = 0x00543210, legacy_expected[1] = 0x00000000;
3070 legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
3071 todo_wine check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3072 0, 0, 1, 1, 0, 0, 2, 2, expected, legacy_expected, __LINE__);
3074 expected[0] = 0x00000000, expected[1] = 0x00000000;
3075 expected[2] = 0x00000000, expected[3] = 0x00000000;
3076 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3077 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
3079 expected[0] = 0x00000000, expected[1] = 0x00000000;
3080 expected[2] = 0x00000000, expected[3] = 0x00000000;
3081 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3082 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
3084 expected[0] = 0x00000000, expected[1] = 0x00000000;
3085 expected[2] = 0x00000000, expected[3] = 0x00000000;
3086 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3087 1, 1, -2, -2, 1, 1, -2, -2, expected, expected, __LINE__);
3089 expected[0] = 0x00000000, expected[1] = 0x00000000;
3090 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
3091 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3092 1, 1, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
3094 SelectObject(hdcDst, oldDst);
3095 DeleteObject(bmpDst);
3097 /* Bottom up destination tests */
3098 biDst.bmiHeader.biHeight = 2;
3099 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3101 oldDst = SelectObject(hdcDst, bmpDst);
3103 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3104 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
3105 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3106 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
3109 SelectObject(hdcDst, oldDst);
3110 DeleteObject(bmpDst);
3113 DeleteDC(hdcScreen);
3116 static void test_GdiAlphaBlend(void)
3118 /* test out-of-bound parameters for GdiAlphaBlend */
3131 BLENDFUNCTION blend;
3133 if (!pGdiAlphaBlend)
3135 win_skip("GdiAlphaBlend() is not implemented\n");
3139 hdcNull = GetDC(NULL);
3140 hdcDst = CreateCompatibleDC(hdcNull);
3141 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
3142 hdcSrc = CreateCompatibleDC(hdcNull);
3144 memset(&bmi, 0, sizeof(bmi)); /* as of Wine 0.9.44 we require the src to be a DIB section */
3145 bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
3146 bmi.bmiHeader.biHeight = 20;
3147 bmi.bmiHeader.biWidth = 20;
3148 bmi.bmiHeader.biBitCount = 32;
3149 bmi.bmiHeader.biPlanes = 1;
3150 bmi.bmiHeader.biCompression = BI_RGB;
3151 bmpSrc = CreateDIBSection(hdcDst, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3152 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3154 oldDst = SelectObject(hdcDst, bmpDst);
3155 oldSrc = SelectObject(hdcSrc, bmpSrc);
3157 blend.BlendOp = AC_SRC_OVER;
3158 blend.BlendFlags = 0;
3159 blend.SourceConstantAlpha = 128;
3160 blend.AlphaFormat = 0;
3162 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend), TRUE, BOOL, "%d");
3163 SetLastError(0xdeadbeef);
3164 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), FALSE, BOOL, "%d");
3165 expect_eq(GetLastError(), ERROR_INVALID_PARAMETER, int, "%d");
3166 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), FALSE, BOOL, "%d");
3167 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend), FALSE, BOOL, "%d");
3168 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
3169 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
3171 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
3172 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), TRUE, BOOL, "%d");
3173 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), TRUE, BOOL, "%d");
3174 SetMapMode(hdcSrc, MM_ANISOTROPIC);
3175 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
3176 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend), TRUE, BOOL, "%d");
3177 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend), TRUE, BOOL, "%d");
3179 SetLastError(0xdeadbeef);
3180 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend), FALSE, BOOL, "%d");
3181 expect_eq(GetLastError(), 0xdeadbeef, int, "%d");
3183 SelectObject(hdcDst, oldDst);
3184 SelectObject(hdcSrc, oldSrc);
3185 DeleteObject(bmpSrc);
3186 DeleteObject(bmpDst);
3190 ReleaseDC(NULL, hdcNull);
3194 static void test_clipping(void)
3202 HDC hdcDst = CreateCompatibleDC( NULL );
3203 HDC hdcSrc = CreateCompatibleDC( NULL );
3205 BITMAPINFO bmpinfo={{0}};
3206 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3207 bmpinfo.bmiHeader.biWidth = 100;
3208 bmpinfo.bmiHeader.biHeight = 100;
3209 bmpinfo.bmiHeader.biPlanes = 1;
3210 bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3211 bmpinfo.bmiHeader.biCompression = BI_RGB;
3213 bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3214 ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3215 SelectObject( hdcDst, bmpDst );
3217 bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3218 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3219 SelectObject( hdcSrc, bmpSrc );
3221 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3222 ok(result, "BitBlt failed\n");
3224 hRgn = CreateRectRgn( 0,0,0,0 );
3225 SelectClipRgn( hdcDst, hRgn );
3227 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3228 ok(result, "BitBlt failed\n");
3230 DeleteObject( bmpDst );
3231 DeleteObject( bmpSrc );
3232 DeleteObject( hRgn );
3237 static void test_32bit_bitmap_blt(void)
3240 HBITMAP bmpSrc, bmpDst;
3241 HBITMAP oldSrc, oldDst;
3242 HDC hdcSrc, hdcDst, hdcScreen;
3244 DWORD colorSrc = 0x11223344;
3246 memset(&biDst, 0, sizeof(BITMAPINFO));
3247 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3248 biDst.bmiHeader.biWidth = 2;
3249 biDst.bmiHeader.biHeight = -2;
3250 biDst.bmiHeader.biPlanes = 1;
3251 biDst.bmiHeader.biBitCount = 32;
3252 biDst.bmiHeader.biCompression = BI_RGB;
3254 hdcScreen = CreateCompatibleDC(0);
3255 if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3257 DeleteDC(hdcScreen);
3258 trace("Skipping 32-bit DDB test\n");
3262 hdcSrc = CreateCompatibleDC(hdcScreen);
3263 bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3264 oldSrc = SelectObject(hdcSrc, bmpSrc);
3266 hdcDst = CreateCompatibleDC(hdcScreen);
3267 bmpDst = CreateDIBSection(hdcDst, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3268 oldDst = SelectObject(hdcDst, bmpDst);
3270 StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3271 ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3274 SelectObject(hdcDst, oldDst);
3275 DeleteObject(bmpDst);
3278 SelectObject(hdcSrc, oldSrc);
3279 DeleteObject(bmpSrc);
3282 DeleteDC(hdcScreen);
3286 * Used by test_GetDIBits_top_down to create the bitmap to test against.
3288 static void setup_picture(char *picture, int bpp)
3296 /*Set the first byte in each pixel to the index of that pixel.*/
3297 for (i = 0; i < 4; i++)
3298 picture[i * (bpp / 8)] = i;
3303 /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
3310 static void test_GetDIBits_top_down(int bpp)
3313 HBITMAP bmptb, bmpbt;
3319 memset( &bi, 0, sizeof(bi) );
3320 bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
3321 bi.bmiHeader.biWidth=2;
3322 bi.bmiHeader.biHeight=2;
3323 bi.bmiHeader.biPlanes=1;
3324 bi.bmiHeader.biBitCount=bpp;
3325 bi.bmiHeader.biCompression=BI_RGB;
3327 /*Get the device context for the screen.*/
3329 ok(hdc != NULL, "Could not get a handle to a device context.\n");
3331 /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
3332 bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3333 ok(bmpbt != NULL, "Could not create a DIB section.\n");
3334 /*Now that we have a pointer to the pixels, we write to them.*/
3335 setup_picture((char*)picture, bpp);
3336 /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
3337 bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
3338 bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3339 ok(bmptb != NULL, "Could not create a DIB section.\n");
3340 /*Write to this top to bottom bitmap.*/
3341 setup_picture((char*)picture, bpp);
3343 bi.bmiHeader.biWidth = 1;
3345 bi.bmiHeader.biHeight = 2;
3346 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3347 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3348 /*Check the first byte of the pixel.*/
3349 ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3350 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3351 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3352 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3353 /*Check second scanline.*/
3354 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3355 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3356 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3357 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3358 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3359 ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3360 /*Check both scanlines.*/
3361 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3362 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3363 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3364 ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3365 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3366 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3367 ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3368 ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3370 /*Make destination bitmap top-down.*/
3371 bi.bmiHeader.biHeight = -2;
3372 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3373 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3374 ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3375 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3376 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3377 ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3378 /*Check second scanline.*/
3379 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3380 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3381 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3382 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3383 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3384 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3385 /*Check both scanlines.*/
3386 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3387 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3388 ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3389 ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3390 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3391 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3392 ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3393 ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3395 DeleteObject(bmpbt);
3396 DeleteObject(bmptb);
3399 static void test_GetSetDIBits_rtl(void)
3402 HBITMAP bitmap, orig_bitmap;
3405 DWORD bits_1[8 * 8], bits_2[8 * 8];
3409 win_skip("Don't have SetLayout\n");
3413 hdc = GetDC( NULL );
3414 hdc_mem = CreateCompatibleDC( hdc );
3415 pSetLayout( hdc_mem, LAYOUT_LTR );
3417 bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
3418 orig_bitmap = SelectObject( hdc_mem, bitmap );
3419 SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
3420 SelectObject( hdc_mem, orig_bitmap );
3422 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3423 info.bmiHeader.biWidth = 8;
3424 info.bmiHeader.biHeight = 8;
3425 info.bmiHeader.biPlanes = 1;
3426 info.bmiHeader.biBitCount = 32;
3427 info.bmiHeader.biCompression = BI_RGB;
3429 /* First show that GetDIBits ignores the layout mode. */
3431 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3432 ok(ret == 8, "got %d\n", ret);
3433 ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
3435 pSetLayout( hdc_mem, LAYOUT_RTL );
3437 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3438 ok(ret == 8, "got %d\n", ret);
3440 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3442 /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
3443 followed by a GetDIBits and show that the bits remain unchanged. */
3445 pSetLayout( hdc_mem, LAYOUT_LTR );
3447 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3448 ok(ret == 8, "got %d\n", ret);
3449 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3450 ok(ret == 8, "got %d\n", ret);
3451 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3453 pSetLayout( hdc_mem, LAYOUT_RTL );
3455 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3456 ok(ret == 8, "got %d\n", ret);
3457 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3458 ok(ret == 8, "got %d\n", ret);
3459 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3461 DeleteObject( bitmap );
3462 DeleteDC( hdc_mem );
3463 ReleaseDC( NULL, hdc );
3466 static void test_GetDIBits_scanlines(void)
3468 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3469 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3471 HDC hdc = GetDC( NULL );
3473 DWORD data[128], inverted_bits[64];
3476 memset( info, 0, sizeof(bmi_buf) );
3478 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3479 info->bmiHeader.biWidth = 8;
3480 info->bmiHeader.biHeight = 8;
3481 info->bmiHeader.biPlanes = 1;
3482 info->bmiHeader.biBitCount = 32;
3483 info->bmiHeader.biCompression = BI_RGB;
3485 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3487 for (i = 0; i < 64; i++)
3490 inverted_bits[56 - (i & ~7) + (i & 7)] = i;
3495 memset( data, 0xaa, sizeof(data) );
3497 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3498 ok( ret == 8, "got %d\n", ret );
3499 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3500 memset( data, 0xaa, sizeof(data) );
3502 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3503 ok( ret == 5, "got %d\n", ret );
3504 ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
3505 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3506 memset( data, 0xaa, sizeof(data) );
3508 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3509 ok( ret == 7, "got %d\n", ret );
3510 ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
3511 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3512 memset( data, 0xaa, sizeof(data) );
3514 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3515 ok( ret == 1, "got %d\n", ret );
3516 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3517 memset( data, 0xaa, sizeof(data) );
3519 info->bmiHeader.biHeight = 16;
3520 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3521 ok( ret == 5, "got %d\n", ret );
3522 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3523 ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
3524 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3525 memset( data, 0xaa, sizeof(data) );
3527 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3528 ok( ret == 6, "got %d\n", ret );
3529 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3530 ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
3531 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3532 memset( data, 0xaa, sizeof(data) );
3534 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3535 ok( ret == 0, "got %d\n", ret );
3536 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3537 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3538 memset( data, 0xaa, sizeof(data) );
3540 info->bmiHeader.biHeight = 5;
3541 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3542 ok( ret == 2, "got %d\n", ret );
3543 ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
3544 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3545 memset( data, 0xaa, sizeof(data) );
3549 info->bmiHeader.biHeight = -8;
3550 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3551 ok( ret == 8, "got %d\n", ret );
3552 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3553 memset( data, 0xaa, sizeof(data) );
3555 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3556 ok( ret == 5, "got %d\n", ret );
3557 ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
3558 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3559 memset( data, 0xaa, sizeof(data) );
3561 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3562 ok( ret == 7, "got %d\n", ret );
3563 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3564 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3565 memset( data, 0xaa, sizeof(data) );
3567 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3568 ok( ret == 4, "got %d\n", ret );
3569 ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
3570 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3571 memset( data, 0xaa, sizeof(data) );
3573 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3574 ok( ret == 5, "got %d\n", ret );
3575 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3576 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3577 memset( data, 0xaa, sizeof(data) );
3579 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3580 ok( ret == 5, "got %d\n", ret );
3581 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3582 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3583 memset( data, 0xaa, sizeof(data) );
3585 info->bmiHeader.biHeight = -16;
3586 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3587 ok( ret == 8, "got %d\n", ret );
3588 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3589 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3590 memset( data, 0xaa, sizeof(data) );
3592 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3593 ok( ret == 5, "got %d\n", ret );
3594 ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
3595 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3596 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3597 memset( data, 0xaa, sizeof(data) );
3599 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3600 ok( ret == 8, "got %d\n", ret );
3601 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3602 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3603 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3604 memset( data, 0xaa, sizeof(data) );
3606 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3607 ok( ret == 8, "got %d\n", ret );
3608 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3609 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3610 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3611 memset( data, 0xaa, sizeof(data) );
3613 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3614 ok( ret == 7, "got %d\n", ret );
3615 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3616 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3617 memset( data, 0xaa, sizeof(data) );
3619 ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
3620 ok( ret == 1, "got %d\n", ret );
3621 for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3622 memset( data, 0xaa, sizeof(data) );
3624 info->bmiHeader.biHeight = -5;
3625 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3626 ok( ret == 2, "got %d\n", ret );
3627 ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
3628 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3629 memset( data, 0xaa, sizeof(data) );
3631 DeleteObject( dib );
3633 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3634 info->bmiHeader.biWidth = 8;
3635 info->bmiHeader.biHeight = -8;
3636 info->bmiHeader.biPlanes = 1;
3637 info->bmiHeader.biBitCount = 32;
3638 info->bmiHeader.biCompression = BI_RGB;
3640 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3642 for (i = 0; i < 64; i++) dib_bits[i] = i;
3646 info->bmiHeader.biHeight = -8;
3647 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3648 ok( ret == 8, "got %d\n", ret );
3649 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3650 memset( data, 0xaa, sizeof(data) );
3652 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3653 ok( ret == 5, "got %d\n", ret );
3654 ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
3655 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3656 memset( data, 0xaa, sizeof(data) );
3658 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3659 ok( ret == 7, "got %d\n", ret );
3660 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3661 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3662 memset( data, 0xaa, sizeof(data) );
3664 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3665 ok( ret == 4, "got %d\n", ret );
3666 ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
3667 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3668 memset( data, 0xaa, sizeof(data) );
3670 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3671 ok( ret == 5, "got %d\n", ret );
3672 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3673 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3674 memset( data, 0xaa, sizeof(data) );
3676 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3677 ok( ret == 5, "got %d\n", ret );
3678 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3679 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3680 memset( data, 0xaa, sizeof(data) );
3682 info->bmiHeader.biHeight = -16;
3683 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3684 ok( ret == 8, "got %d\n", ret );
3685 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3686 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3687 memset( data, 0xaa, sizeof(data) );
3689 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3690 ok( ret == 5, "got %d\n", ret );
3691 ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
3692 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3693 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3694 memset( data, 0xaa, sizeof(data) );
3696 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3697 ok( ret == 8, "got %d\n", ret );
3698 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3699 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3700 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3701 memset( data, 0xaa, sizeof(data) );
3703 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3704 ok( ret == 8, "got %d\n", ret );
3705 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3706 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3707 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3708 memset( data, 0xaa, sizeof(data) );
3710 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3711 ok( ret == 7, "got %d\n", ret );
3712 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3713 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3714 memset( data, 0xaa, sizeof(data) );
3716 info->bmiHeader.biHeight = -5;
3717 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3718 ok( ret == 2, "got %d\n", ret );
3719 ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
3720 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3721 memset( data, 0xaa, sizeof(data) );
3726 info->bmiHeader.biHeight = 8;
3728 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3729 ok( ret == 8, "got %d\n", ret );
3730 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3731 memset( data, 0xaa, sizeof(data) );
3733 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3734 ok( ret == 5, "got %d\n", ret );
3735 ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
3736 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3737 memset( data, 0xaa, sizeof(data) );
3739 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3740 ok( ret == 7, "got %d\n", ret );
3741 ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
3742 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3743 memset( data, 0xaa, sizeof(data) );
3745 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3746 ok( ret == 1, "got %d\n", ret );
3747 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3748 memset( data, 0xaa, sizeof(data) );
3750 info->bmiHeader.biHeight = 16;
3751 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3752 ok( ret == 5, "got %d\n", ret );
3753 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3754 ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
3755 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3756 memset( data, 0xaa, sizeof(data) );
3758 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3759 ok( ret == 6, "got %d\n", ret );
3760 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3761 ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
3762 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3763 memset( data, 0xaa, sizeof(data) );
3765 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3766 ok( ret == 0, "got %d\n", ret );
3767 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3768 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3769 memset( data, 0xaa, sizeof(data) );
3771 info->bmiHeader.biHeight = 5;
3772 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3773 ok( ret == 2, "got %d\n", ret );
3774 ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
3775 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3776 memset( data, 0xaa, sizeof(data) );
3778 DeleteObject( dib );
3780 ReleaseDC( NULL, hdc );
3784 static void test_SetDIBits(void)
3786 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3787 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3789 HDC hdc = GetDC( NULL );
3790 DWORD data[128], inverted_data[128];
3794 memset( info, 0, sizeof(bmi_buf) );
3796 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3797 info->bmiHeader.biWidth = 8;
3798 info->bmiHeader.biHeight = 8;
3799 info->bmiHeader.biPlanes = 1;
3800 info->bmiHeader.biBitCount = 32;
3801 info->bmiHeader.biCompression = BI_RGB;
3803 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3804 memset( dib_bits, 0xaa, 64 * 4 );
3806 for (i = 0; i < 128; i++)
3809 inverted_data[120 - (i & ~7) + (i & 7)] = i;
3814 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3815 ok( ret == 8, "got %d\n", ret );
3816 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
3817 memset( dib_bits, 0xaa, 64 * 4 );
3819 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3820 ok( ret == 5, "got %d\n", ret );
3821 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3822 ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
3823 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3824 memset( dib_bits, 0xaa, 64 * 4 );
3826 /* top of dst is aligned with startscans down for the top of the src.
3827 Then starting from the bottom of src, lines rows are copied across. */
3829 info->bmiHeader.biHeight = 16;
3830 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3831 ok( ret == 12, "got %d\n", ret );
3832 ok( !memcmp( dib_bits, data + 56, 40 * 4 ), "bits differ\n");
3833 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3834 memset( dib_bits, 0xaa, 64 * 4 );
3836 info->bmiHeader.biHeight = 5;
3837 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3838 ok( ret == 2, "got %d\n", ret );
3839 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3840 ok( !memcmp( dib_bits + 32, data, 16 * 4 ), "bits differ\n");
3841 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3842 memset( dib_bits, 0xaa, 64 * 4 );
3845 info->bmiHeader.biHeight = -8;
3846 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3847 ok( ret == 8, "got %d\n", ret );
3848 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3849 memset( dib_bits, 0xaa, 64 * 4 );
3851 /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
3852 we copy lines rows from the top of the src */
3854 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3855 ok( ret == 5, "got %d\n", ret );
3856 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3857 ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
3858 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3859 memset( dib_bits, 0xaa, 64 * 4 );
3861 info->bmiHeader.biHeight = -16;
3862 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3863 ok( ret == 12, "got %d\n", ret );
3864 ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
3865 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3866 memset( dib_bits, 0xaa, 64 * 4 );
3868 ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3869 ok( ret == 12, "got %d\n", ret );
3870 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3871 memset( dib_bits, 0xaa, 64 * 4 );
3873 ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3874 ok( ret == 12, "got %d\n", ret );
3875 ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
3876 memset( dib_bits, 0xaa, 64 * 4 );
3878 info->bmiHeader.biHeight = -5;
3879 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3880 ok( ret == 2, "got %d\n", ret );
3881 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3882 ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
3883 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3884 memset( dib_bits, 0xaa, 64 * 4 );
3886 DeleteObject( dib );
3888 info->bmiHeader.biHeight = -8;
3890 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3891 memset( dib_bits, 0xaa, 16 * 16 * 4 );
3895 /* like the t-d -> b-u case. */
3897 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3898 ok( ret == 8, "got %d\n", ret );
3899 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
3900 memset( dib_bits, 0xaa, 64 * 4 );
3902 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3903 ok( ret == 5, "got %d\n", ret );
3904 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3905 ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
3906 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3907 memset( dib_bits, 0xaa, 64 * 4 );
3909 info->bmiHeader.biHeight = -16;
3910 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3911 ok( ret == 12, "got %d\n", ret );
3912 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3913 ok( !memcmp( dib_bits + 24, data, 40 * 4 ), "bits differ\n");
3914 memset( dib_bits, 0xaa, 64 * 4 );
3916 info->bmiHeader.biHeight = -5;
3917 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3918 ok( ret == 2, "got %d\n", ret );
3919 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3920 ok( !memcmp( dib_bits + 16, data, 16 * 4 ), "bits differ\n");
3921 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3922 memset( dib_bits, 0xaa, 64 * 4 );
3925 /* like the b-u -> b-u case */
3927 info->bmiHeader.biHeight = 8;
3928 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3929 ok( ret == 8, "got %d\n", ret );
3930 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3931 memset( dib_bits, 0xaa, 64 * 4 );
3933 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3934 ok( ret == 5, "got %d\n", ret );
3935 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3936 ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
3937 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3938 memset( dib_bits, 0xaa, 64 * 4 );
3940 info->bmiHeader.biHeight = 16;
3941 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3942 ok( ret == 12, "got %d\n", ret );
3943 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3944 ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
3945 memset( dib_bits, 0xaa, 64 * 4 );
3947 info->bmiHeader.biHeight = 5;
3948 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3949 ok( ret == 2, "got %d\n", ret );
3950 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3951 ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
3952 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3953 memset( dib_bits, 0xaa, 64 * 4 );
3955 DeleteObject( dib );
3956 ReleaseDC( NULL, hdc );
3959 static void test_SetDIBits_RLE4(void)
3961 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3962 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3964 HDC hdc = GetDC( NULL );
3965 BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00, /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
3966 0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
3967 0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00, /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
3968 0x00, 0x02, 0x01, 0x02, 0x05, 0x87, /* dx=1, dy=2, 8, 7, 8, 7, 8 */
3969 0x00, 0x01 }; /* <eod> */
3972 DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
3973 0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
3974 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3975 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3976 0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
3977 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3978 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3979 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
3981 memset( info, 0, sizeof(bmi_buf) );
3983 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3984 info->bmiHeader.biWidth = 8;
3985 info->bmiHeader.biHeight = 8;
3986 info->bmiHeader.biPlanes = 1;
3987 info->bmiHeader.biBitCount = 32;
3988 info->bmiHeader.biCompression = BI_RGB;
3990 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3991 memset( dib_bits, 0xaa, 64 * 4 );
3993 info->bmiHeader.biBitCount = 4;
3994 info->bmiHeader.biCompression = BI_RLE4;
3995 info->bmiHeader.biSizeImage = sizeof(rle4_data);
3997 for (i = 0; i < 16; i++)
3999 info->bmiColors[i].rgbRed = i;
4000 info->bmiColors[i].rgbGreen = i;
4001 info->bmiColors[i].rgbBlue = i;
4002 info->bmiColors[i].rgbReserved = 0;
4005 ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
4006 ok( ret == 8, "got %d\n", ret );
4007 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
4008 memset( dib_bits, 0xaa, 64 * 4 );
4010 DeleteObject( dib );
4011 ReleaseDC( NULL, hdc );
4014 static void test_SetDIBits_RLE8(void)
4016 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
4017 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
4019 HDC hdc = GetDC( NULL );
4020 BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00, /* 2, 2, 2, f0, f0, f0, f0, <eol> */
4021 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4022 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4023 0x00, 0x01 }; /* <eod> */
4026 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4027 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4028 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4029 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4030 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4031 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4032 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4033 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4034 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4035 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4036 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4037 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4038 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4039 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4040 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4041 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4043 memset( info, 0, sizeof(bmi_buf) );
4045 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4046 info->bmiHeader.biWidth = 8;
4047 info->bmiHeader.biHeight = 8;
4048 info->bmiHeader.biPlanes = 1;
4049 info->bmiHeader.biBitCount = 32;
4050 info->bmiHeader.biCompression = BI_RGB;
4052 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4053 memset( dib_bits, 0xaa, 64 * 4 );
4055 info->bmiHeader.biBitCount = 8;
4056 info->bmiHeader.biCompression = BI_RLE8;
4057 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4059 for (i = 0; i < 256; i++)
4061 info->bmiColors[i].rgbRed = i;
4062 info->bmiColors[i].rgbGreen = i;
4063 info->bmiColors[i].rgbBlue = i;
4064 info->bmiColors[i].rgbReserved = 0;
4067 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4068 ok( ret == 8, "got %d\n", ret );
4069 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4070 memset( dib_bits, 0xaa, 64 * 4 );
4072 /* startscan and lines are ignored, unless lines == 0 */
4073 ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4074 ok( ret == 8, "got %d\n", ret );
4075 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4076 memset( dib_bits, 0xaa, 64 * 4 );
4078 ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4079 ok( ret == 8, "got %d\n", ret );
4080 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4081 memset( dib_bits, 0xaa, 64 * 4 );
4083 ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4084 ok( ret == 0, "got %d\n", ret );
4085 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4086 memset( dib_bits, 0xaa, 64 * 4 );
4088 /* reduce width to 4, left-hand side of dst is touched. */
4089 info->bmiHeader.biWidth = 4;
4090 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4091 ok( ret == 8, "got %d\n", ret );
4092 for (i = 0; i < 64; i++)
4094 DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4095 ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4097 memset( dib_bits, 0xaa, 64 * 4 );
4099 /* Show that the top lines are aligned by adjusting the height of the src */
4101 /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4102 info->bmiHeader.biWidth = 8;
4103 info->bmiHeader.biHeight = 4;
4104 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4105 ok( ret == 4, "got %d\n", ret );
4106 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4107 ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4108 memset( dib_bits, 0xaa, 64 * 4 );
4110 /* increase the height to 9 -> everything moves down one row. */
4111 info->bmiHeader.biHeight = 9;
4112 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4113 ok( ret == 9, "got %d\n", ret );
4114 ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4115 for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4116 memset( dib_bits, 0xaa, 64 * 4 );
4118 /* top-down compressed dibs are invalid */
4119 info->bmiHeader.biHeight = -8;
4120 SetLastError( 0xdeadbeef );
4121 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4122 ok( ret == 0, "got %d\n", ret );
4123 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4124 DeleteObject( dib );
4128 info->bmiHeader.biHeight = -8;
4129 info->bmiHeader.biBitCount = 32;
4130 info->bmiHeader.biCompression = BI_RGB;
4131 info->bmiHeader.biSizeImage = 0;
4133 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4134 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4136 info->bmiHeader.biHeight = 8;
4137 info->bmiHeader.biBitCount = 8;
4138 info->bmiHeader.biCompression = BI_RLE8;
4139 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4141 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4142 ok( ret == 8, "got %d\n", ret );
4143 ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4144 memset( dib_bits, 0xaa, 64 * 4 );
4146 info->bmiHeader.biHeight = 4;
4147 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4148 ok( ret == 4, "got %d\n", ret );
4149 ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4150 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4151 memset( dib_bits, 0xaa, 64 * 4 );
4153 info->bmiHeader.biHeight = 9;
4154 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4155 ok( ret == 9, "got %d\n", ret );
4156 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4157 ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4158 memset( dib_bits, 0xaa, 64 * 4 );
4160 DeleteObject( dib );
4162 ReleaseDC( NULL, hdc );
4165 static void test_SetDIBitsToDevice(void)
4167 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
4168 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
4170 HDC hdc = CreateCompatibleDC( 0 );
4171 DWORD data[128], inverted_data[128];
4175 memset( info, 0, sizeof(bmi_buf) );
4177 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4178 info->bmiHeader.biWidth = 8;
4179 info->bmiHeader.biHeight = 8;
4180 info->bmiHeader.biPlanes = 1;
4181 info->bmiHeader.biBitCount = 32;
4182 info->bmiHeader.biCompression = BI_RGB;
4184 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4185 memset( dib_bits, 0xaa, 64 * 4 );
4186 SelectObject( hdc, dib );
4188 for (i = 0; i < 128; i++)
4191 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4196 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4197 ok( ret == 8, "got %d\n", ret );
4198 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4199 memset( dib_bits, 0xaa, 64 * 4 );
4201 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4202 ok( ret == 5, "got %d\n", ret );
4203 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4204 for (i = 8; i < 48; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4205 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4206 memset( dib_bits, 0xaa, 64 * 4 );
4208 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 3, 1, 5, data, info, DIB_RGB_COLORS );
4209 ok( ret == 5, "got %d\n", ret );
4210 for (i = 0; i < 24; i++) ok( dib_bits[i] == data[i + 16], "%d: got %08x\n", i, dib_bits[i] );
4211 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4212 memset( dib_bits, 0xaa, 64 * 4 );
4214 info->bmiHeader.biHeight = 16;
4215 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4216 ok( ret == 7, "got %d\n", ret );
4217 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4218 for (i = 8; i < 64; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4219 memset( dib_bits, 0xaa, 64 * 4 );
4221 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 8, 0, 6, 1, 12, data, info, DIB_RGB_COLORS );
4222 ok( ret == 12, "got %d\n", ret );
4223 for (i = 0; i < 40; i++) ok( dib_bits[i] == data[i + 56], "%d: got %08x\n", i, dib_bits[i] );
4224 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4225 memset( dib_bits, 0xaa, 64 * 4 );
4227 ret = SetDIBitsToDevice( hdc, 0, -4, 8, 8, 0, 3, 1, 12, data, info, DIB_RGB_COLORS );
4228 ok( ret == 10, "got %d\n", ret );
4229 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4230 for (i = 32; i < 64; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4231 memset( dib_bits, 0xaa, 64 * 4 );
4233 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, -3, 1, 12, data, info, DIB_RGB_COLORS );
4234 ok( ret == 4, "got %d\n", ret );
4235 for (i = 0; i < 32; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4236 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4237 memset( dib_bits, 0xaa, 64 * 4 );
4239 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 5, 0, -2, 1, 12, data, info, DIB_RGB_COLORS );
4240 ok( ret == 2, "got %d\n", ret );
4241 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4242 for (i = 32; i < 48; i++) ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4243 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4244 memset( dib_bits, 0xaa, 64 * 4 );
4246 info->bmiHeader.biHeight = 5;
4247 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 2, 2, data, info, DIB_RGB_COLORS );
4248 ok( ret == 2, "got %d\n", ret );
4249 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4250 for (i = 16; i < 32; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4251 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4252 memset( dib_bits, 0xaa, 64 * 4 );
4254 ret = SetDIBitsToDevice( hdc, 3, 3, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4255 ok( ret == 3, "got %d\n", ret );
4256 for (i = 0; i < 64; i++)
4257 if (i == 27 || i == 28 || i == 35 || i == 36)
4258 ok( dib_bits[i] == data[i - 18], "%d: got %08x\n", i, dib_bits[i] );
4260 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4261 memset( dib_bits, 0xaa, 64 * 4 );
4263 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4264 ok( ret == 5, "got %d\n", ret );
4265 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4266 memset( dib_bits, 0xaa, 64 * 4 );
4268 SetMapMode( hdc, MM_ANISOTROPIC );
4269 SetWindowExtEx( hdc, 3, 3, NULL );
4270 ret = SetDIBitsToDevice( hdc, 2, 2, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4271 ok( ret == 3, "got %d\n", ret );
4272 for (i = 0; i < 64; i++)
4273 if (i == 41 || i == 42 || i == 49 || i == 50)
4274 ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4276 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4277 memset( dib_bits, 0xaa, 64 * 4 );
4279 SetWindowExtEx( hdc, -1, -1, NULL );
4280 ret = SetDIBitsToDevice( hdc, 2, 2, 4, 4, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4281 ok( ret == 4, "got %d\n", ret );
4282 for (i = 0; i < 64; i++)
4283 if (i == 48 || i == 49 || i == 56 || i == 57)
4284 ok( dib_bits[i] == data[i - 37], "%d: got %08x\n", i, dib_bits[i] );
4286 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4287 memset( dib_bits, 0xaa, 64 * 4 );
4288 SetMapMode( hdc, MM_TEXT );
4291 info->bmiHeader.biHeight = -8;
4292 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4293 ok( ret == 8, "got %d\n", ret );
4294 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4295 memset( dib_bits, 0xaa, 64 * 4 );
4297 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4298 ok( ret == 5, "got %d\n", ret );
4299 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4300 for (i = 8; i < 48; i++) ok( dib_bits[i] == inverted_data[i + 80], "%d: got %08x\n", i, dib_bits[i] );
4301 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4302 memset( dib_bits, 0xaa, 64 * 4 );
4304 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 4, 1, 5, data, info, DIB_RGB_COLORS );
4305 ok( ret == 5, "got %d\n", ret );
4306 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4307 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4308 memset( dib_bits, 0xaa, 64 * 4 );
4310 info->bmiHeader.biHeight = -16;
4311 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4312 ok( ret == 12, "got %d\n", ret );
4313 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4314 for (i = 8; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4315 memset( dib_bits, 0xaa, 64 * 4 );
4317 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, 7, 1, 12, data, info, DIB_RGB_COLORS );
4318 ok( ret == 12, "got %d\n", ret );
4319 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4320 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4321 memset( dib_bits, 0xaa, 64 * 4 );
4323 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 4, 12, data, info, DIB_RGB_COLORS );
4324 ok( ret == 12, "got %d\n", ret );
4325 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4326 for (i = 32; i < 64; i++) ok( dib_bits[i] == inverted_data[i], "%d: got %08x\n", i, dib_bits[i] );
4327 memset( dib_bits, 0xaa, 64 * 4 );
4329 ret = SetDIBitsToDevice( hdc, 0, -3, 8, 8, 0, 2, 4, 12, data, info, DIB_RGB_COLORS );
4330 ok( ret == 12, "got %d\n", ret );
4331 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4332 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4333 memset( dib_bits, 0xaa, 64 * 4 );
4335 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, -2, 4, 12, data, info, DIB_RGB_COLORS );
4336 ok( ret == 12, "got %d\n", ret );
4337 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4338 for (i = 24; i < 40; i++) ok( dib_bits[i] == inverted_data[i + 8], "%d: got %08x\n", i, dib_bits[i] );
4339 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4340 memset( dib_bits, 0xaa, 64 * 4 );
4342 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 5, 12, data, info, DIB_RGB_COLORS );
4343 ok( ret == 12, "got %d\n", ret );
4344 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4345 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4346 memset( dib_bits, 0xaa, 64 * 4 );
4348 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4349 ok( ret == 12, "got %d\n", ret );
4350 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4351 memset( dib_bits, 0xaa, 64 * 4 );
4353 info->bmiHeader.biHeight = -5;
4354 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4355 ok( ret == 2, "got %d\n", ret );
4356 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4357 for (i = 8; i < 24; i++) ok( dib_bits[i] == inverted_data[i + 104], "%d: got %08x\n", i, dib_bits[i] );
4358 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4359 memset( dib_bits, 0xaa, 64 * 4 );
4361 ret = SetDIBitsToDevice( hdc, 5, 4, 2, 2, 6, 3, 1, 5, data, info, DIB_RGB_COLORS );
4362 ok( ret == 5, "got %d\n", ret );
4363 for (i = 0; i < 64; i++)
4364 if (i == 21 || i == 22 || i == 29 || i == 30)
4365 ok( dib_bits[i] == inverted_data[i + 89], "%d: got %08x\n", i, dib_bits[i] );
4367 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4368 memset( dib_bits, 0xaa, 64 * 4 );
4370 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4371 ok( ret == 5, "got %d\n", ret );
4372 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4373 memset( dib_bits, 0xaa, 64 * 4 );
4375 info->bmiHeader.biHeight = -8;
4377 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4378 DeleteObject( SelectObject( hdc, dib ));
4379 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4383 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4384 ok( ret == 8, "got %d\n", ret );
4385 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4386 memset( dib_bits, 0xaa, 64 * 4 );
4388 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4389 ok( ret == 5, "got %d\n", ret );
4390 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4391 for (i = 16; i < 56; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4392 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4393 memset( dib_bits, 0xaa, 64 * 4 );
4395 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 3, 0, 2, 1, 5, data, info, DIB_RGB_COLORS );
4396 ok( ret == 5, "got %d\n", ret );
4397 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4398 for (i = 24; i < 48; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4399 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4400 memset( dib_bits, 0xaa, 64 * 4 );
4402 info->bmiHeader.biHeight = -16;
4403 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4404 ok( ret == 12, "got %d\n", ret );
4405 for (i = 0; i < 56; i++) ok( dib_bits[i] == data[i + 40], "%d: got %08x\n", i, dib_bits[i] );
4406 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4407 memset( dib_bits, 0xaa, 64 * 4 );
4409 info->bmiHeader.biHeight = -5;
4410 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4411 ok( ret == 2, "got %d\n", ret );
4412 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4413 for (i = 40; i < 56; i++) ok( dib_bits[i] == data[i - 40], "%d: got %08x\n", i, dib_bits[i] );
4414 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4415 memset( dib_bits, 0xaa, 64 * 4 );
4417 ret = SetDIBitsToDevice( hdc, 7, 2, 8, 8, 1, 0, 0, 5, data, info, DIB_RGB_COLORS );
4418 ok( ret == 5, "got %d\n", ret );
4419 for (i = 0; i < 64; i++)
4420 if (i == 47 || i == 55 || i == 63)
4421 ok( dib_bits[i] == data[i - 46], "%d: got %08x\n", i, dib_bits[i] );
4423 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4424 memset( dib_bits, 0xaa, 64 * 4 );
4426 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4427 ok( ret == 5, "got %d\n", ret );
4428 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4429 memset( dib_bits, 0xaa, 64 * 4 );
4433 info->bmiHeader.biHeight = 8;
4434 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4435 ok( ret == 8, "got %d\n", ret );
4436 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4437 memset( dib_bits, 0xaa, 64 * 4 );
4439 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4440 ok( ret == 5, "got %d\n", ret );
4441 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4442 for (i = 16; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4443 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4444 memset( dib_bits, 0xaa, 64 * 4 );
4446 info->bmiHeader.biHeight = 16;
4447 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4448 ok( ret == 7, "got %d\n", ret );
4449 for (i = 0; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4450 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4451 memset( dib_bits, 0xaa, 64 * 4 );
4453 info->bmiHeader.biHeight = 5;
4454 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4455 ok( ret == 2, "got %d\n", ret );
4456 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4457 for (i = 40; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4458 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4459 memset( dib_bits, 0xaa, 64 * 4 );
4461 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4462 ok( ret == 5, "got %d\n", ret );
4463 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4464 memset( dib_bits, 0xaa, 64 * 4 );
4467 DeleteObject( dib );
4474 hdll = GetModuleHandle("gdi32.dll");
4475 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
4476 pSetLayout = (void*)GetProcAddress(hdll, "SetLayout");
4478 test_createdibitmap();
4481 test_mono_dibsection();
4484 test_GetDIBits_selected_DIB(1);
4485 test_GetDIBits_selected_DIB(4);
4486 test_GetDIBits_selected_DIB(8);
4487 test_GetDIBits_selected_DDB(TRUE);
4488 test_GetDIBits_selected_DDB(FALSE);
4490 test_GetDIBits_BI_BITFIELDS();
4491 test_select_object();
4492 test_CreateBitmap();
4495 test_StretchDIBits();
4496 test_GdiAlphaBlend();
4497 test_32bit_bitmap_blt();
4498 test_bitmapinfoheadersize();
4501 test_GetDIBits_top_down(16);
4502 test_GetDIBits_top_down(24);
4503 test_GetDIBits_top_down(32);
4504 test_GetSetDIBits_rtl();
4505 test_GetDIBits_scanlines();
4507 test_SetDIBits_RLE4();
4508 test_SetDIBits_RLE8();
4509 test_SetDIBitsToDevice();