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 static inline int get_bitmap_stride( int width, int bpp )
40 return ((width * bpp + 15) >> 3) & ~1;
43 static inline int get_dib_stride( int width, int bpp )
45 return ((width * bpp + 31) >> 3) & ~3;
48 static inline int get_dib_image_size( const BITMAPINFO *info )
50 return get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount )
51 * abs( info->bmiHeader.biHeight );
54 static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHEADER *bmih)
59 BYTE buf[512], buf_cmp[512];
61 ret = GetObject(hbm, sizeof(bm), &bm);
62 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
64 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
65 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
66 ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
67 width_bytes = get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel);
68 ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
69 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
70 ok(bm.bmBitsPixel == expected_depth, "wrong bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, expected_depth);
71 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
73 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
74 assert(sizeof(buf) == sizeof(buf_cmp));
76 SetLastError(0xdeadbeef);
77 ret = GetBitmapBits(hbm, 0, NULL);
78 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
80 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
81 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
83 memset(buf, 0xAA, sizeof(buf));
84 ret = GetBitmapBits(hbm, sizeof(buf), buf);
85 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
86 ok(!memcmp(buf, buf_cmp, sizeof(buf)),
87 "buffers do not match, depth %d\n", bmih->biBitCount);
89 /* test various buffer sizes for GetObject */
90 ret = GetObject(hbm, sizeof(*bma) * 2, bma);
91 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
93 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
94 ok(ret == 0, "%d != 0\n", ret);
96 ret = GetObject(hbm, 0, &bm);
97 ok(ret == 0, "%d != 0\n", ret);
99 ret = GetObject(hbm, 1, &bm);
100 ok(ret == 0, "%d != 0\n", ret);
102 ret = GetObject(hbm, 0, NULL);
103 ok(ret == sizeof(bm), "wrong size %d\n", ret);
106 static void test_createdibitmap(void)
109 BITMAPINFOHEADER bmih;
111 HBITMAP hbm, hbm_colour, hbm_old;
116 screen_depth = GetDeviceCaps(hdc, BITSPIXEL);
117 memset(&bmih, 0, sizeof(bmih));
118 bmih.biSize = sizeof(bmih);
122 bmih.biBitCount = 32;
123 bmih.biCompression = BI_RGB;
125 hbm = CreateDIBitmap(hdc, NULL, CBM_INIT, NULL, NULL, 0);
126 ok(hbm == NULL, "CreateDIBitmap should fail\n");
127 hbm = CreateDIBitmap(hdc, NULL, 0, NULL, NULL, 0);
128 ok(hbm == NULL, "CreateDIBitmap should fail\n");
130 /* First create an un-initialised bitmap. The depth of the bitmap
131 should match that of the hdc and not that supplied in bmih.
134 /* First try 32 bits */
135 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
136 ok(hbm != NULL, "CreateDIBitmap failed\n");
137 test_bitmap_info(hbm, screen_depth, &bmih);
141 bmih.biBitCount = 16;
142 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
143 ok(hbm != NULL, "CreateDIBitmap failed\n");
144 test_bitmap_info(hbm, screen_depth, &bmih);
149 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
150 ok(hbm != NULL, "CreateDIBitmap failed\n");
151 test_bitmap_info(hbm, screen_depth, &bmih);
154 /* Now with a monochrome dc we expect a monochrome bitmap */
155 hdcmem = CreateCompatibleDC(hdc);
157 /* First try 32 bits */
158 bmih.biBitCount = 32;
159 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
160 ok(hbm != NULL, "CreateDIBitmap failed\n");
161 test_bitmap_info(hbm, 1, &bmih);
165 bmih.biBitCount = 16;
166 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
167 ok(hbm != NULL, "CreateDIBitmap failed\n");
168 test_bitmap_info(hbm, 1, &bmih);
173 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
174 ok(hbm != NULL, "CreateDIBitmap failed\n");
175 test_bitmap_info(hbm, 1, &bmih);
178 /* Now select a polychrome bitmap into the dc and we expect
179 screen_depth bitmaps again */
180 hbm_colour = CreateCompatibleBitmap(hdc, bmih.biWidth, bmih.biHeight);
181 test_bitmap_info(hbm_colour, screen_depth, &bmih);
182 hbm_old = SelectObject(hdcmem, hbm_colour);
184 /* First try 32 bits */
185 bmih.biBitCount = 32;
186 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
187 ok(hbm != NULL, "CreateDIBitmap failed\n");
188 test_bitmap_info(hbm, screen_depth, &bmih);
192 bmih.biBitCount = 16;
193 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
194 ok(hbm != NULL, "CreateDIBitmap failed\n");
195 test_bitmap_info(hbm, screen_depth, &bmih);
200 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
201 ok(hbm != NULL, "CreateDIBitmap failed\n");
202 test_bitmap_info(hbm, screen_depth, &bmih);
205 SelectObject(hdcmem, hbm_old);
206 DeleteObject(hbm_colour);
209 bmih.biBitCount = 32;
210 hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0);
211 ok(hbm != NULL, "CreateDIBitmap failed\n");
212 test_bitmap_info(hbm, 1, &bmih);
215 /* Test how formats are converted */
221 memset(&bm, 0, sizeof(bm));
222 bm.bmiHeader.biSize = sizeof(bm.bmiHeader);
223 bm.bmiHeader.biWidth = 1;
224 bm.bmiHeader.biHeight = 1;
225 bm.bmiHeader.biPlanes = 1;
226 bm.bmiHeader.biBitCount= 24;
227 bm.bmiHeader.biCompression= BI_RGB;
228 bm.bmiHeader.biSizeImage = 0;
229 hbm = CreateDIBitmap(hdc, &bmih, CBM_INIT, &pixel, &bm, DIB_RGB_COLORS);
230 ok(hbm != NULL, "CreateDIBitmap failed\n");
233 bm.bmiHeader.biBitCount= 32;
234 GetDIBits(hdc, hbm, 0, 1, &pixel, &bm, DIB_RGB_COLORS);
235 ok(pixel == 0x00ffffff, "Reading a 32 bit pixel from a DDB returned %08x\n", pixel);
241 static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
247 INT ret, bm_width_bytes, dib_width_bytes;
250 ret = GetObject(hbm, sizeof(bm), &bm);
251 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
253 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
254 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
255 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
256 dib_width_bytes = get_dib_stride(bm.bmWidth, bm.bmBitsPixel);
257 bm_width_bytes = get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel);
258 if (bm.bmWidthBytes != dib_width_bytes) /* Win2k bug */
259 ok(bm.bmWidthBytes == bm_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, bm_width_bytes);
261 ok(bm.bmWidthBytes == dib_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, dib_width_bytes);
262 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
263 ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount);
264 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
266 buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);
268 /* GetBitmapBits returns not 32-bit aligned data */
269 SetLastError(0xdeadbeef);
270 ret = GetBitmapBits(hbm, 0, NULL);
271 ok(ret == bm_width_bytes * bm.bmHeight,
272 "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
274 memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
275 ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
276 ok(ret == bm_width_bytes * bm.bmHeight, "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
278 HeapFree(GetProcessHeap(), 0, buf);
280 /* test various buffer sizes for GetObject */
281 memset(&ds, 0xAA, sizeof(ds));
282 ret = GetObject(hbm, sizeof(*bma) * 2, bma);
283 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
284 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
285 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
286 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
288 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
289 ok(ret == 0, "%d != 0\n", ret);
291 ret = GetObject(hbm, 0, &bm);
292 ok(ret == 0, "%d != 0\n", ret);
294 ret = GetObject(hbm, 1, &bm);
295 ok(ret == 0, "%d != 0\n", ret);
297 /* test various buffer sizes for GetObject */
298 ret = GetObject(hbm, 0, NULL);
299 ok(ret == sizeof(bm), "wrong size %d\n", ret);
301 ret = GetObject(hbm, sizeof(*dsa) * 2, dsa);
302 ok(ret == sizeof(*dsa), "wrong size %d\n", ret);
304 memset(&ds, 0xAA, sizeof(ds));
305 ret = GetObject(hbm, sizeof(ds), &ds);
306 ok(ret == sizeof(ds), "wrong size %d\n", ret);
308 ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
309 if (ds.dsBm.bmWidthBytes != bm_width_bytes) /* Win2k bug */
310 ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%u != %u\n",
311 ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
312 ok(bmih->biSizeImage == 0, "%u != 0\n", bmih->biSizeImage);
313 ds.dsBmih.biSizeImage = 0;
315 ok(ds.dsBmih.biSize == bmih->biSize, "%u != %u\n", ds.dsBmih.biSize, bmih->biSize);
316 ok(ds.dsBmih.biWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
317 ok(ds.dsBmih.biHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
318 ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes);
319 ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount);
320 ok(ds.dsBmih.biCompression == bmih->biCompression ||
321 ((bmih->biBitCount == 32) && broken(ds.dsBmih.biCompression == BI_BITFIELDS)), /* nt4 sp1 and 2 */
322 "%u != %u\n", ds.dsBmih.biCompression, bmih->biCompression);
323 ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%u != %u\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
324 ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%d != %d\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
325 ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%d != %d\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);
327 memset(&ds, 0xAA, sizeof(ds));
328 ret = GetObject(hbm, sizeof(ds) - 4, &ds);
329 ok(ret == sizeof(ds.dsBm), "wrong size %d\n", ret);
330 ok(ds.dsBm.bmWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
331 ok(ds.dsBm.bmHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
332 ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);
334 ret = GetObject(hbm, 0, &ds);
335 ok(ret == 0, "%d != 0\n", ret);
337 ret = GetObject(hbm, 1, &ds);
338 ok(ret == 0, "%d != 0\n", ret);
341 #define test_color(hdc, color, exp) \
344 c = SetPixel(hdc, 0, 0, color); \
345 ok(c == exp, "SetPixel failed: got 0x%06x expected 0x%06x\n", c, (UINT)exp); \
346 c = GetPixel(hdc, 0, 0); \
347 ok(c == exp, "GetPixel failed: got 0x%06x expected 0x%06x\n", c, (UINT)exp); \
350 static void test_dib_bits_access( HBITMAP hdib, void *bits )
352 MEMORY_BASIC_INFORMATION info;
353 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
355 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
357 char filename[MAX_PATH];
362 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
363 "VirtualQuery failed\n");
364 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
365 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
366 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
367 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
368 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
369 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
371 memset( pbmi, 0, sizeof(bmibuf) );
372 memset( data, 0xcc, sizeof(data) );
373 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
374 pbmi->bmiHeader.biHeight = 16;
375 pbmi->bmiHeader.biWidth = 16;
376 pbmi->bmiHeader.biBitCount = 32;
377 pbmi->bmiHeader.biPlanes = 1;
378 pbmi->bmiHeader.biCompression = BI_RGB;
382 ret = SetDIBits( hdc, hdib, 0, 16, data, pbmi, DIB_RGB_COLORS );
383 ok(ret == 16, "SetDIBits failed: expected 16 got %d\n", ret);
387 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
388 "VirtualQuery failed\n");
389 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
390 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
391 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
392 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
393 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
394 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
396 /* try writing protected bits to a file */
398 GetTempFileNameA( ".", "dib", 0, filename );
399 file = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
400 CREATE_ALWAYS, 0, 0 );
401 ok( file != INVALID_HANDLE_VALUE, "failed to open %s error %u\n", filename, GetLastError() );
402 ret = WriteFile( file, bits, 8192, &written, NULL );
403 ok( ret, "WriteFile failed error %u\n", GetLastError() );
404 if (ret) ok( written == 8192, "only wrote %u bytes\n", written );
406 DeleteFileA( filename );
409 static void test_dibsections(void)
411 HDC hdc, hdcmem, hdcmem2;
412 HBITMAP hdib, oldbm, hdib2, oldbm2;
413 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
414 char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
415 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
416 BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
422 char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
423 LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
426 HPALETTE hpal, oldpal;
431 MEMORY_BASIC_INFORMATION info;
434 screen_depth = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
436 memset(pbmi, 0, sizeof(bmibuf));
437 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
438 pbmi->bmiHeader.biHeight = 100;
439 pbmi->bmiHeader.biWidth = 512;
440 pbmi->bmiHeader.biBitCount = 24;
441 pbmi->bmiHeader.biPlanes = 1;
442 pbmi->bmiHeader.biCompression = BI_RGB;
444 SetLastError(0xdeadbeef);
446 /* invalid pointer for BITMAPINFO
447 (*bits should be NULL on error) */
448 bits = (BYTE*)0xdeadbeef;
449 hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
450 ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n");
452 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
453 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
454 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
455 ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
457 /* test the DIB memory */
458 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
459 "VirtualQuery failed\n");
460 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
461 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
462 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
463 ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
464 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
465 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
466 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
468 test_dib_bits_access( hdib, bits );
470 test_dib_info(hdib, bits, &pbmi->bmiHeader);
473 /* Test a top-down DIB. */
474 pbmi->bmiHeader.biHeight = -100;
475 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
476 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
477 test_dib_info(hdib, bits, &pbmi->bmiHeader);
480 pbmi->bmiHeader.biHeight = 100;
481 pbmi->bmiHeader.biBitCount = 8;
482 pbmi->bmiHeader.biCompression = BI_RLE8;
483 SetLastError(0xdeadbeef);
484 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
485 ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
486 ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
488 pbmi->bmiHeader.biBitCount = 16;
489 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
490 ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
491 ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
492 ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
493 SetLastError(0xdeadbeef);
494 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
495 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
497 /* test the DIB memory */
498 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
499 "VirtualQuery failed\n");
500 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
501 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
502 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
503 ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
504 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
505 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
506 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
508 test_dib_info(hdib, bits, &pbmi->bmiHeader);
511 memset(pbmi, 0, sizeof(bmibuf));
512 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
513 pbmi->bmiHeader.biHeight = 16;
514 pbmi->bmiHeader.biWidth = 16;
515 pbmi->bmiHeader.biBitCount = 1;
516 pbmi->bmiHeader.biPlanes = 1;
517 pbmi->bmiHeader.biCompression = BI_RGB;
518 pbmi->bmiColors[0].rgbRed = 0xff;
519 pbmi->bmiColors[0].rgbGreen = 0;
520 pbmi->bmiColors[0].rgbBlue = 0;
521 pbmi->bmiColors[1].rgbRed = 0;
522 pbmi->bmiColors[1].rgbGreen = 0;
523 pbmi->bmiColors[1].rgbBlue = 0xff;
525 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
526 ok(hdib != NULL, "CreateDIBSection failed\n");
527 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
528 ok(dibsec.dsBmih.biClrUsed == 2,
529 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
531 /* Test if the old BITMAPCOREINFO structure is supported */
533 pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
534 pbci->bmciHeader.bcBitCount = 0;
536 ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
537 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
538 ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
539 && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
540 "GetDIBits didn't fill in the BITMAPCOREHEADER structure properly\n");
542 ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
543 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
544 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
545 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
546 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
547 "The color table has not been translated to the old BITMAPCOREINFO format\n");
549 hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
550 ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
552 ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
553 ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
554 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
555 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
556 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
557 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
558 "The color table has not been translated to the old BITMAPCOREINFO format\n");
560 DeleteObject(hcoredib);
562 hdcmem = CreateCompatibleDC(hdc);
563 oldbm = SelectObject(hdcmem, hdib);
565 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
566 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
567 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
568 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
569 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
570 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
572 c0 = RGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen, pbmi->bmiColors[0].rgbBlue);
573 c1 = RGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen, pbmi->bmiColors[1].rgbBlue);
575 test_color(hdcmem, DIBINDEX(0), c0);
576 test_color(hdcmem, DIBINDEX(1), c1);
577 test_color(hdcmem, DIBINDEX(2), c0);
578 test_color(hdcmem, PALETTEINDEX(0), c0);
579 test_color(hdcmem, PALETTEINDEX(1), c0);
580 test_color(hdcmem, PALETTEINDEX(2), c0);
581 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen,
582 pbmi->bmiColors[0].rgbBlue), c0);
583 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen,
584 pbmi->bmiColors[1].rgbBlue), c1);
585 test_color(hdcmem, PALETTERGB(0, 0, 0), c0);
586 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0);
587 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1);
589 SelectObject(hdcmem, oldbm);
592 pbmi->bmiColors[0].rgbRed = 0xff;
593 pbmi->bmiColors[0].rgbGreen = 0xff;
594 pbmi->bmiColors[0].rgbBlue = 0xff;
595 pbmi->bmiColors[1].rgbRed = 0;
596 pbmi->bmiColors[1].rgbGreen = 0;
597 pbmi->bmiColors[1].rgbBlue = 0;
599 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
600 ok(hdib != NULL, "CreateDIBSection failed\n");
602 test_dib_info(hdib, bits, &pbmi->bmiHeader);
604 oldbm = SelectObject(hdcmem, hdib);
606 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
607 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
608 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
609 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
610 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
611 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
613 SelectObject(hdcmem, oldbm);
614 test_dib_info(hdib, bits, &pbmi->bmiHeader);
617 pbmi->bmiHeader.biBitCount = 4;
618 for (i = 0; i < 16; i++) {
619 pbmi->bmiColors[i].rgbRed = i;
620 pbmi->bmiColors[i].rgbGreen = 16-i;
621 pbmi->bmiColors[i].rgbBlue = 0;
623 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
624 ok(hdib != NULL, "CreateDIBSection failed\n");
625 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
626 ok(dibsec.dsBmih.biClrUsed == 16,
627 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
628 test_dib_info(hdib, bits, &pbmi->bmiHeader);
631 pbmi->bmiHeader.biBitCount = 8;
633 for (i = 0; i < 128; i++) {
634 pbmi->bmiColors[i].rgbRed = 255 - i * 2;
635 pbmi->bmiColors[i].rgbGreen = i * 2;
636 pbmi->bmiColors[i].rgbBlue = 0;
637 pbmi->bmiColors[255 - i].rgbRed = 0;
638 pbmi->bmiColors[255 - i].rgbGreen = i * 2;
639 pbmi->bmiColors[255 - i].rgbBlue = 255 - i * 2;
641 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
642 ok(hdib != NULL, "CreateDIBSection failed\n");
643 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
644 ok(dibsec.dsBmih.biClrUsed == 256,
645 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
647 oldbm = SelectObject(hdcmem, hdib);
649 for (i = 0; i < 256; i++) {
650 test_color(hdcmem, DIBINDEX(i),
651 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue));
652 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue),
653 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue));
656 SelectObject(hdcmem, oldbm);
657 test_dib_info(hdib, bits, &pbmi->bmiHeader);
660 pbmi->bmiHeader.biBitCount = 1;
662 /* Now create a palette and a palette indexed dib section */
663 memset(plogpal, 0, sizeof(logpalbuf));
664 plogpal->palVersion = 0x300;
665 plogpal->palNumEntries = 2;
666 plogpal->palPalEntry[0].peRed = 0xff;
667 plogpal->palPalEntry[0].peBlue = 0xff;
668 plogpal->palPalEntry[1].peGreen = 0xff;
670 index = (WORD*)pbmi->bmiColors;
673 hpal = CreatePalette(plogpal);
674 ok(hpal != NULL, "CreatePalette failed\n");
675 oldpal = SelectPalette(hdc, hpal, TRUE);
676 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
677 ok(hdib != NULL, "CreateDIBSection failed\n");
678 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
679 ok(dibsec.dsBmih.biClrUsed == 2, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
681 /* The colour table has already been grabbed from the dc, so we select back the
684 SelectPalette(hdc, oldpal, TRUE);
685 oldbm = SelectObject(hdcmem, hdib);
686 oldpal = SelectPalette(hdcmem, hpal, TRUE);
688 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
689 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
690 ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
691 rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
692 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
693 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
694 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
696 c0 = RGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen, plogpal->palPalEntry[0].peBlue);
697 c1 = RGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen, plogpal->palPalEntry[1].peBlue);
699 test_color(hdcmem, DIBINDEX(0), c0);
700 test_color(hdcmem, DIBINDEX(1), c1);
701 test_color(hdcmem, DIBINDEX(2), c0);
702 test_color(hdcmem, PALETTEINDEX(0), c0);
703 test_color(hdcmem, PALETTEINDEX(1), c1);
704 test_color(hdcmem, PALETTEINDEX(2), c0);
705 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen,
706 plogpal->palPalEntry[0].peBlue), c0);
707 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen,
708 plogpal->palPalEntry[1].peBlue), c1);
709 test_color(hdcmem, PALETTERGB(0, 0, 0), c1);
710 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0);
711 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0);
712 test_color(hdcmem, PALETTERGB(0, 1, 0), c1);
713 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1);
714 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0);
716 /* Bottom and 2nd row from top green, everything else magenta */
717 bits[0] = bits[1] = 0xff;
718 bits[13 * 4] = bits[13*4 + 1] = 0xff;
720 test_dib_info(hdib, bits, &pbmi->bmiHeader);
722 pbmi->bmiHeader.biBitCount = 32;
724 hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
725 ok(hdib2 != NULL, "CreateDIBSection failed\n");
726 hdcmem2 = CreateCompatibleDC(hdc);
727 oldbm2 = SelectObject(hdcmem2, hdib2);
729 BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
731 ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
732 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
734 SelectObject(hdcmem2, oldbm2);
735 test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
738 SelectObject(hdcmem, oldbm);
739 SelectPalette(hdcmem, oldpal, TRUE);
744 pbmi->bmiHeader.biBitCount = 8;
746 memset(plogpal, 0, sizeof(logpalbuf));
747 plogpal->palVersion = 0x300;
748 plogpal->palNumEntries = 256;
750 for (i = 0; i < 128; i++) {
751 plogpal->palPalEntry[i].peRed = 255 - i * 2;
752 plogpal->palPalEntry[i].peBlue = i * 2;
753 plogpal->palPalEntry[i].peGreen = 0;
754 plogpal->palPalEntry[255 - i].peRed = 0;
755 plogpal->palPalEntry[255 - i].peGreen = i * 2;
756 plogpal->palPalEntry[255 - i].peBlue = 255 - i * 2;
759 index = (WORD*)pbmi->bmiColors;
760 for (i = 0; i < 256; i++) {
764 hpal = CreatePalette(plogpal);
765 ok(hpal != NULL, "CreatePalette failed\n");
766 oldpal = SelectPalette(hdc, hpal, TRUE);
767 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
768 ok(hdib != NULL, "CreateDIBSection failed\n");
769 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
770 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
772 test_dib_info(hdib, bits, &pbmi->bmiHeader);
774 SelectPalette(hdc, oldpal, TRUE);
775 oldbm = SelectObject(hdcmem, hdib);
776 oldpal = SelectPalette(hdcmem, hpal, TRUE);
778 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
779 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
780 for (i = 0; i < 256; i++) {
781 ok(rgb[i].rgbRed == plogpal->palPalEntry[i].peRed &&
782 rgb[i].rgbBlue == plogpal->palPalEntry[i].peBlue &&
783 rgb[i].rgbGreen == plogpal->palPalEntry[i].peGreen,
784 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
785 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
788 for (i = 0; i < 256; i++) {
789 test_color(hdcmem, DIBINDEX(i),
790 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue));
791 test_color(hdcmem, PALETTEINDEX(i),
792 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue));
793 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue),
794 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue));
797 SelectPalette(hdcmem, oldpal, TRUE);
798 SelectObject(hdcmem, oldbm);
807 static void test_dib_formats(void)
812 int planes, bpp, compr;
818 bi = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
820 memdc = CreateCompatibleDC( 0 );
821 hbmp = CreateCompatibleBitmap( hdc, 10, 10 );
823 memset( data, 0xaa, sizeof(data) );
825 for (bpp = 0; bpp <= 64; bpp++)
827 for (planes = 0; planes <= 64; planes++)
829 for (compr = 0; compr < 8; compr++)
836 case 24: expect_ok = (compr == BI_RGB); break;
838 case 32: expect_ok = (compr == BI_RGB || compr == BI_BITFIELDS); break;
839 default: expect_ok = FALSE; break;
842 memset( bi, 0, sizeof(bi->bmiHeader) );
843 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
844 bi->bmiHeader.biWidth = 2;
845 bi->bmiHeader.biHeight = 2;
846 bi->bmiHeader.biPlanes = planes;
847 bi->bmiHeader.biBitCount = bpp;
848 bi->bmiHeader.biCompression = compr;
849 bi->bmiHeader.biSizeImage = 0;
850 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
851 ret = GetDIBits(hdc, hbmp, 0, 0, data, bi, DIB_RGB_COLORS);
852 if (expect_ok || (!bpp && compr != BI_JPEG && compr != BI_PNG) ||
853 (bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8))
854 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
856 ok( !ret || broken(!bpp && (compr == BI_JPEG || compr == BI_PNG)), /* nt4 */
857 "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
859 /* all functions check planes except GetDIBits with 0 lines */
860 if (!planes) expect_ok = FALSE;
861 memset( bi, 0, sizeof(bi->bmiHeader) );
862 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
863 bi->bmiHeader.biWidth = 2;
864 bi->bmiHeader.biHeight = 2;
865 bi->bmiHeader.biPlanes = planes;
866 bi->bmiHeader.biBitCount = bpp;
867 bi->bmiHeader.biCompression = compr;
868 bi->bmiHeader.biSizeImage = 0;
869 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
871 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
872 if (expect_ok && (planes == 1 || planes * bpp <= 16))
873 ok( hdib != NULL, "CreateDIBSection failed for %u/%u/%u\n", bpp, planes, compr );
875 ok( hdib == NULL, "CreateDIBSection succeeded for %u/%u/%u\n", bpp, planes, compr );
876 if (hdib) DeleteObject( hdib );
878 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, data, bi, DIB_RGB_COLORS );
879 /* no sanity checks in CreateDIBitmap except compression */
880 if (compr == BI_JPEG || compr == BI_PNG)
881 ok( hdib == NULL || broken(hdib != NULL), /* nt4 */
882 "CreateDIBitmap succeeded for %u/%u/%u\n", bpp, planes, compr );
884 ok( hdib != NULL, "CreateDIBitmap failed for %u/%u/%u\n", bpp, planes, compr );
885 if (hdib) DeleteObject( hdib );
887 /* RLE needs a size */
888 bi->bmiHeader.biSizeImage = 0;
889 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
891 ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
894 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
895 "SetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
896 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
898 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
901 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
902 "SetDIBitsToDevice succeeded for %u/%u/%u\n", bpp, planes, compr );
903 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
905 ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
908 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
909 "StretchDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
911 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
913 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
915 ok( !ret, "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
916 ok( bi->bmiHeader.biBitCount == bpp, "GetDIBits modified bpp %u/%u\n",
917 bpp, bi->bmiHeader.biBitCount );
919 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
920 bi->bmiHeader.biWidth = 2;
921 bi->bmiHeader.biHeight = 2;
922 bi->bmiHeader.biPlanes = planes;
923 bi->bmiHeader.biBitCount = bpp;
924 bi->bmiHeader.biCompression = compr;
925 bi->bmiHeader.biSizeImage = 1;
926 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
927 /* RLE allowed with valid biSizeImage */
928 if ((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)) expect_ok = TRUE;
930 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
932 ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
934 ok( !ret, "SetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
935 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
937 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
939 ok( !ret, "SetDIBitsToDevice succeeded for %u/%u/%u\n", bpp, planes, compr );
940 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
942 ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
944 ok( !ret, "StretchDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
946 bi->bmiHeader.biSizeImage = 0;
947 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
948 if (expect_ok || !bpp)
949 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
951 ok( !ret, "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
956 memset( bi, 0, sizeof(bi->bmiHeader) );
957 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
958 bi->bmiHeader.biWidth = 2;
959 bi->bmiHeader.biHeight = 2;
960 bi->bmiHeader.biPlanes = 1;
961 bi->bmiHeader.biBitCount = 16;
962 bi->bmiHeader.biCompression = BI_BITFIELDS;
963 bi->bmiHeader.biSizeImage = 0;
964 *(DWORD *)&bi->bmiColors[0] = 0;
965 *(DWORD *)&bi->bmiColors[1] = 0;
966 *(DWORD *)&bi->bmiColors[2] = 0;
968 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
969 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
970 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
971 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
972 /* other functions don't check */
973 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
974 ok( hdib != NULL, "CreateDIBitmap failed with null bitfields\n" );
975 DeleteObject( hdib );
976 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
977 ok( ret, "SetDIBitsToDevice failed with null bitfields\n" );
978 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
979 ok( ret, "StretchDIBits failed with null bitfields\n" );
980 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
981 ok( ret, "GetDIBits failed with null bitfields\n" );
982 bi->bmiHeader.biPlanes = 1;
983 bi->bmiHeader.biBitCount = 16;
984 bi->bmiHeader.biCompression = BI_BITFIELDS;
985 bi->bmiHeader.biSizeImage = 0;
986 *(DWORD *)&bi->bmiColors[0] = 0;
987 *(DWORD *)&bi->bmiColors[1] = 0;
988 *(DWORD *)&bi->bmiColors[2] = 0;
989 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
990 ok( ret, "GetDIBits failed with null bitfields\n" );
992 /* all fields must be non-zero */
993 *(DWORD *)&bi->bmiColors[0] = 3;
994 *(DWORD *)&bi->bmiColors[1] = 0;
995 *(DWORD *)&bi->bmiColors[2] = 7;
996 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
997 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
998 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
999 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1001 /* garbage is ok though */
1002 *(DWORD *)&bi->bmiColors[0] = 0x55;
1003 *(DWORD *)&bi->bmiColors[1] = 0x44;
1004 *(DWORD *)&bi->bmiColors[2] = 0x33;
1005 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1006 ok( hdib != NULL, "CreateDIBSection failed with bad bitfields\n" );
1007 if (hdib) DeleteObject( hdib );
1008 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1009 ok( ret, "SetDIBits failed with bad bitfields\n" );
1011 bi->bmiHeader.biWidth = -2;
1012 bi->bmiHeader.biHeight = 2;
1013 bi->bmiHeader.biBitCount = 32;
1014 bi->bmiHeader.biCompression = BI_RGB;
1015 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1016 ok( hdib == NULL, "CreateDIBSection succeeded with negative width\n" );
1017 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1018 ok( hdib == NULL, "CreateDIBitmap succeeded with negative width\n" );
1019 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1020 ok( !ret, "SetDIBits succeeded with negative width\n" );
1021 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1022 ok( !ret, "SetDIBitsToDevice succeeded with negative width\n" );
1023 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1024 ok( !ret, "StretchDIBits succeeded with negative width\n" );
1025 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1026 ok( !ret, "GetDIBits succeeded with negative width\n" );
1027 bi->bmiHeader.biWidth = -2;
1028 bi->bmiHeader.biHeight = 2;
1029 bi->bmiHeader.biBitCount = 32;
1030 bi->bmiHeader.biCompression = BI_RGB;
1031 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1032 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with negative width\n" );
1034 bi->bmiHeader.biWidth = 0;
1035 bi->bmiHeader.biHeight = 2;
1036 bi->bmiHeader.biBitCount = 32;
1037 bi->bmiHeader.biCompression = BI_RGB;
1038 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1039 ok( hdib == NULL, "CreateDIBSection succeeded with zero width\n" );
1040 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1041 ok( hdib != NULL, "CreateDIBitmap failed with zero width\n" );
1042 DeleteObject( hdib );
1043 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1044 ok( !ret || broken(ret), /* nt4 */ "SetDIBits succeeded with zero width\n" );
1045 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1046 ok( !ret || broken(ret), /* nt4 */ "SetDIBitsToDevice succeeded with zero width\n" );
1047 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1048 ok( !ret || broken(ret), /* nt4 */ "StretchDIBits succeeded with zero width\n" );
1049 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1050 ok( !ret, "GetDIBits succeeded with zero width\n" );
1051 bi->bmiHeader.biWidth = 0;
1052 bi->bmiHeader.biHeight = 2;
1053 bi->bmiHeader.biBitCount = 32;
1054 bi->bmiHeader.biCompression = BI_RGB;
1055 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1056 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero width\n" );
1058 bi->bmiHeader.biWidth = 2;
1059 bi->bmiHeader.biHeight = 0;
1060 bi->bmiHeader.biBitCount = 32;
1061 bi->bmiHeader.biCompression = BI_RGB;
1062 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1063 ok( hdib == NULL, "CreateDIBSection succeeded with zero height\n" );
1064 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1065 ok( hdib != NULL, "CreateDIBitmap failed with zero height\n" );
1066 DeleteObject( hdib );
1067 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1068 ok( !ret, "SetDIBits succeeded with zero height\n" );
1069 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1070 ok( !ret, "SetDIBitsToDevice succeeded with zero height\n" );
1071 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1072 ok( !ret, "StretchDIBits succeeded with zero height\n" );
1073 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1074 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1075 bi->bmiHeader.biWidth = 2;
1076 bi->bmiHeader.biHeight = 0;
1077 bi->bmiHeader.biBitCount = 32;
1078 bi->bmiHeader.biCompression = BI_RGB;
1079 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1080 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1083 DeleteObject( hbmp );
1084 ReleaseDC( 0, hdc );
1085 HeapFree( GetProcessHeap(), 0, bi );
1088 static void test_mono_dibsection(void)
1091 HBITMAP old_bm, mono_ds;
1092 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
1093 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
1100 memdc = CreateCompatibleDC(hdc);
1102 memset(pbmi, 0, sizeof(bmibuf));
1103 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
1104 pbmi->bmiHeader.biHeight = 10;
1105 pbmi->bmiHeader.biWidth = 10;
1106 pbmi->bmiHeader.biBitCount = 1;
1107 pbmi->bmiHeader.biPlanes = 1;
1108 pbmi->bmiHeader.biCompression = BI_RGB;
1109 pbmi->bmiColors[0].rgbRed = 0xff;
1110 pbmi->bmiColors[0].rgbGreen = 0xff;
1111 pbmi->bmiColors[0].rgbBlue = 0xff;
1112 pbmi->bmiColors[1].rgbRed = 0x0;
1113 pbmi->bmiColors[1].rgbGreen = 0x0;
1114 pbmi->bmiColors[1].rgbBlue = 0x0;
1117 * First dib section is 'inverted' ie color[0] is white, color[1] is black
1120 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1121 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1122 old_bm = SelectObject(memdc, mono_ds);
1124 /* black border, white interior */
1125 Rectangle(memdc, 0, 0, 10, 10);
1126 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1127 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1129 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1131 memset(bits, 0, sizeof(bits));
1134 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1135 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1137 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1139 pbmi->bmiColors[0].rgbRed = 0x0;
1140 pbmi->bmiColors[0].rgbGreen = 0x0;
1141 pbmi->bmiColors[0].rgbBlue = 0x0;
1142 pbmi->bmiColors[1].rgbRed = 0xff;
1143 pbmi->bmiColors[1].rgbGreen = 0xff;
1144 pbmi->bmiColors[1].rgbBlue = 0xff;
1146 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1147 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1149 SelectObject(memdc, old_bm);
1150 DeleteObject(mono_ds);
1153 * Next dib section is 'normal' ie color[0] is black, color[1] is white
1156 pbmi->bmiColors[0].rgbRed = 0x0;
1157 pbmi->bmiColors[0].rgbGreen = 0x0;
1158 pbmi->bmiColors[0].rgbBlue = 0x0;
1159 pbmi->bmiColors[1].rgbRed = 0xff;
1160 pbmi->bmiColors[1].rgbGreen = 0xff;
1161 pbmi->bmiColors[1].rgbBlue = 0xff;
1163 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1164 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1165 old_bm = SelectObject(memdc, mono_ds);
1167 /* black border, white interior */
1168 Rectangle(memdc, 0, 0, 10, 10);
1169 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
1170 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
1172 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
1174 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1175 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1177 /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
1179 pbmi->bmiColors[0].rgbRed = 0xff;
1180 pbmi->bmiColors[0].rgbGreen = 0xff;
1181 pbmi->bmiColors[0].rgbBlue = 0xff;
1182 pbmi->bmiColors[1].rgbRed = 0x0;
1183 pbmi->bmiColors[1].rgbGreen = 0x0;
1184 pbmi->bmiColors[1].rgbBlue = 0x0;
1186 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1187 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1190 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
1193 pbmi->bmiColors[0].rgbRed = 0xff;
1194 pbmi->bmiColors[0].rgbGreen = 0xff;
1195 pbmi->bmiColors[0].rgbBlue = 0xff;
1196 pbmi->bmiColors[1].rgbRed = 0x0;
1197 pbmi->bmiColors[1].rgbGreen = 0x0;
1198 pbmi->bmiColors[1].rgbBlue = 0x0;
1199 num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors);
1200 ok(num == 2, "num = %d\n", num);
1202 /* black border, white interior */
1203 Rectangle(memdc, 0, 0, 10, 10);
1204 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1205 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1207 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1209 memset(bits, 0, sizeof(bits));
1212 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1213 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1215 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1217 pbmi->bmiColors[0].rgbRed = 0x0;
1218 pbmi->bmiColors[0].rgbGreen = 0x0;
1219 pbmi->bmiColors[0].rgbBlue = 0x0;
1220 pbmi->bmiColors[1].rgbRed = 0xff;
1221 pbmi->bmiColors[1].rgbGreen = 0xff;
1222 pbmi->bmiColors[1].rgbBlue = 0xff;
1224 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1225 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1227 SelectObject(memdc, old_bm);
1228 DeleteObject(mono_ds);
1231 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
1234 pbmi->bmiColors[0].rgbRed = 0xff;
1235 pbmi->bmiColors[0].rgbGreen = 0x0;
1236 pbmi->bmiColors[0].rgbBlue = 0x0;
1237 pbmi->bmiColors[1].rgbRed = 0xfe;
1238 pbmi->bmiColors[1].rgbGreen = 0x0;
1239 pbmi->bmiColors[1].rgbBlue = 0x0;
1241 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1242 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1243 old_bm = SelectObject(memdc, mono_ds);
1245 /* black border, white interior */
1246 Rectangle(memdc, 0, 0, 10, 10);
1247 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1248 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1250 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1252 pbmi->bmiColors[0].rgbRed = 0x0;
1253 pbmi->bmiColors[0].rgbGreen = 0x0;
1254 pbmi->bmiColors[0].rgbBlue = 0x0;
1255 pbmi->bmiColors[1].rgbRed = 0xff;
1256 pbmi->bmiColors[1].rgbGreen = 0xff;
1257 pbmi->bmiColors[1].rgbBlue = 0xff;
1259 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1260 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1262 /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
1264 pbmi->bmiColors[0].rgbRed = 0xff;
1265 pbmi->bmiColors[0].rgbGreen = 0xff;
1266 pbmi->bmiColors[0].rgbBlue = 0xff;
1267 pbmi->bmiColors[1].rgbRed = 0x0;
1268 pbmi->bmiColors[1].rgbGreen = 0x0;
1269 pbmi->bmiColors[1].rgbBlue = 0x0;
1271 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1272 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1274 SelectObject(memdc, old_bm);
1275 DeleteObject(mono_ds);
1281 static void test_bitmap(void)
1283 char buf[256], buf_cmp[256];
1284 HBITMAP hbmp, hbmp_old;
1290 hdc = CreateCompatibleDC(0);
1293 SetLastError(0xdeadbeef);
1294 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1297 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1298 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1299 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1304 SetLastError(0xdeadbeef);
1305 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1308 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1309 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1310 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1315 SetLastError(0xdeadbeef);
1316 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1317 ok(!hbmp, "CreateBitmap should fail\n");
1319 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1320 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1324 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1325 assert(hbmp != NULL);
1327 ret = GetObject(hbmp, sizeof(bm), &bm);
1328 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1330 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1331 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1332 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1333 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1334 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1335 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1336 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1338 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1339 assert(sizeof(buf) == sizeof(buf_cmp));
1341 ret = GetBitmapBits(hbmp, 0, NULL);
1342 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1344 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1345 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1347 memset(buf, 0xAA, sizeof(buf));
1348 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1349 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1350 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1352 hbmp_old = SelectObject(hdc, hbmp);
1354 ret = GetObject(hbmp, sizeof(bm), &bm);
1355 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1357 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1358 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1359 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1360 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1361 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1362 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1363 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1365 memset(buf, 0xAA, sizeof(buf));
1366 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1367 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1368 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1370 hbmp_old = SelectObject(hdc, hbmp_old);
1371 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1373 /* test various buffer sizes for GetObject */
1374 ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
1375 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1377 ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1378 ok(ret == 0, "%d != 0\n", ret);
1380 ret = GetObject(hbmp, 0, &bm);
1381 ok(ret == 0, "%d != 0\n", ret);
1383 ret = GetObject(hbmp, 1, &bm);
1384 ok(ret == 0, "%d != 0\n", ret);
1390 static void test_bmBits(void)
1396 memset(bits, 0, sizeof(bits));
1397 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1398 ok(hbmp != NULL, "CreateBitmap failed\n");
1400 memset(&bmp, 0xFF, sizeof(bmp));
1401 ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1402 "GetObject failed or returned a wrong structure size\n");
1403 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1408 static void test_GetDIBits_selected_DIB(UINT bpp)
1415 UINT dib_size, dib32_size;
1422 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1423 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1425 /* Create a DIB section with a color table */
1427 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1428 info->bmiHeader.biWidth = 32;
1429 info->bmiHeader.biHeight = 32;
1430 info->bmiHeader.biPlanes = 1;
1431 info->bmiHeader.biBitCount = bpp;
1432 info->bmiHeader.biCompression = BI_RGB;
1433 info->bmiHeader.biXPelsPerMeter = 0;
1434 info->bmiHeader.biYPelsPerMeter = 0;
1435 info->bmiHeader.biClrUsed = 0;
1436 info->bmiHeader.biClrImportant = 0;
1438 for (i=0; i < (1u << bpp); i++)
1440 BYTE c = i * (1 << (8 - bpp));
1441 info->bmiColors[i].rgbRed = c;
1442 info->bmiColors[i].rgbGreen = c;
1443 info->bmiColors[i].rgbBlue = c;
1444 info->bmiColors[i].rgbReserved = 0;
1447 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1448 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1449 dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1451 /* Set the bits of the DIB section */
1452 for (i=0; i < dib_size; i++)
1454 ((BYTE *)bits)[i] = i % 256;
1457 /* Select the DIB into a DC */
1458 dib_dc = CreateCompatibleDC(NULL);
1459 old_bmp = SelectObject(dib_dc, dib);
1460 dc = CreateCompatibleDC(NULL);
1461 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
1463 /* Copy the DIB attributes but not the color table */
1464 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1466 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1467 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1469 /* Compare the color table and the bits */
1470 for (i=0; i < (1u << bpp); i++)
1471 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1472 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1473 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1474 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1475 "color table entry %d differs (bpp %d)\n", i, bpp );
1477 ok( !memcmp( bits, bits2, dib_size ), "bit mismatch (bpp %d)\n", bpp );
1479 /* Test various combinations of lines = 0 and bits2 = NULL */
1480 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1481 res = GetDIBits( dc, dib, 0, 0, bits2, info2, DIB_RGB_COLORS );
1482 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1483 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1484 "color table mismatch (bpp %d)\n", bpp );
1486 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1487 res = GetDIBits( dc, dib, 0, 0, NULL, info2, DIB_RGB_COLORS );
1488 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1489 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1490 "color table mismatch (bpp %d)\n", bpp );
1492 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1493 res = GetDIBits( dc, dib, 0, info->bmiHeader.biHeight, NULL, info2, DIB_RGB_COLORS );
1494 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1495 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1496 "color table mismatch (bpp %d)\n", bpp );
1498 /* Map into a 32bit-DIB */
1499 info2->bmiHeader.biBitCount = 32;
1500 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1501 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1503 /* Check if last pixel was set */
1504 pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
1505 ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
1507 HeapFree(GetProcessHeap(), 0, bits2);
1510 SelectObject(dib_dc, old_bmp);
1513 HeapFree(GetProcessHeap(), 0, info2);
1514 HeapFree(GetProcessHeap(), 0, info);
1517 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1531 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1532 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1534 width = height = 16;
1536 /* Create a DDB (device-dependent bitmap) */
1540 ddb = CreateBitmap(width, height, 1, 1, NULL);
1544 HDC screen_dc = GetDC(NULL);
1545 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1546 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1547 ReleaseDC(NULL, screen_dc);
1550 /* Set the pixels */
1551 ddb_dc = CreateCompatibleDC(NULL);
1552 old_bmp = SelectObject(ddb_dc, ddb);
1553 for (i = 0; i < width; i++)
1555 for (j=0; j < height; j++)
1557 BYTE c = (i * width + j) % 256;
1558 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1561 SelectObject(ddb_dc, old_bmp);
1563 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1564 info->bmiHeader.biWidth = width;
1565 info->bmiHeader.biHeight = height;
1566 info->bmiHeader.biPlanes = 1;
1567 info->bmiHeader.biBitCount = bpp;
1568 info->bmiHeader.biCompression = BI_RGB;
1570 dc = CreateCompatibleDC(NULL);
1572 /* Fill in biSizeImage */
1573 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1574 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1576 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1577 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1580 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1581 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1583 /* Copy the DIB attributes but not the color table */
1584 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1586 /* Select the DDB into another DC */
1587 old_bmp = SelectObject(ddb_dc, ddb);
1590 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1591 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1593 /* Compare the color table and the bits */
1596 for (i=0; i < (1u << bpp); i++)
1597 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1598 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1599 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1600 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1601 "color table entry %d differs (bpp %d)\n", i, bpp );
1604 ok( !memcmp( bits, bits2, info->bmiHeader.biSizeImage ), "bit mismatch (bpp %d)\n", bpp );
1606 /* Test the palette */
1607 if (info2->bmiHeader.biBitCount <= 8)
1609 WORD *colors = (WORD*)info2->bmiColors;
1611 /* Get the palette indices */
1612 res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1613 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1615 for (i = 0; i < (1 << info->bmiHeader.biBitCount); i++)
1616 ok( colors[i] == i, "%d: got %d (bpp %d)\n", i, colors[i], bpp );
1619 HeapFree(GetProcessHeap(), 0, bits2);
1620 HeapFree(GetProcessHeap(), 0, bits);
1623 SelectObject(ddb_dc, old_bmp);
1626 HeapFree(GetProcessHeap(), 0, info2);
1627 HeapFree(GetProcessHeap(), 0, info);
1630 static void test_GetDIBits(void)
1632 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1633 static const BYTE bmp_bits_1[16 * 2] =
1635 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1636 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1637 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1638 0xff,0xff, 0,0, 0xff,0xff, 0,0
1640 /* 4-bytes aligned 1-bit DIB data: 16x16 */
1641 static const BYTE dib_bits_1[16 * 4] =
1643 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1644 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1645 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1646 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1648 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1649 static const BYTE bmp_bits_24[16 * 16*3] =
1651 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1652 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1653 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1654 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1655 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1656 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1657 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1658 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1659 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1660 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1661 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1662 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1663 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1664 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1665 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1666 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1667 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1668 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1669 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1670 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1671 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1672 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1673 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1674 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1675 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1676 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1677 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1678 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1679 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1680 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1681 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1682 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1684 /* 4-bytes aligned 24-bit DIB data: 16x16 */
1685 static const BYTE dib_bits_24[16 * 16*3] =
1687 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1688 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1689 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1690 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1691 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1692 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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
1723 int i, bytes, lines;
1725 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1726 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1727 PALETTEENTRY pal_ents[20];
1731 /* 1-bit source bitmap data */
1732 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1733 ok(hbmp != 0, "CreateBitmap failed\n");
1735 memset(&bm, 0xAA, sizeof(bm));
1736 bytes = GetObject(hbmp, sizeof(bm), &bm);
1737 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1738 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1739 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1740 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1741 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1742 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1743 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1744 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1746 bytes = GetBitmapBits(hbmp, 0, NULL);
1747 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1748 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1749 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1750 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1752 /* retrieve 1-bit DIB data */
1753 memset(bi, 0, sizeof(*bi));
1754 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1755 bi->bmiHeader.biWidth = bm.bmWidth;
1756 bi->bmiHeader.biHeight = bm.bmHeight;
1757 bi->bmiHeader.biPlanes = 1;
1758 bi->bmiHeader.biBitCount = 1;
1759 bi->bmiHeader.biCompression = BI_RGB;
1760 bi->bmiHeader.biSizeImage = 0;
1761 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1762 SetLastError(0xdeadbeef);
1763 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1764 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1765 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1766 broken(GetLastError() == 0xdeadbeef), /* winnt */
1767 "wrong error %u\n", GetLastError());
1768 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1770 memset(buf, 0xAA, sizeof(buf));
1771 SetLastError(0xdeadbeef);
1772 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1773 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1774 lines, bm.bmHeight, GetLastError());
1775 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1777 /* the color table consists of black and white */
1778 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1779 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1780 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1781 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1782 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1783 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1784 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1785 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1786 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1787 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1788 for (i = 2; i < 256; i++)
1790 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1791 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1792 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1793 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1794 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1797 /* returned bits are DWORD aligned and upside down */
1798 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1800 /* Test the palette indices */
1801 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1802 SetLastError(0xdeadbeef);
1803 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1804 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1805 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1806 for (i = 2; i < 256; i++)
1807 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[1]);
1809 /* retrieve 24-bit DIB data */
1810 memset(bi, 0, sizeof(*bi));
1811 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1812 bi->bmiHeader.biWidth = bm.bmWidth;
1813 bi->bmiHeader.biHeight = bm.bmHeight;
1814 bi->bmiHeader.biPlanes = 1;
1815 bi->bmiHeader.biBitCount = 24;
1816 bi->bmiHeader.biCompression = BI_RGB;
1817 bi->bmiHeader.biSizeImage = 0;
1818 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1819 memset(buf, 0xAA, sizeof(buf));
1820 SetLastError(0xdeadbeef);
1821 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1822 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1823 lines, bm.bmHeight, GetLastError());
1824 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1826 /* the color table doesn't exist for 24-bit images */
1827 for (i = 0; i < 256; i++)
1829 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1830 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1831 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1832 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1833 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1836 /* returned bits are DWORD aligned and upside down */
1837 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1840 /* 24-bit source bitmap data */
1841 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1842 ok(hbmp != 0, "CreateBitmap failed\n");
1843 SetLastError(0xdeadbeef);
1844 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1845 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1846 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1847 lines, bm.bmHeight, GetLastError());
1849 memset(&bm, 0xAA, sizeof(bm));
1850 bytes = GetObject(hbmp, sizeof(bm), &bm);
1851 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1852 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1853 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1854 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1855 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1856 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1857 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1858 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1860 bytes = GetBitmapBits(hbmp, 0, NULL);
1861 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
1862 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1863 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1864 bm.bmWidthBytes * bm.bmHeight, bytes);
1866 /* retrieve 1-bit DIB data */
1867 memset(bi, 0, sizeof(*bi));
1868 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1869 bi->bmiHeader.biWidth = bm.bmWidth;
1870 bi->bmiHeader.biHeight = bm.bmHeight;
1871 bi->bmiHeader.biPlanes = 1;
1872 bi->bmiHeader.biBitCount = 1;
1873 bi->bmiHeader.biCompression = BI_RGB;
1874 bi->bmiHeader.biSizeImage = 0;
1875 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1876 memset(buf, 0xAA, sizeof(buf));
1877 SetLastError(0xdeadbeef);
1878 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1879 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1880 lines, bm.bmHeight, GetLastError());
1881 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1883 /* the color table consists of black and white */
1884 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1885 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1886 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1887 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1888 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1889 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1890 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1891 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1892 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1893 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1894 for (i = 2; i < 256; i++)
1896 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1897 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1898 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1899 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1900 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1903 /* returned bits are DWORD aligned and upside down */
1904 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1906 /* Test the palette indices */
1907 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1908 SetLastError(0xdeadbeef);
1909 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1910 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1911 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1912 for (i = 2; i < 256; i++)
1913 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[i]);
1915 /* retrieve 4-bit DIB data */
1916 memset(bi, 0, sizeof(*bi));
1917 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1918 bi->bmiHeader.biWidth = bm.bmWidth;
1919 bi->bmiHeader.biHeight = bm.bmHeight;
1920 bi->bmiHeader.biPlanes = 1;
1921 bi->bmiHeader.biBitCount = 4;
1922 bi->bmiHeader.biCompression = BI_RGB;
1923 bi->bmiHeader.biSizeImage = 0;
1924 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1925 memset(buf, 0xAA, sizeof(buf));
1926 SetLastError(0xdeadbeef);
1927 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1928 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1929 lines, bm.bmHeight, GetLastError());
1931 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
1933 for (i = 0; i < 16; i++)
1936 int entry = i < 8 ? i : i + 4;
1938 if(entry == 7) entry = 12;
1939 else if(entry == 12) entry = 7;
1941 expect.rgbRed = pal_ents[entry].peRed;
1942 expect.rgbGreen = pal_ents[entry].peGreen;
1943 expect.rgbBlue = pal_ents[entry].peBlue;
1944 expect.rgbReserved = 0;
1946 ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
1947 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
1948 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
1949 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1950 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1953 /* retrieve 8-bit DIB data */
1954 memset(bi, 0, sizeof(*bi));
1955 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1956 bi->bmiHeader.biWidth = bm.bmWidth;
1957 bi->bmiHeader.biHeight = bm.bmHeight;
1958 bi->bmiHeader.biPlanes = 1;
1959 bi->bmiHeader.biBitCount = 8;
1960 bi->bmiHeader.biCompression = BI_RGB;
1961 bi->bmiHeader.biSizeImage = 0;
1962 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1963 memset(buf, 0xAA, sizeof(buf));
1964 SetLastError(0xdeadbeef);
1965 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1966 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1967 lines, bm.bmHeight, GetLastError());
1969 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
1971 for (i = 0; i < 256; i++)
1975 if (i < 10 || i >= 246)
1977 int entry = i < 10 ? i : i - 236;
1978 expect.rgbRed = pal_ents[entry].peRed;
1979 expect.rgbGreen = pal_ents[entry].peGreen;
1980 expect.rgbBlue = pal_ents[entry].peBlue;
1984 expect.rgbRed = (i & 0x07) << 5;
1985 expect.rgbGreen = (i & 0x38) << 2;
1986 expect.rgbBlue = i & 0xc0;
1988 expect.rgbReserved = 0;
1990 ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
1991 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
1992 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
1993 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1994 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1997 /* retrieve 24-bit DIB data */
1998 memset(bi, 0, sizeof(*bi));
1999 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2000 bi->bmiHeader.biWidth = bm.bmWidth;
2001 bi->bmiHeader.biHeight = bm.bmHeight;
2002 bi->bmiHeader.biPlanes = 1;
2003 bi->bmiHeader.biBitCount = 24;
2004 bi->bmiHeader.biCompression = BI_RGB;
2005 bi->bmiHeader.biSizeImage = 0;
2006 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
2007 memset(buf, 0xAA, sizeof(buf));
2008 SetLastError(0xdeadbeef);
2009 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2010 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2011 lines, bm.bmHeight, GetLastError());
2012 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2014 /* the color table doesn't exist for 24-bit images */
2015 for (i = 0; i < 256; i++)
2017 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
2018 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
2019 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2020 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
2021 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
2024 /* returned bits are DWORD aligned and upside down */
2025 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2031 static void test_GetDIBits_BI_BITFIELDS(void)
2033 /* Try a screen resolution detection technique
2034 * from the September 1999 issue of Windows Developer's Journal
2035 * which seems to be in widespread use.
2036 * http://www.lesher.ws/highcolor.html
2037 * http://www.lesher.ws/vidfmt.c
2038 * It hinges on being able to retrieve the bitmaps
2039 * for the three primary colors in non-paletted 16 bit mode.
2041 char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
2043 LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
2044 DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
2050 memset(dibinfo, 0, sizeof(dibinfo_buf));
2051 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2054 ok(hdc != NULL, "GetDC failed?\n");
2055 hbm = CreateCompatibleBitmap(hdc, 1, 1);
2056 ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
2058 /* Call GetDIBits to fill in bmiHeader. */
2059 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2060 ok(ret == 1, "GetDIBits failed\n");
2061 if (dibinfo->bmiHeader.biBitCount > 8)
2063 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2064 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2065 "compression is %u (%d bpp)\n", dibinfo->bmiHeader.biCompression, dibinfo->bmiHeader.biBitCount );
2067 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2069 ok( !bitmasks[0], "red mask is set\n" );
2070 ok( !bitmasks[1], "green mask is set\n" );
2071 ok( !bitmasks[2], "blue mask is set\n" );
2073 /* test with NULL bits pointer and correct bpp */
2074 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2075 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2076 ok(ret == 1, "GetDIBits failed\n");
2078 ok( bitmasks[0] != 0, "red mask is not set\n" );
2079 ok( bitmasks[1] != 0, "green mask is not set\n" );
2080 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2081 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2083 /* test with valid bits pointer */
2084 memset(dibinfo, 0, sizeof(dibinfo_buf));
2085 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2086 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2087 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2088 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2089 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2090 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2092 ok( bitmasks[0] != 0, "red mask is not set\n" );
2093 ok( bitmasks[1] != 0, "green mask is not set\n" );
2094 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2095 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2097 /* now with bits and 0 lines */
2098 memset(dibinfo, 0, sizeof(dibinfo_buf));
2099 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2100 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2101 SetLastError(0xdeadbeef);
2102 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2103 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2105 ok( !bitmasks[0], "red mask is set\n" );
2106 ok( !bitmasks[1], "green mask is set\n" );
2107 ok( !bitmasks[2], "blue mask is set\n" );
2108 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2110 memset(bitmasks, 0, 3*sizeof(DWORD));
2111 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2112 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2113 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2115 ok( bitmasks[0] != 0, "red mask is not set\n" );
2116 ok( bitmasks[1] != 0, "green mask is not set\n" );
2117 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2118 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2121 else skip("bitmap in colortable mode, skipping BI_BITFIELDS tests\n");
2125 /* same thing now with a 32-bpp DIB section */
2127 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2128 dibinfo->bmiHeader.biWidth = 1;
2129 dibinfo->bmiHeader.biHeight = 1;
2130 dibinfo->bmiHeader.biPlanes = 1;
2131 dibinfo->bmiHeader.biBitCount = 32;
2132 dibinfo->bmiHeader.biCompression = BI_RGB;
2133 dibinfo->bmiHeader.biSizeImage = 0;
2134 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2135 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2136 dibinfo->bmiHeader.biClrUsed = 0;
2137 dibinfo->bmiHeader.biClrImportant = 0;
2138 bitmasks[0] = 0x0000ff;
2139 bitmasks[1] = 0x00ff00;
2140 bitmasks[2] = 0xff0000;
2141 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2142 ok( hbm != 0, "failed to create bitmap\n" );
2144 memset(dibinfo, 0, sizeof(dibinfo_buf));
2145 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2146 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2147 ok(ret == 1, "GetDIBits failed\n");
2148 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2150 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2151 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2152 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2153 ok( !bitmasks[0], "red mask is set\n" );
2154 ok( !bitmasks[1], "green mask is set\n" );
2155 ok( !bitmasks[2], "blue mask is set\n" );
2157 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2158 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2159 ok(ret == 1, "GetDIBits failed\n");
2160 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2161 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2162 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2163 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2164 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2166 ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
2167 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2168 ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
2170 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2174 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2175 dibinfo->bmiHeader.biWidth = 1;
2176 dibinfo->bmiHeader.biHeight = 1;
2177 dibinfo->bmiHeader.biPlanes = 1;
2178 dibinfo->bmiHeader.biBitCount = 32;
2179 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2180 dibinfo->bmiHeader.biSizeImage = 0;
2181 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2182 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2183 dibinfo->bmiHeader.biClrUsed = 0;
2184 dibinfo->bmiHeader.biClrImportant = 0;
2185 bitmasks[0] = 0x0000ff;
2186 bitmasks[1] = 0x00ff00;
2187 bitmasks[2] = 0xff0000;
2188 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2189 ok( hbm != 0, "failed to create bitmap\n" );
2193 memset(dibinfo, 0, sizeof(dibinfo_buf));
2194 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2195 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2196 ok(ret == 1, "GetDIBits failed\n");
2198 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
2199 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2200 ok( !bitmasks[0], "red mask is set\n" );
2201 ok( !bitmasks[1], "green mask is set\n" );
2202 ok( !bitmasks[2], "blue mask is set\n" );
2204 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2205 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2206 ok(ret == 1, "GetDIBits failed\n");
2207 ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
2208 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2209 ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
2210 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2215 /* 24-bpp DIB sections don't have bitfields */
2217 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2218 dibinfo->bmiHeader.biWidth = 1;
2219 dibinfo->bmiHeader.biHeight = 1;
2220 dibinfo->bmiHeader.biPlanes = 1;
2221 dibinfo->bmiHeader.biBitCount = 24;
2222 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2223 dibinfo->bmiHeader.biSizeImage = 0;
2224 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2225 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2226 dibinfo->bmiHeader.biClrUsed = 0;
2227 dibinfo->bmiHeader.biClrImportant = 0;
2228 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2229 ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
2230 dibinfo->bmiHeader.biCompression = BI_RGB;
2231 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2232 ok( hbm != 0, "failed to create bitmap\n" );
2234 memset(dibinfo, 0, sizeof(dibinfo_buf));
2235 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2236 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2237 ok(ret == 1, "GetDIBits failed\n");
2238 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2240 ok( dibinfo->bmiHeader.biCompression == BI_RGB,
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( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2250 ok( !bitmasks[0], "red mask is set\n" );
2251 ok( !bitmasks[1], "green mask is set\n" );
2252 ok( !bitmasks[2], "blue mask is set\n" );
2253 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2256 ReleaseDC(NULL, hdc);
2259 static void test_select_object(void)
2262 HBITMAP hbm, hbm_old;
2264 DWORD depths[] = {8, 15, 16, 24, 32};
2269 ok(hdc != 0, "GetDC(0) failed\n");
2270 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2271 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2273 hbm_old = SelectObject(hdc, hbm);
2274 ok(hbm_old == 0, "SelectObject should fail\n");
2279 hdc = CreateCompatibleDC(0);
2280 ok(hdc != 0, "GetDC(0) failed\n");
2281 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2282 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2284 hbm_old = SelectObject(hdc, hbm);
2285 ok(hbm_old != 0, "SelectObject failed\n");
2286 hbm_old = SelectObject(hdc, hbm_old);
2287 ok(hbm_old == hbm, "SelectObject failed\n");
2291 /* test an 1-bpp bitmap */
2292 planes = GetDeviceCaps(hdc, PLANES);
2295 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
2296 ok(hbm != 0, "CreateBitmap failed\n");
2298 hbm_old = SelectObject(hdc, hbm);
2299 ok(hbm_old != 0, "SelectObject failed\n");
2300 hbm_old = SelectObject(hdc, hbm_old);
2301 ok(hbm_old == hbm, "SelectObject failed\n");
2305 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
2306 /* test a color bitmap to dc bpp matching */
2307 planes = GetDeviceCaps(hdc, PLANES);
2308 bpp = GetDeviceCaps(hdc, BITSPIXEL);
2310 hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
2311 ok(hbm != 0, "CreateBitmap failed\n");
2313 hbm_old = SelectObject(hdc, hbm);
2314 if(depths[i] == bpp ||
2315 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
2317 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
2318 SelectObject(hdc, hbm_old);
2320 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
2323 memset(&bm, 0xAA, sizeof(bm));
2324 bytes = GetObject(hbm, sizeof(bm), &bm);
2325 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2326 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2327 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
2328 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
2329 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2330 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
2331 if(depths[i] == 15) {
2332 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
2334 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2336 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2344 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
2349 ret = GetObjectType(hbmp);
2350 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
2352 ret = GetObject(hbmp, 0, 0);
2353 ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
2355 memset(&bm, 0xDA, sizeof(bm));
2356 SetLastError(0xdeadbeef);
2357 ret = GetObject(hbmp, sizeof(bm), &bm);
2358 if (!ret) /* XP, only for curObj2 */ return;
2359 ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
2360 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2361 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2362 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2363 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2364 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2365 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2366 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2369 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2371 static void test_CreateBitmap(void)
2374 HDC screenDC = GetDC(0);
2375 HDC hdc = CreateCompatibleDC(screenDC);
2378 /* all of these are the stock monochrome bitmap */
2379 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2380 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2381 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2382 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2383 HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2384 HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2386 /* these 2 are not the stock monochrome bitmap */
2387 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2388 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2390 HBITMAP old1 = SelectObject(hdc, bm2);
2391 HBITMAP old2 = SelectObject(screenDC, bm3);
2392 SelectObject(hdc, old1);
2393 SelectObject(screenDC, old2);
2395 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2396 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2397 bm, bm1, bm4, bm5, curObj1, old1);
2398 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2400 ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
2401 ok(old2 == 0, "old2 %p\n", old2);
2403 test_mono_1x1_bmp(bm);
2404 test_mono_1x1_bmp(bm1);
2405 test_mono_1x1_bmp(bm2);
2406 test_mono_1x1_bmp(bm3);
2407 test_mono_1x1_bmp(bm4);
2408 test_mono_1x1_bmp(bm5);
2409 test_mono_1x1_bmp(old1);
2410 test_mono_1x1_bmp(curObj1);
2420 ReleaseDC(0, screenDC);
2422 /* show that Windows ignores the provided bm.bmWidthBytes */
2426 bmp.bmWidthBytes = 28;
2428 bmp.bmBitsPixel = 1;
2430 bm = CreateBitmapIndirect(&bmp);
2431 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2432 test_mono_1x1_bmp(bm);
2435 /* Test how the bmBitsPixel field is treated */
2436 for(i = 1; i <= 33; i++) {
2440 bmp.bmWidthBytes = 28;
2442 bmp.bmBitsPixel = i;
2444 SetLastError(0xdeadbeef);
2445 bm = CreateBitmapIndirect(&bmp);
2447 DWORD error = GetLastError();
2448 ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
2449 ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2453 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2454 GetObject(bm, sizeof(bmp), &bmp);
2461 } else if(i <= 16) {
2463 } else if(i <= 24) {
2465 } else if(i <= 32) {
2468 ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2469 i, bmp.bmBitsPixel, expect);
2474 static void test_bitmapinfoheadersize(void)
2481 memset(&bmi, 0, sizeof(BITMAPINFO));
2482 bmi.bmiHeader.biHeight = 100;
2483 bmi.bmiHeader.biWidth = 512;
2484 bmi.bmiHeader.biBitCount = 24;
2485 bmi.bmiHeader.biPlanes = 1;
2487 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2489 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2490 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2492 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2494 SetLastError(0xdeadbeef);
2495 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2496 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2499 bmi.bmiHeader.biSize++;
2501 SetLastError(0xdeadbeef);
2502 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2504 broken(!hdib), /* Win98, WinMe */
2505 "CreateDIBSection error %d\n", GetLastError());
2508 bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2510 SetLastError(0xdeadbeef);
2511 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2513 broken(!hdib), /* Win98, WinMe */
2514 "CreateDIBSection error %d\n", GetLastError());
2517 bmi.bmiHeader.biSize++;
2519 SetLastError(0xdeadbeef);
2520 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2522 broken(!hdib), /* Win98, WinMe */
2523 "CreateDIBSection error %d\n", GetLastError());
2526 bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2528 SetLastError(0xdeadbeef);
2529 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2530 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2533 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2535 SetLastError(0xdeadbeef);
2536 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2538 broken(!hdib), /* Win95 */
2539 "CreateDIBSection error %d\n", GetLastError());
2542 memset(&bci, 0, sizeof(BITMAPCOREINFO));
2543 bci.bmciHeader.bcHeight = 100;
2544 bci.bmciHeader.bcWidth = 512;
2545 bci.bmciHeader.bcBitCount = 24;
2546 bci.bmciHeader.bcPlanes = 1;
2548 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2550 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2551 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2553 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2555 SetLastError(0xdeadbeef);
2556 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2557 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2560 bci.bmciHeader.bcSize++;
2562 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2563 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2565 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2567 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2568 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2573 static void test_get16dibits(void)
2575 BYTE bits[4 * (16 / sizeof(BYTE))];
2577 HDC screen_dc = GetDC(NULL);
2580 int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2582 int overwritten_bytes = 0;
2584 memset(bits, 0, sizeof(bits));
2585 hbmp = CreateBitmap(2, 2, 1, 16, bits);
2586 ok(hbmp != NULL, "CreateBitmap failed\n");
2588 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2591 memset(info, '!', info_len);
2592 memset(info, 0, sizeof(info->bmiHeader));
2594 info->bmiHeader.biSize = sizeof(info->bmiHeader);
2595 info->bmiHeader.biWidth = 2;
2596 info->bmiHeader.biHeight = 2;
2597 info->bmiHeader.biPlanes = 1;
2598 info->bmiHeader.biCompression = BI_RGB;
2600 ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2601 ok(ret != 0, "GetDIBits failed got %d\n", ret);
2603 for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2605 overwritten_bytes++;
2606 ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2608 HeapFree(GetProcessHeap(), 0, info);
2610 ReleaseDC(NULL, screen_dc);
2613 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2614 DWORD dwRop, UINT32 expected, int line)
2616 *srcBuffer = 0xFEDCBA98;
2617 *dstBuffer = 0x89ABCDEF;
2618 Rectangle(hdcSrc, 0, 0, 1, 1); /* A null operation to ensure dibs are coerced to X11 */
2619 BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
2620 ok(expected == *dstBuffer,
2621 "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2622 dwRop, expected, *dstBuffer, line);
2625 static void test_BitBlt(void)
2627 HBITMAP bmpDst, bmpSrc;
2628 HBITMAP oldDst, oldSrc;
2629 HDC hdcScreen, hdcDst, hdcSrc;
2630 UINT32 *dstBuffer, *srcBuffer;
2631 HBRUSH hBrush, hOldBrush;
2632 BITMAPINFO bitmapInfo;
2634 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2635 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2636 bitmapInfo.bmiHeader.biWidth = 1;
2637 bitmapInfo.bmiHeader.biHeight = 1;
2638 bitmapInfo.bmiHeader.biPlanes = 1;
2639 bitmapInfo.bmiHeader.biBitCount = 32;
2640 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2641 bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2643 hdcScreen = CreateCompatibleDC(0);
2644 hdcDst = CreateCompatibleDC(hdcScreen);
2645 hdcSrc = CreateCompatibleDC(hdcDst);
2647 /* Setup the destination dib section */
2648 bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
2650 oldDst = SelectObject(hdcDst, bmpDst);
2652 hBrush = CreateSolidBrush(0x012345678);
2653 hOldBrush = SelectObject(hdcDst, hBrush);
2655 /* Setup the source dib section */
2656 bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
2658 oldSrc = SelectObject(hdcSrc, bmpSrc);
2660 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2661 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2662 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2663 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2664 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2665 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2666 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2667 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2668 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2669 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2670 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2671 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2672 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2673 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2674 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2677 SelectObject(hdcSrc, oldSrc);
2678 DeleteObject(bmpSrc);
2681 SelectObject(hdcDst, hOldBrush);
2682 DeleteObject(hBrush);
2683 SelectObject(hdcDst, oldDst);
2684 DeleteObject(bmpDst);
2688 DeleteDC(hdcScreen);
2691 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2692 DWORD dwRop, UINT32 expected, int line)
2694 *srcBuffer = 0xFEDCBA98;
2695 *dstBuffer = 0x89ABCDEF;
2696 StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
2697 ok(expected == *dstBuffer,
2698 "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2699 dwRop, expected, *dstBuffer, line);
2702 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, BITMAPINFO *dst_info, UINT32 *dstBuffer, UINT32 *srcBuffer,
2703 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2704 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2705 UINT32 *expected, int line)
2707 int dst_size = get_dib_image_size( dst_info );
2709 memset(dstBuffer, 0, dst_size);
2710 StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2711 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
2712 ok(memcmp(dstBuffer, expected, dst_size) == 0,
2713 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2714 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2715 expected[0], expected[1], expected[2], expected[3],
2716 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2717 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2718 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2721 static void test_StretchBlt(void)
2723 HBITMAP bmpDst, bmpSrc;
2724 HBITMAP oldDst, oldSrc;
2725 HDC hdcScreen, hdcDst, hdcSrc;
2726 UINT32 *dstBuffer, *srcBuffer;
2727 HBRUSH hBrush, hOldBrush;
2728 BITMAPINFO biDst, biSrc;
2729 UINT32 expected[256];
2732 memset(&biDst, 0, sizeof(BITMAPINFO));
2733 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2734 biDst.bmiHeader.biWidth = 16;
2735 biDst.bmiHeader.biHeight = -16;
2736 biDst.bmiHeader.biPlanes = 1;
2737 biDst.bmiHeader.biBitCount = 32;
2738 biDst.bmiHeader.biCompression = BI_RGB;
2739 memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
2741 hdcScreen = CreateCompatibleDC(0);
2742 hdcDst = CreateCompatibleDC(hdcScreen);
2743 hdcSrc = CreateCompatibleDC(hdcDst);
2746 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2748 oldDst = SelectObject(hdcDst, bmpDst);
2750 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2752 oldSrc = SelectObject(hdcSrc, bmpSrc);
2754 hBrush = CreateSolidBrush(0x012345678);
2755 hOldBrush = SelectObject(hdcDst, hBrush);
2757 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2758 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2759 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2760 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2761 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2762 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2763 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2764 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2765 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2766 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2767 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2768 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2769 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2770 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2771 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2773 SelectObject(hdcDst, hOldBrush);
2774 DeleteObject(hBrush);
2776 /* Top-down to top-down tests */
2777 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2778 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2780 memset( expected, 0, get_dib_image_size( &biDst ) );
2781 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2782 expected[16] = 0xFEDCBA98, expected[17] = 0x76543210;
2783 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2784 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2786 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2787 expected[16] = 0x00000000, expected[17] = 0x00000000;
2788 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2789 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
2791 expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
2792 expected[16] = 0xCAFED00D, expected[17] = 0xCAFED00D;
2793 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2794 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
2796 /* This is an example of the dst width (height) == 1 exception, explored below */
2797 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2798 expected[16] = 0x00000000, expected[17] = 0x00000000;
2799 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2800 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
2802 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2803 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
2804 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2805 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2807 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2808 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
2809 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2810 1, 1, -2, -2, 0, 0, 2, 2, expected, __LINE__);
2812 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2813 expected[16] = 0x00000000, expected[17] = 0x00000000;
2814 todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2815 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
2817 expected[0] = 0x00000000, expected[1] = 0x00000000;
2818 expected[16] = 0x00000000, expected[17] = 0xCAFED00D, expected[18] = 0xFEEDFACE;
2819 expected[32] = 0x00000000, expected[33] = 0xFEDCBA98, expected[34] = 0x76543210;
2821 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2822 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2824 /* when dst width is 1 merge src width - 1 pixels */
2825 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
2826 srcBuffer[0] = 0x0000ff00, srcBuffer[1] = 0x0000f0f0, srcBuffer[2] = 0x0000cccc, srcBuffer[3] = 0x0000aaaa;
2827 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2829 memset( expected, 0, get_dib_image_size( &biDst ) );
2830 expected[0] = srcBuffer[0];
2831 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2832 0, 0, 1, 1, 0, 0, 2, 1, expected, __LINE__);
2834 expected[0] = srcBuffer[0] & srcBuffer[1];
2835 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2836 0, 0, 1, 1, 0, 0, 3, 1, expected, __LINE__);
2838 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
2839 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2840 0, 0, 1, 1, 0, 0, 4, 1, expected, __LINE__);
2842 /* this doesn't happen if the src width is -ve */
2843 expected[0] = srcBuffer[1] & srcBuffer[2];
2844 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2845 0, 0, 1, 1, 2, 0, -2, 1, expected, __LINE__);
2847 /* when dst width > 1 behaviour reverts to what one would expect */
2848 expected[0] = srcBuffer[0] & srcBuffer[1], expected[1] = srcBuffer[2] & srcBuffer[3];
2849 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2850 0, 0, 2, 1, 0, 0, 4, 1, expected, __LINE__);
2852 /* similarly in the vertical direction */
2853 memset( expected, 0, get_dib_image_size( &biDst ) );
2854 expected[0] = srcBuffer[0];
2855 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2856 0, 0, 1, 1, 0, 0, 1, 2, expected, __LINE__);
2858 /* check that it's the dst size in device units that needs to be 1 */
2859 SetMapMode( hdcDst, MM_ISOTROPIC );
2860 SetWindowExtEx( hdcDst, 200, 200, NULL );
2861 SetViewportExtEx( hdcDst, 100, 100, NULL );
2863 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
2864 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2865 0, 0, 2, 2, 0, 0, 4, 1, expected, __LINE__);
2866 SetMapMode( hdcDst, MM_TEXT );
2868 SelectObject(hdcDst, oldDst);
2869 DeleteObject(bmpDst);
2871 /* Top-down to bottom-up tests */
2872 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
2873 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2874 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2876 biDst.bmiHeader.biHeight = 16;
2877 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2879 oldDst = SelectObject(hdcDst, bmpDst);
2881 memset( expected, 0, get_dib_image_size( &biDst ) );
2883 expected[224] = 0xFEDCBA98, expected[225] = 0x76543210;
2884 expected[240] = 0xCAFED00D, expected[241] = 0xFEEDFACE;
2885 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2886 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2888 expected[224] = 0xFEEDFACE, expected[225] = 0xCAFED00D;
2889 expected[240] = 0x76543210, expected[241] = 0xFEDCBA98;
2890 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2891 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2893 SelectObject(hdcSrc, oldSrc);
2894 DeleteObject(bmpSrc);
2896 /* Bottom-up to bottom-up tests */
2897 biSrc.bmiHeader.biHeight = 16;
2898 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2900 srcBuffer[224] = 0xCAFED00D, srcBuffer[225] = 0xFEEDFACE;
2901 srcBuffer[240] = 0xFEDCBA98, srcBuffer[241] = 0x76543210;
2902 oldSrc = SelectObject(hdcSrc, bmpSrc);
2904 memset( expected, 0, get_dib_image_size( &biDst ) );
2906 expected[224] = 0xCAFED00D, expected[225] = 0xFEEDFACE;
2907 expected[240] = 0xFEDCBA98, expected[241] = 0x76543210;
2908 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2909 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2911 expected[224] = 0x76543210, expected[225] = 0xFEDCBA98;
2912 expected[240] = 0xFEEDFACE, expected[241] = 0xCAFED00D;
2913 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2914 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2916 SelectObject(hdcDst, oldDst);
2917 DeleteObject(bmpDst);
2919 /* Bottom-up to top-down tests */
2920 biDst.bmiHeader.biHeight = -16;
2921 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2923 oldDst = SelectObject(hdcDst, bmpDst);
2925 memset( expected, 0, get_dib_image_size( &biDst ) );
2926 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2927 expected[16] = 0xCAFED00D, expected[17] = 0xFEEDFACE;
2928 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2929 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2931 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2932 expected[16] = 0x76543210, expected[17] = 0xFEDCBA98;
2933 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2934 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2936 SelectObject(hdcSrc, oldSrc);
2937 DeleteObject(bmpSrc);
2939 biSrc.bmiHeader.biHeight = -2;
2940 biSrc.bmiHeader.biBitCount = 24;
2941 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
2942 oldSrc = SelectObject(hdcSrc, bmpSrc);
2944 memset( expected, 0, get_dib_image_size( &biDst ) );
2945 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2946 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2947 memcpy(dstBuffer, expected, 4 * sizeof(*dstBuffer));
2948 StretchBlt(hdcSrc, 0, 0, 4, 1, hdcDst, 0, 0, 4, 1, SRCCOPY );
2949 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
2950 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
2951 expected[0] = 0x00EDFACE, expected[1] = 0x00FED00D;
2952 expected[2] = 0x00543210, expected[3] = 0x00DCBA98;
2953 ok(!memcmp(dstBuffer, expected, 16),
2954 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
2955 expected[0], expected[1], expected[2], expected[3],
2956 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
2958 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2959 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2960 memcpy(srcBuffer, expected, 4 * sizeof(*dstBuffer));
2961 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
2962 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
2963 expected[0] = 0x00EDFACE, expected[1] = 0x00D00DFE;
2964 expected[2] = 0x0010CAFE, expected[3] = 0x00765432;
2965 ok(!memcmp(dstBuffer, expected, 16),
2966 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
2967 expected[0], expected[1], expected[2], expected[3],
2968 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
2970 SelectObject(hdcSrc, oldSrc);
2971 DeleteObject(bmpSrc);
2973 biSrc.bmiHeader.biBitCount = 1;
2974 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
2975 oldSrc = SelectObject(hdcSrc, bmpSrc);
2976 *((DWORD *)colors + 0) = 0x123456;
2977 *((DWORD *)colors + 1) = 0x335577;
2978 SetDIBColorTable( hdcSrc, 0, 2, colors );
2979 srcBuffer[0] = 0x55555555;
2980 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
2981 SetTextColor( hdcDst, 0 );
2982 SetBkColor( hdcDst, 0 );
2983 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
2984 expected[0] = expected[2] = 0x00123456;
2985 expected[1] = expected[3] = 0x00335577;
2986 ok(!memcmp(dstBuffer, expected, 16),
2987 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
2988 expected[0], expected[1], expected[2], expected[3],
2989 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
2991 SelectObject(hdcSrc, oldSrc);
2992 DeleteObject(bmpSrc);
2994 bmpSrc = CreateBitmap( 16, 16, 1, 1, 0 );
2995 oldSrc = SelectObject(hdcSrc, bmpSrc);
2996 SetPixel( hdcSrc, 0, 0, 0 );
2997 SetPixel( hdcSrc, 1, 0, 0xffffff );
2998 SetPixel( hdcSrc, 2, 0, 0xffffff );
2999 SetPixel( hdcSrc, 3, 0, 0 );
3000 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
3001 SetTextColor( hdcDst, RGB(0x22,0x44,0x66) );
3002 SetBkColor( hdcDst, RGB(0x65,0x43,0x21) );
3003 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3004 expected[0] = expected[3] = 0x00224466;
3005 expected[1] = expected[2] = 0x00654321;
3006 ok(!memcmp(dstBuffer, expected, 16),
3007 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3008 expected[0], expected[1], expected[2], expected[3],
3009 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3011 SelectObject(hdcSrc, oldSrc);
3012 DeleteObject(bmpSrc);
3016 SelectObject(hdcDst, oldDst);
3017 DeleteObject(bmpDst);
3020 DeleteDC(hdcScreen);
3023 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3024 DWORD dwRop, UINT32 expected, int line)
3026 const UINT32 buffer[2] = { 0xFEDCBA98, 0 };
3027 BITMAPINFO bitmapInfo;
3029 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3030 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3031 bitmapInfo.bmiHeader.biWidth = 2;
3032 bitmapInfo.bmiHeader.biHeight = 1;
3033 bitmapInfo.bmiHeader.biPlanes = 1;
3034 bitmapInfo.bmiHeader.biBitCount = 32;
3035 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3036 bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer);
3038 *dstBuffer = 0x89ABCDEF;
3040 StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop);
3041 ok(expected == *dstBuffer,
3042 "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
3043 dwRop, expected, *dstBuffer, line);
3046 static void check_StretchDIBits_stretch(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3047 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
3048 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
3049 UINT32 expected[4], int line)
3051 BITMAPINFO bitmapInfo;
3053 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3054 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3055 bitmapInfo.bmiHeader.biWidth = 2;
3056 bitmapInfo.bmiHeader.biHeight = -2;
3057 bitmapInfo.bmiHeader.biPlanes = 1;
3058 bitmapInfo.bmiHeader.biBitCount = 32;
3059 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3061 memset(dstBuffer, 0, 16);
3062 StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
3063 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3064 srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
3065 ok(memcmp(dstBuffer, expected, 16) == 0,
3066 "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
3067 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
3068 expected[0], expected[1], expected[2], expected[3],
3069 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
3070 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3071 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
3074 static void test_StretchDIBits(void)
3078 HDC hdcScreen, hdcDst;
3079 UINT32 *dstBuffer, srcBuffer[4];
3080 HBRUSH hBrush, hOldBrush;
3084 memset(&biDst, 0, sizeof(BITMAPINFO));
3085 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3086 biDst.bmiHeader.biWidth = 2;
3087 biDst.bmiHeader.biHeight = -2;
3088 biDst.bmiHeader.biPlanes = 1;
3089 biDst.bmiHeader.biBitCount = 32;
3090 biDst.bmiHeader.biCompression = BI_RGB;
3092 hdcScreen = CreateCompatibleDC(0);
3093 hdcDst = CreateCompatibleDC(hdcScreen);
3096 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3098 oldDst = SelectObject(hdcDst, bmpDst);
3100 hBrush = CreateSolidBrush(0x012345678);
3101 hOldBrush = SelectObject(hdcDst, hBrush);
3103 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3104 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3105 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3106 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3107 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3108 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3109 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3110 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3111 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3112 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3113 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3114 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3115 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3116 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3117 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3119 SelectObject(hdcDst, hOldBrush);
3120 DeleteObject(hBrush);
3122 /* Top-down destination tests */
3123 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3124 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
3126 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
3127 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
3128 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3129 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3131 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3132 expected[2] = 0x00000000, expected[3] = 0x00000000;
3133 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3134 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
3136 expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
3137 expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
3138 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3139 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
3141 expected[0] = 0x42441000, expected[1] = 0x00000000;
3142 expected[2] = 0x00000000, expected[3] = 0x00000000;
3143 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3144 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
3146 expected[0] = 0x00000000, expected[1] = 0x00000000;
3147 expected[2] = 0x00000000, expected[3] = 0x00000000;
3148 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3149 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3151 expected[0] = 0x00000000, expected[1] = 0x00000000;
3152 expected[2] = 0x00000000, expected[3] = 0x00000000;
3153 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3154 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3156 expected[0] = 0x00000000, expected[1] = 0x00000000;
3157 expected[2] = 0x00000000, expected[3] = 0x00000000;
3158 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3159 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
3161 expected[0] = 0x00000000, expected[1] = 0x00000000;
3162 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
3163 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3164 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3166 SelectObject(hdcDst, oldDst);
3167 DeleteObject(bmpDst);
3169 /* Bottom up destination tests */
3170 biDst.bmiHeader.biHeight = 2;
3171 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3173 oldDst = SelectObject(hdcDst, bmpDst);
3175 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3176 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
3177 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3178 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3181 SelectObject(hdcDst, oldDst);
3182 DeleteObject(bmpDst);
3185 DeleteDC(hdcScreen);
3188 static void test_GdiAlphaBlend(void)
3200 BLENDFUNCTION blend;
3202 if (!pGdiAlphaBlend)
3204 win_skip("GdiAlphaBlend() is not implemented\n");
3208 hdcNull = GetDC(NULL);
3209 hdcDst = CreateCompatibleDC(hdcNull);
3210 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
3211 hdcSrc = CreateCompatibleDC(hdcNull);
3213 bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3214 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3215 bmi->bmiHeader.biHeight = 20;
3216 bmi->bmiHeader.biWidth = 20;
3217 bmi->bmiHeader.biBitCount = 32;
3218 bmi->bmiHeader.biPlanes = 1;
3219 bmi->bmiHeader.biCompression = BI_RGB;
3220 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3221 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3223 oldDst = SelectObject(hdcDst, bmpDst);
3224 oldSrc = SelectObject(hdcSrc, bmpSrc);
3226 blend.BlendOp = AC_SRC_OVER;
3227 blend.BlendFlags = 0;
3228 blend.SourceConstantAlpha = 128;
3229 blend.AlphaFormat = 0;
3231 SetLastError(0xdeadbeef);
3232 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3233 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3235 SetLastError(0xdeadbeef);
3236 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3237 ok( !ret, "GdiAlphaBlend succeeded\n" );
3238 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3240 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3241 ok( !ret, "GdiAlphaBlend succeeded\n" );
3242 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend);
3243 ok( !ret, "GdiAlphaBlend succeeded\n" );
3244 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3245 ok( !ret, "GdiAlphaBlend succeeded\n" );
3246 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3247 ok( !ret, "GdiAlphaBlend succeeded\n" );
3249 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
3250 SetLastError(0xdeadbeef);
3251 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3252 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3253 SetLastError(0xdeadbeef);
3254 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3255 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3256 SetMapMode(hdcSrc, MM_ANISOTROPIC);
3257 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
3258 SetLastError(0xdeadbeef);
3259 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend);
3260 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3261 SetLastError(0xdeadbeef);
3262 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend);
3263 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3265 SetLastError(0xdeadbeef);
3266 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend);
3267 ok( !ret, "GdiAlphaBlend succeeded\n" );
3268 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3270 /* overlapping source and dest not allowed */
3272 SetLastError(0xdeadbeef);
3273 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 19, 19, 20, 20, blend);
3274 ok( !ret, "GdiAlphaBlend succeeded\n" );
3275 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3277 SetLastError(0xdeadbeef);
3278 ret = pGdiAlphaBlend(hdcDst, 20, 20, 20, 20, hdcDst, 1, 1, 20, 20, blend);
3279 ok( !ret, "GdiAlphaBlend succeeded\n" );
3280 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3282 SetLastError(0xdeadbeef);
3283 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 20, 10, 20, 20, blend);
3284 ok( ret, "GdiAlphaBlend succeeded\n" );
3285 SetLastError(0xdeadbeef);
3286 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 10, 20, 20, 20, blend);
3287 ok( ret, "GdiAlphaBlend succeeded\n" );
3289 /* AC_SRC_ALPHA requires 32-bpp BI_RGB format */
3291 blend.AlphaFormat = AC_SRC_ALPHA;
3292 SetLastError(0xdeadbeef);
3293 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3294 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3296 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3297 ((DWORD *)bmi->bmiColors)[0] = 0xff0000;
3298 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3299 ((DWORD *)bmi->bmiColors)[2] = 0x0000ff;
3300 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3301 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3302 oldSrc = SelectObject(hdcSrc, bmpSrc);
3303 DeleteObject( oldSrc );
3305 SetLastError(0xdeadbeef);
3306 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3307 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3309 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3310 ((DWORD *)bmi->bmiColors)[0] = 0x0000ff;
3311 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3312 ((DWORD *)bmi->bmiColors)[2] = 0xff0000;
3313 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3314 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3315 oldSrc = SelectObject(hdcSrc, bmpSrc);
3316 DeleteObject( oldSrc );
3318 SetLastError(0xdeadbeef);
3319 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3320 ok( !ret, "GdiAlphaBlend succeeded\n" );
3321 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3323 bmi->bmiHeader.biBitCount = 24;
3324 bmi->bmiHeader.biCompression = BI_RGB;
3325 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3326 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3327 oldSrc = SelectObject(hdcSrc, bmpSrc);
3328 DeleteObject( oldSrc );
3330 SetLastError(0xdeadbeef);
3331 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3332 ok( !ret, "GdiAlphaBlend succeeded\n" );
3333 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3335 bmi->bmiHeader.biBitCount = 1;
3336 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3337 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3338 oldSrc = SelectObject(hdcSrc, bmpSrc);
3339 DeleteObject( oldSrc );
3341 SetLastError(0xdeadbeef);
3342 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3343 ok( !ret, "GdiAlphaBlend succeeded\n" );
3344 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3346 bmpSrc = CreateBitmap( 100, 100, 1, 1, NULL );
3347 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3348 oldSrc = SelectObject(hdcSrc, bmpSrc);
3349 DeleteObject( oldSrc );
3351 SetLastError(0xdeadbeef);
3352 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3353 ok( !ret, "GdiAlphaBlend succeeded\n" );
3354 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3356 SelectObject(hdcDst, oldDst);
3357 SelectObject(hdcSrc, oldSrc);
3358 DeleteObject(bmpSrc);
3359 DeleteObject(bmpDst);
3363 ReleaseDC(NULL, hdcNull);
3367 static void test_clipping(void)
3375 HDC hdcDst = CreateCompatibleDC( NULL );
3376 HDC hdcSrc = CreateCompatibleDC( NULL );
3378 BITMAPINFO bmpinfo={{0}};
3379 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3380 bmpinfo.bmiHeader.biWidth = 100;
3381 bmpinfo.bmiHeader.biHeight = 100;
3382 bmpinfo.bmiHeader.biPlanes = 1;
3383 bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3384 bmpinfo.bmiHeader.biCompression = BI_RGB;
3386 bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3387 ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3388 SelectObject( hdcDst, bmpDst );
3390 bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3391 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3392 SelectObject( hdcSrc, bmpSrc );
3394 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3395 ok(result, "BitBlt failed\n");
3397 hRgn = CreateRectRgn( 0,0,0,0 );
3398 SelectClipRgn( hdcDst, hRgn );
3400 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3401 ok(result, "BitBlt failed\n");
3403 DeleteObject( bmpDst );
3404 DeleteObject( bmpSrc );
3405 DeleteObject( hRgn );
3410 static void test_32bit_bitmap_blt(void)
3413 HBITMAP bmpSrc, bmpDst;
3414 HBITMAP oldSrc, oldDst;
3415 HDC hdcSrc, hdcDst, hdcScreen;
3417 DWORD colorSrc = 0x11223344;
3419 memset(&biDst, 0, sizeof(BITMAPINFO));
3420 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3421 biDst.bmiHeader.biWidth = 2;
3422 biDst.bmiHeader.biHeight = -2;
3423 biDst.bmiHeader.biPlanes = 1;
3424 biDst.bmiHeader.biBitCount = 32;
3425 biDst.bmiHeader.biCompression = BI_RGB;
3427 hdcScreen = CreateCompatibleDC(0);
3428 if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3430 DeleteDC(hdcScreen);
3431 trace("Skipping 32-bit DDB test\n");
3435 hdcSrc = CreateCompatibleDC(hdcScreen);
3436 bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3437 oldSrc = SelectObject(hdcSrc, bmpSrc);
3439 hdcDst = CreateCompatibleDC(hdcScreen);
3440 bmpDst = CreateDIBSection(hdcDst, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3441 oldDst = SelectObject(hdcDst, bmpDst);
3443 StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3444 ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3447 SelectObject(hdcDst, oldDst);
3448 DeleteObject(bmpDst);
3451 SelectObject(hdcSrc, oldSrc);
3452 DeleteObject(bmpSrc);
3455 DeleteDC(hdcScreen);
3459 * Used by test_GetDIBits_top_down to create the bitmap to test against.
3461 static void setup_picture(char *picture, int bpp)
3469 /*Set the first byte in each pixel to the index of that pixel.*/
3470 for (i = 0; i < 4; i++)
3471 picture[i * (bpp / 8)] = i;
3476 /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
3483 static void test_GetDIBits_top_down(int bpp)
3486 HBITMAP bmptb, bmpbt;
3492 memset( &bi, 0, sizeof(bi) );
3493 bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
3494 bi.bmiHeader.biWidth=2;
3495 bi.bmiHeader.biHeight=2;
3496 bi.bmiHeader.biPlanes=1;
3497 bi.bmiHeader.biBitCount=bpp;
3498 bi.bmiHeader.biCompression=BI_RGB;
3500 /*Get the device context for the screen.*/
3502 ok(hdc != NULL, "Could not get a handle to a device context.\n");
3504 /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
3505 bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3506 ok(bmpbt != NULL, "Could not create a DIB section.\n");
3507 /*Now that we have a pointer to the pixels, we write to them.*/
3508 setup_picture((char*)picture, bpp);
3509 /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
3510 bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
3511 bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3512 ok(bmptb != NULL, "Could not create a DIB section.\n");
3513 /*Write to this top to bottom bitmap.*/
3514 setup_picture((char*)picture, bpp);
3516 bi.bmiHeader.biWidth = 1;
3518 bi.bmiHeader.biHeight = 2;
3519 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3520 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3521 /*Check the first byte of the pixel.*/
3522 ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3523 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3524 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3525 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3526 /*Check second scanline.*/
3527 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3528 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3529 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3530 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3531 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3532 ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3533 /*Check both scanlines.*/
3534 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3535 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3536 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3537 ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3538 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3539 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3540 ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3541 ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3543 /*Make destination bitmap top-down.*/
3544 bi.bmiHeader.biHeight = -2;
3545 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3546 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3547 ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3548 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3549 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3550 ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3551 /*Check second scanline.*/
3552 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3553 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3554 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3555 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3556 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3557 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3558 /*Check both scanlines.*/
3559 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3560 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3561 ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3562 ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3563 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3564 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3565 ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3566 ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3568 DeleteObject(bmpbt);
3569 DeleteObject(bmptb);
3572 static void test_GetSetDIBits_rtl(void)
3575 HBITMAP bitmap, orig_bitmap;
3578 DWORD bits_1[8 * 8], bits_2[8 * 8];
3582 win_skip("Don't have SetLayout\n");
3586 hdc = GetDC( NULL );
3587 hdc_mem = CreateCompatibleDC( hdc );
3588 pSetLayout( hdc_mem, LAYOUT_LTR );
3590 bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
3591 orig_bitmap = SelectObject( hdc_mem, bitmap );
3592 SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
3593 SelectObject( hdc_mem, orig_bitmap );
3595 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3596 info.bmiHeader.biWidth = 8;
3597 info.bmiHeader.biHeight = 8;
3598 info.bmiHeader.biPlanes = 1;
3599 info.bmiHeader.biBitCount = 32;
3600 info.bmiHeader.biCompression = BI_RGB;
3602 /* First show that GetDIBits ignores the layout mode. */
3604 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3605 ok(ret == 8, "got %d\n", ret);
3606 ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
3608 pSetLayout( hdc_mem, LAYOUT_RTL );
3610 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3611 ok(ret == 8, "got %d\n", ret);
3613 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3615 /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
3616 followed by a GetDIBits and show that the bits remain unchanged. */
3618 pSetLayout( hdc_mem, LAYOUT_LTR );
3620 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3621 ok(ret == 8, "got %d\n", ret);
3622 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3623 ok(ret == 8, "got %d\n", ret);
3624 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3626 pSetLayout( hdc_mem, LAYOUT_RTL );
3628 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3629 ok(ret == 8, "got %d\n", ret);
3630 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3631 ok(ret == 8, "got %d\n", ret);
3632 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3634 DeleteObject( bitmap );
3635 DeleteDC( hdc_mem );
3636 ReleaseDC( NULL, hdc );
3639 static void test_GetDIBits_scanlines(void)
3643 HDC hdc = GetDC( NULL );
3645 DWORD data[128], inverted_bits[64];
3648 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
3650 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3651 info->bmiHeader.biWidth = 8;
3652 info->bmiHeader.biHeight = 8;
3653 info->bmiHeader.biPlanes = 1;
3654 info->bmiHeader.biBitCount = 32;
3655 info->bmiHeader.biCompression = BI_RGB;
3657 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3659 for (i = 0; i < 64; i++)
3662 inverted_bits[56 - (i & ~7) + (i & 7)] = i;
3667 memset( data, 0xaa, sizeof(data) );
3669 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3670 ok( ret == 8, "got %d\n", ret );
3671 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3672 memset( data, 0xaa, sizeof(data) );
3674 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3675 ok( ret == 5, "got %d\n", ret );
3676 ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
3677 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3678 memset( data, 0xaa, sizeof(data) );
3680 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3681 ok( ret == 7, "got %d\n", ret );
3682 ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
3683 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3684 memset( data, 0xaa, sizeof(data) );
3686 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3687 ok( ret == 1, "got %d\n", ret );
3688 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3689 memset( data, 0xaa, sizeof(data) );
3691 info->bmiHeader.biHeight = 16;
3692 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3693 ok( ret == 5, "got %d\n", ret );
3694 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3695 ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
3696 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3697 memset( data, 0xaa, sizeof(data) );
3699 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3700 ok( ret == 6, "got %d\n", ret );
3701 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3702 ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
3703 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3704 memset( data, 0xaa, sizeof(data) );
3706 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3707 ok( ret == 0, "got %d\n", ret );
3708 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3709 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3710 memset( data, 0xaa, sizeof(data) );
3712 info->bmiHeader.biHeight = 5;
3713 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3714 ok( ret == 2, "got %d\n", ret );
3715 ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
3716 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3717 memset( data, 0xaa, sizeof(data) );
3721 info->bmiHeader.biHeight = -8;
3722 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3723 ok( ret == 8, "got %d\n", ret );
3724 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3725 memset( data, 0xaa, sizeof(data) );
3727 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3728 ok( ret == 5, "got %d\n", ret );
3729 ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
3730 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3731 memset( data, 0xaa, sizeof(data) );
3733 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3734 ok( ret == 7, "got %d\n", ret );
3735 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3736 for (i = 56; 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, 4, 12, data, info, DIB_RGB_COLORS );
3740 ok( ret == 4, "got %d\n", ret );
3741 ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
3742 for (i = 32; 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, 3, 12, data, info, DIB_RGB_COLORS );
3746 ok( ret == 5, "got %d\n", ret );
3747 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3748 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3749 memset( data, 0xaa, sizeof(data) );
3751 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3752 ok( ret == 5, "got %d\n", ret );
3753 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3754 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3755 memset( data, 0xaa, sizeof(data) );
3757 info->bmiHeader.biHeight = -16;
3758 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3759 ok( ret == 8, "got %d\n", ret );
3760 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3761 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3762 memset( data, 0xaa, sizeof(data) );
3764 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3765 ok( ret == 5, "got %d\n", ret );
3766 ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
3767 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3768 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3769 memset( data, 0xaa, sizeof(data) );
3771 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3772 ok( ret == 8, "got %d\n", ret );
3773 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3774 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3775 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3776 memset( data, 0xaa, sizeof(data) );
3778 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3779 ok( ret == 8, "got %d\n", ret );
3780 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3781 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3782 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3783 memset( data, 0xaa, sizeof(data) );
3785 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3786 ok( ret == 7, "got %d\n", ret );
3787 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3788 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3789 memset( data, 0xaa, sizeof(data) );
3791 ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
3792 ok( ret == 1, "got %d\n", ret );
3793 for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3794 memset( data, 0xaa, sizeof(data) );
3796 info->bmiHeader.biHeight = -5;
3797 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3798 ok( ret == 2, "got %d\n", ret );
3799 ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
3800 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3801 memset( data, 0xaa, sizeof(data) );
3803 DeleteObject( dib );
3805 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3806 info->bmiHeader.biWidth = 8;
3807 info->bmiHeader.biHeight = -8;
3808 info->bmiHeader.biPlanes = 1;
3809 info->bmiHeader.biBitCount = 32;
3810 info->bmiHeader.biCompression = BI_RGB;
3812 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3814 for (i = 0; i < 64; i++) dib_bits[i] = i;
3818 info->bmiHeader.biHeight = -8;
3819 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3820 ok( ret == 8, "got %d\n", ret );
3821 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3822 memset( data, 0xaa, sizeof(data) );
3824 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3825 ok( ret == 5, "got %d\n", ret );
3826 ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
3827 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3828 memset( data, 0xaa, sizeof(data) );
3830 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3831 ok( ret == 7, "got %d\n", ret );
3832 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3833 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3834 memset( data, 0xaa, sizeof(data) );
3836 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3837 ok( ret == 4, "got %d\n", ret );
3838 ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
3839 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3840 memset( data, 0xaa, sizeof(data) );
3842 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3843 ok( ret == 5, "got %d\n", ret );
3844 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3845 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3846 memset( data, 0xaa, sizeof(data) );
3848 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3849 ok( ret == 5, "got %d\n", ret );
3850 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3851 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3852 memset( data, 0xaa, sizeof(data) );
3854 info->bmiHeader.biHeight = -16;
3855 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3856 ok( ret == 8, "got %d\n", ret );
3857 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3858 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3859 memset( data, 0xaa, sizeof(data) );
3861 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3862 ok( ret == 5, "got %d\n", ret );
3863 ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
3864 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3865 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3866 memset( data, 0xaa, sizeof(data) );
3868 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3869 ok( ret == 8, "got %d\n", ret );
3870 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3871 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3872 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3873 memset( data, 0xaa, sizeof(data) );
3875 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3876 ok( ret == 8, "got %d\n", ret );
3877 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3878 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3879 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3880 memset( data, 0xaa, sizeof(data) );
3882 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3883 ok( ret == 7, "got %d\n", ret );
3884 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3885 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3886 memset( data, 0xaa, sizeof(data) );
3888 info->bmiHeader.biHeight = -5;
3889 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3890 ok( ret == 2, "got %d\n", ret );
3891 ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
3892 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3893 memset( data, 0xaa, sizeof(data) );
3898 info->bmiHeader.biHeight = 8;
3900 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3901 ok( ret == 8, "got %d\n", ret );
3902 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3903 memset( data, 0xaa, sizeof(data) );
3905 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3906 ok( ret == 5, "got %d\n", ret );
3907 ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
3908 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3909 memset( data, 0xaa, sizeof(data) );
3911 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3912 ok( ret == 7, "got %d\n", ret );
3913 ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
3914 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3915 memset( data, 0xaa, sizeof(data) );
3917 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3918 ok( ret == 1, "got %d\n", ret );
3919 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3920 memset( data, 0xaa, sizeof(data) );
3922 info->bmiHeader.biHeight = 16;
3923 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3924 ok( ret == 5, "got %d\n", ret );
3925 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3926 ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
3927 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3928 memset( data, 0xaa, sizeof(data) );
3930 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3931 ok( ret == 6, "got %d\n", ret );
3932 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3933 ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
3934 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3935 memset( data, 0xaa, sizeof(data) );
3937 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3938 ok( ret == 0, "got %d\n", ret );
3939 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3940 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3941 memset( data, 0xaa, sizeof(data) );
3943 info->bmiHeader.biHeight = 5;
3944 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3945 ok( ret == 2, "got %d\n", ret );
3946 ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
3947 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3948 memset( data, 0xaa, sizeof(data) );
3950 DeleteObject( dib );
3952 ReleaseDC( NULL, hdc );
3953 HeapFree( GetProcessHeap(), 0, info );
3957 static void test_SetDIBits(void)
3961 HDC hdc = GetDC( NULL );
3962 DWORD data[128], inverted_data[128];
3966 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
3968 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3969 info->bmiHeader.biWidth = 8;
3970 info->bmiHeader.biHeight = 8;
3971 info->bmiHeader.biPlanes = 1;
3972 info->bmiHeader.biBitCount = 32;
3973 info->bmiHeader.biCompression = BI_RGB;
3975 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3976 memset( dib_bits, 0xaa, 64 * 4 );
3978 for (i = 0; i < 128; i++)
3981 inverted_data[120 - (i & ~7) + (i & 7)] = i;
3986 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3987 ok( ret == 8, "got %d\n", ret );
3988 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
3989 memset( dib_bits, 0xaa, 64 * 4 );
3991 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3992 ok( ret == 5, "got %d\n", ret );
3993 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3994 ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
3995 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3996 memset( dib_bits, 0xaa, 64 * 4 );
3998 /* top of dst is aligned with startscans down for the top of the src.
3999 Then starting from the bottom of src, lines rows are copied across. */
4001 info->bmiHeader.biHeight = 16;
4002 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4003 ok( ret == 12, "got %d\n", ret );
4004 ok( !memcmp( dib_bits, data + 56, 40 * 4 ), "bits differ\n");
4005 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4006 memset( dib_bits, 0xaa, 64 * 4 );
4008 info->bmiHeader.biHeight = 5;
4009 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4010 ok( ret == 2, "got %d\n", ret );
4011 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4012 ok( !memcmp( dib_bits + 32, data, 16 * 4 ), "bits differ\n");
4013 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4014 memset( dib_bits, 0xaa, 64 * 4 );
4017 info->bmiHeader.biHeight = -8;
4018 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4019 ok( ret == 8, "got %d\n", ret );
4020 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4021 memset( dib_bits, 0xaa, 64 * 4 );
4023 /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
4024 we copy lines rows from the top of the src */
4026 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4027 ok( ret == 5, "got %d\n", ret );
4028 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4029 ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
4030 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4031 memset( dib_bits, 0xaa, 64 * 4 );
4033 info->bmiHeader.biHeight = -16;
4034 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4035 ok( ret == 12, "got %d\n", ret );
4036 ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
4037 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4038 memset( dib_bits, 0xaa, 64 * 4 );
4040 ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4041 ok( ret == 12, "got %d\n", ret );
4042 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4043 memset( dib_bits, 0xaa, 64 * 4 );
4045 ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4046 ok( ret == 12, "got %d\n", ret );
4047 ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
4048 memset( dib_bits, 0xaa, 64 * 4 );
4050 info->bmiHeader.biHeight = -5;
4051 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4052 ok( ret == 2, "got %d\n", ret );
4053 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4054 ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
4055 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4056 memset( dib_bits, 0xaa, 64 * 4 );
4058 DeleteObject( dib );
4060 info->bmiHeader.biHeight = -8;
4062 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4063 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4067 /* like the t-d -> b-u case. */
4069 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4070 ok( ret == 8, "got %d\n", ret );
4071 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4072 memset( dib_bits, 0xaa, 64 * 4 );
4074 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4075 ok( ret == 5, "got %d\n", ret );
4076 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4077 ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
4078 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4079 memset( dib_bits, 0xaa, 64 * 4 );
4081 info->bmiHeader.biHeight = -16;
4082 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4083 ok( ret == 12, "got %d\n", ret );
4084 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4085 ok( !memcmp( dib_bits + 24, data, 40 * 4 ), "bits differ\n");
4086 memset( dib_bits, 0xaa, 64 * 4 );
4088 info->bmiHeader.biHeight = -5;
4089 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4090 ok( ret == 2, "got %d\n", ret );
4091 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4092 ok( !memcmp( dib_bits + 16, data, 16 * 4 ), "bits differ\n");
4093 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4094 memset( dib_bits, 0xaa, 64 * 4 );
4097 /* like the b-u -> b-u case */
4099 info->bmiHeader.biHeight = 8;
4100 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4101 ok( ret == 8, "got %d\n", ret );
4102 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4103 memset( dib_bits, 0xaa, 64 * 4 );
4105 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4106 ok( ret == 5, "got %d\n", ret );
4107 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4108 ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
4109 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4110 memset( dib_bits, 0xaa, 64 * 4 );
4112 info->bmiHeader.biHeight = 16;
4113 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4114 ok( ret == 12, "got %d\n", ret );
4115 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4116 ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
4117 memset( dib_bits, 0xaa, 64 * 4 );
4119 info->bmiHeader.biHeight = 5;
4120 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4121 ok( ret == 2, "got %d\n", ret );
4122 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4123 ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
4124 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4125 memset( dib_bits, 0xaa, 64 * 4 );
4127 DeleteObject( dib );
4128 ReleaseDC( NULL, hdc );
4129 HeapFree( GetProcessHeap(), 0, info );
4132 static void test_SetDIBits_RLE4(void)
4136 HDC hdc = GetDC( NULL );
4137 BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00, /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
4138 0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
4139 0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00, /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
4140 0x00, 0x02, 0x01, 0x02, 0x05, 0x87, /* dx=1, dy=2, 8, 7, 8, 7, 8 */
4141 0x00, 0x01 }; /* <eod> */
4144 DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
4145 0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
4146 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4147 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4148 0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
4149 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4150 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4151 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4153 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4155 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4156 info->bmiHeader.biWidth = 8;
4157 info->bmiHeader.biHeight = 8;
4158 info->bmiHeader.biPlanes = 1;
4159 info->bmiHeader.biBitCount = 32;
4160 info->bmiHeader.biCompression = BI_RGB;
4162 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4163 memset( dib_bits, 0xaa, 64 * 4 );
4165 info->bmiHeader.biBitCount = 4;
4166 info->bmiHeader.biCompression = BI_RLE4;
4167 info->bmiHeader.biSizeImage = sizeof(rle4_data);
4169 for (i = 0; i < 16; i++)
4171 info->bmiColors[i].rgbRed = i;
4172 info->bmiColors[i].rgbGreen = i;
4173 info->bmiColors[i].rgbBlue = i;
4174 info->bmiColors[i].rgbReserved = 0;
4177 ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
4178 ok( ret == 8, "got %d\n", ret );
4179 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
4180 memset( dib_bits, 0xaa, 64 * 4 );
4182 DeleteObject( dib );
4183 ReleaseDC( NULL, hdc );
4184 HeapFree( GetProcessHeap(), 0, info );
4187 static void test_SetDIBits_RLE8(void)
4191 HDC hdc = GetDC( NULL );
4192 BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00, /* 2, 2, 2, f0, f0, f0, f0, <eol> */
4193 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4194 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4195 0x00, 0x01 }; /* <eod> */
4198 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4199 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4200 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4201 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4202 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4203 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4204 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4205 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4206 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4207 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4208 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4209 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4210 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4211 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4212 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4213 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4215 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4217 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4218 info->bmiHeader.biWidth = 8;
4219 info->bmiHeader.biHeight = 8;
4220 info->bmiHeader.biPlanes = 1;
4221 info->bmiHeader.biBitCount = 32;
4222 info->bmiHeader.biCompression = BI_RGB;
4224 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4225 memset( dib_bits, 0xaa, 64 * 4 );
4227 info->bmiHeader.biBitCount = 8;
4228 info->bmiHeader.biCompression = BI_RLE8;
4229 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4231 for (i = 0; i < 256; i++)
4233 info->bmiColors[i].rgbRed = i;
4234 info->bmiColors[i].rgbGreen = i;
4235 info->bmiColors[i].rgbBlue = i;
4236 info->bmiColors[i].rgbReserved = 0;
4239 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4240 ok( ret == 8, "got %d\n", ret );
4241 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4242 memset( dib_bits, 0xaa, 64 * 4 );
4244 /* startscan and lines are ignored, unless lines == 0 */
4245 ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4246 ok( ret == 8, "got %d\n", ret );
4247 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4248 memset( dib_bits, 0xaa, 64 * 4 );
4250 ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4251 ok( ret == 8, "got %d\n", ret );
4252 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4253 memset( dib_bits, 0xaa, 64 * 4 );
4255 ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4256 ok( ret == 0, "got %d\n", ret );
4257 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4258 memset( dib_bits, 0xaa, 64 * 4 );
4260 /* reduce width to 4, left-hand side of dst is touched. */
4261 info->bmiHeader.biWidth = 4;
4262 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4263 ok( ret == 8, "got %d\n", ret );
4264 for (i = 0; i < 64; i++)
4266 DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4267 ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4269 memset( dib_bits, 0xaa, 64 * 4 );
4271 /* Show that the top lines are aligned by adjusting the height of the src */
4273 /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4274 info->bmiHeader.biWidth = 8;
4275 info->bmiHeader.biHeight = 4;
4276 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4277 ok( ret == 4, "got %d\n", ret );
4278 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4279 ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4280 memset( dib_bits, 0xaa, 64 * 4 );
4282 /* increase the height to 9 -> everything moves down one row. */
4283 info->bmiHeader.biHeight = 9;
4284 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4285 ok( ret == 9, "got %d\n", ret );
4286 ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4287 for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4288 memset( dib_bits, 0xaa, 64 * 4 );
4290 /* top-down compressed dibs are invalid */
4291 info->bmiHeader.biHeight = -8;
4292 SetLastError( 0xdeadbeef );
4293 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4294 ok( ret == 0, "got %d\n", ret );
4295 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4296 DeleteObject( dib );
4300 info->bmiHeader.biHeight = -8;
4301 info->bmiHeader.biBitCount = 32;
4302 info->bmiHeader.biCompression = BI_RGB;
4303 info->bmiHeader.biSizeImage = 0;
4305 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4306 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4308 info->bmiHeader.biHeight = 8;
4309 info->bmiHeader.biBitCount = 8;
4310 info->bmiHeader.biCompression = BI_RLE8;
4311 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4313 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4314 ok( ret == 8, "got %d\n", ret );
4315 ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4316 memset( dib_bits, 0xaa, 64 * 4 );
4318 info->bmiHeader.biHeight = 4;
4319 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4320 ok( ret == 4, "got %d\n", ret );
4321 ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4322 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4323 memset( dib_bits, 0xaa, 64 * 4 );
4325 info->bmiHeader.biHeight = 9;
4326 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4327 ok( ret == 9, "got %d\n", ret );
4328 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4329 ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4330 memset( dib_bits, 0xaa, 64 * 4 );
4332 DeleteObject( dib );
4333 ReleaseDC( NULL, hdc );
4334 HeapFree( GetProcessHeap(), 0, info );
4337 static void test_SetDIBitsToDevice(void)
4341 HDC hdc = CreateCompatibleDC( 0 );
4342 DWORD data[128], inverted_data[128];
4346 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4348 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4349 info->bmiHeader.biWidth = 8;
4350 info->bmiHeader.biHeight = 8;
4351 info->bmiHeader.biPlanes = 1;
4352 info->bmiHeader.biBitCount = 32;
4353 info->bmiHeader.biCompression = BI_RGB;
4355 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4356 memset( dib_bits, 0xaa, 64 * 4 );
4357 SelectObject( hdc, dib );
4359 for (i = 0; i < 128; i++)
4362 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4367 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4368 ok( ret == 8, "got %d\n", ret );
4369 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4370 memset( dib_bits, 0xaa, 64 * 4 );
4372 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4373 ok( ret == 5, "got %d\n", ret );
4374 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4375 for (i = 8; i < 48; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4376 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4377 memset( dib_bits, 0xaa, 64 * 4 );
4379 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 3, 1, 5, data, info, DIB_RGB_COLORS );
4380 ok( ret == 5, "got %d\n", ret );
4381 for (i = 0; i < 24; i++) ok( dib_bits[i] == data[i + 16], "%d: got %08x\n", i, dib_bits[i] );
4382 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4383 memset( dib_bits, 0xaa, 64 * 4 );
4385 info->bmiHeader.biHeight = 16;
4386 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4387 ok( ret == 7, "got %d\n", ret );
4388 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4389 for (i = 8; i < 64; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4390 memset( dib_bits, 0xaa, 64 * 4 );
4392 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 8, 0, 6, 1, 12, data, info, DIB_RGB_COLORS );
4393 ok( ret == 12, "got %d\n", ret );
4394 for (i = 0; i < 40; i++) ok( dib_bits[i] == data[i + 56], "%d: got %08x\n", i, dib_bits[i] );
4395 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4396 memset( dib_bits, 0xaa, 64 * 4 );
4398 ret = SetDIBitsToDevice( hdc, 0, -4, 8, 8, 0, 3, 1, 12, data, info, DIB_RGB_COLORS );
4399 ok( ret == 10, "got %d\n", ret );
4400 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4401 for (i = 32; i < 64; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4402 memset( dib_bits, 0xaa, 64 * 4 );
4404 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, -3, 1, 12, data, info, DIB_RGB_COLORS );
4405 ok( ret == 4, "got %d\n", ret );
4406 for (i = 0; i < 32; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4407 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4408 memset( dib_bits, 0xaa, 64 * 4 );
4410 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 5, 0, -2, 1, 12, data, info, DIB_RGB_COLORS );
4411 ok( ret == 2, "got %d\n", ret );
4412 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4413 for (i = 32; i < 48; i++) ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4414 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4415 memset( dib_bits, 0xaa, 64 * 4 );
4417 info->bmiHeader.biHeight = 5;
4418 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 2, 2, data, info, DIB_RGB_COLORS );
4419 ok( ret == 2, "got %d\n", ret );
4420 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4421 for (i = 16; i < 32; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4422 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4423 memset( dib_bits, 0xaa, 64 * 4 );
4425 ret = SetDIBitsToDevice( hdc, 3, 3, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4426 ok( ret == 3, "got %d\n", ret );
4427 for (i = 0; i < 64; i++)
4428 if (i == 27 || i == 28 || i == 35 || i == 36)
4429 ok( dib_bits[i] == data[i - 18], "%d: got %08x\n", i, dib_bits[i] );
4431 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4432 memset( dib_bits, 0xaa, 64 * 4 );
4434 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4435 ok( ret == 5, "got %d\n", ret );
4436 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4437 memset( dib_bits, 0xaa, 64 * 4 );
4439 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4440 ok( ret == 0, "got %d\n", ret );
4441 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4442 memset( dib_bits, 0xaa, 64 * 4 );
4444 SetMapMode( hdc, MM_ANISOTROPIC );
4445 SetWindowExtEx( hdc, 3, 3, NULL );
4446 ret = SetDIBitsToDevice( hdc, 2, 2, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4447 ok( ret == 3, "got %d\n", ret );
4448 for (i = 0; i < 64; i++)
4449 if (i == 41 || i == 42 || i == 49 || i == 50)
4450 ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4452 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4453 memset( dib_bits, 0xaa, 64 * 4 );
4455 SetWindowExtEx( hdc, -1, -1, NULL );
4456 ret = SetDIBitsToDevice( hdc, 2, 2, 4, 4, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4457 ok( ret == 4, "got %d\n", ret );
4458 for (i = 0; i < 64; i++)
4459 if (i == 48 || i == 49 || i == 56 || i == 57)
4460 ok( dib_bits[i] == data[i - 37], "%d: got %08x\n", i, dib_bits[i] );
4462 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4463 memset( dib_bits, 0xaa, 64 * 4 );
4464 SetMapMode( hdc, MM_TEXT );
4468 pSetLayout( hdc, LAYOUT_RTL );
4469 ret = SetDIBitsToDevice( hdc, 1, 2, 3, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4470 ok( ret == 3, "got %d\n", ret );
4471 for (i = 0; i < 64; i++)
4472 if (i == 36 || i == 37 || i == 38 || i == 44 || i == 45 || i == 46)
4473 ok( dib_bits[i] == data[i - 27], "%d: got %08x\n", i, dib_bits[i] );
4475 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4476 memset( dib_bits, 0xaa, 64 * 4 );
4477 pSetLayout( hdc, LAYOUT_LTR );
4481 info->bmiHeader.biHeight = -8;
4482 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4483 ok( ret == 8, "got %d\n", ret );
4484 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4485 memset( dib_bits, 0xaa, 64 * 4 );
4487 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4488 ok( ret == 5, "got %d\n", ret );
4489 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4490 for (i = 8; i < 48; i++) ok( dib_bits[i] == inverted_data[i + 80], "%d: got %08x\n", i, dib_bits[i] );
4491 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4492 memset( dib_bits, 0xaa, 64 * 4 );
4494 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 4, 1, 5, data, info, DIB_RGB_COLORS );
4495 ok( ret == 5, "got %d\n", ret );
4496 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4497 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4498 memset( dib_bits, 0xaa, 64 * 4 );
4500 info->bmiHeader.biHeight = -16;
4501 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4502 ok( ret == 12, "got %d\n", ret );
4503 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4504 for (i = 8; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4505 memset( dib_bits, 0xaa, 64 * 4 );
4507 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, 7, 1, 12, data, info, DIB_RGB_COLORS );
4508 ok( ret == 12, "got %d\n", ret );
4509 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4510 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4511 memset( dib_bits, 0xaa, 64 * 4 );
4513 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 4, 12, data, info, DIB_RGB_COLORS );
4514 ok( ret == 12, "got %d\n", ret );
4515 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4516 for (i = 32; i < 64; i++) ok( dib_bits[i] == inverted_data[i], "%d: got %08x\n", i, dib_bits[i] );
4517 memset( dib_bits, 0xaa, 64 * 4 );
4519 ret = SetDIBitsToDevice( hdc, 0, -3, 8, 8, 0, 2, 4, 12, data, info, DIB_RGB_COLORS );
4520 ok( ret == 12, "got %d\n", ret );
4521 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4522 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4523 memset( dib_bits, 0xaa, 64 * 4 );
4525 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, -2, 4, 12, data, info, DIB_RGB_COLORS );
4526 ok( ret == 12, "got %d\n", ret );
4527 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4528 for (i = 24; i < 40; i++) ok( dib_bits[i] == inverted_data[i + 8], "%d: got %08x\n", i, dib_bits[i] );
4529 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4530 memset( dib_bits, 0xaa, 64 * 4 );
4532 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 5, 12, data, info, DIB_RGB_COLORS );
4533 ok( ret == 12, "got %d\n", ret );
4534 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4535 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4536 memset( dib_bits, 0xaa, 64 * 4 );
4538 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4539 ok( ret == 12, "got %d\n", ret );
4540 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4541 memset( dib_bits, 0xaa, 64 * 4 );
4543 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -2, -4, 0, 12, data, info, DIB_RGB_COLORS );
4544 ok( ret == 12, "got %d\n", ret );
4545 for (i = 0; i < 64; i++)
4546 if (i == 31 || i == 39 || i == 47 || i == 55 || i == 63)
4547 ok( dib_bits[i] == inverted_data[i + 1], "%d: got %08x\n", i, dib_bits[i] );
4549 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4550 memset( dib_bits, 0xaa, 64 * 4 );
4552 info->bmiHeader.biHeight = -5;
4553 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4554 ok( ret == 2, "got %d\n", ret );
4555 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4556 for (i = 8; i < 24; i++) ok( dib_bits[i] == inverted_data[i + 104], "%d: got %08x\n", i, dib_bits[i] );
4557 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4558 memset( dib_bits, 0xaa, 64 * 4 );
4560 ret = SetDIBitsToDevice( hdc, 5, 4, 2, 2, 6, 3, 1, 5, data, info, DIB_RGB_COLORS );
4561 ok( ret == 5, "got %d\n", ret );
4562 for (i = 0; i < 64; i++)
4563 if (i == 21 || i == 22 || i == 29 || i == 30)
4564 ok( dib_bits[i] == inverted_data[i + 89], "%d: got %08x\n", i, dib_bits[i] );
4566 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4567 memset( dib_bits, 0xaa, 64 * 4 );
4569 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4570 ok( ret == 5, "got %d\n", ret );
4571 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4572 memset( dib_bits, 0xaa, 64 * 4 );
4574 info->bmiHeader.biHeight = -8;
4576 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4577 DeleteObject( SelectObject( hdc, dib ));
4578 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4582 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4583 ok( ret == 8, "got %d\n", ret );
4584 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4585 memset( dib_bits, 0xaa, 64 * 4 );
4587 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4588 ok( ret == 5, "got %d\n", ret );
4589 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4590 for (i = 16; i < 56; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4591 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4592 memset( dib_bits, 0xaa, 64 * 4 );
4594 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 3, 0, 2, 1, 5, data, info, DIB_RGB_COLORS );
4595 ok( ret == 5, "got %d\n", ret );
4596 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4597 for (i = 24; i < 48; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4598 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4599 memset( dib_bits, 0xaa, 64 * 4 );
4601 info->bmiHeader.biHeight = -16;
4602 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4603 ok( ret == 12, "got %d\n", ret );
4604 for (i = 0; i < 56; i++) ok( dib_bits[i] == data[i + 40], "%d: got %08x\n", i, dib_bits[i] );
4605 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4606 memset( dib_bits, 0xaa, 64 * 4 );
4608 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -1, -8, 0, 12, data, info, DIB_RGB_COLORS );
4609 ok( ret == 12, "got %d\n", ret );
4610 for (i = 0; i < 64; i++)
4611 if (i == 6 || i == 7)
4612 ok( dib_bits[i] == data[i + 82], "%d: got %08x\n", i, dib_bits[i] );
4614 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4615 memset( dib_bits, 0xaa, 64 * 4 );
4617 info->bmiHeader.biHeight = -5;
4618 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4619 ok( ret == 2, "got %d\n", ret );
4620 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4621 for (i = 40; i < 56; i++) ok( dib_bits[i] == data[i - 40], "%d: got %08x\n", i, dib_bits[i] );
4622 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4623 memset( dib_bits, 0xaa, 64 * 4 );
4625 ret = SetDIBitsToDevice( hdc, 7, 2, 8, 8, 1, 0, 0, 5, data, info, DIB_RGB_COLORS );
4626 ok( ret == 5, "got %d\n", ret );
4627 for (i = 0; i < 64; i++)
4628 if (i == 47 || i == 55 || i == 63)
4629 ok( dib_bits[i] == data[i - 46], "%d: got %08x\n", i, dib_bits[i] );
4631 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4632 memset( dib_bits, 0xaa, 64 * 4 );
4634 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4635 ok( ret == 5, "got %d\n", ret );
4636 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4637 memset( dib_bits, 0xaa, 64 * 4 );
4641 info->bmiHeader.biHeight = 8;
4642 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4643 ok( ret == 8, "got %d\n", ret );
4644 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4645 memset( dib_bits, 0xaa, 64 * 4 );
4647 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4648 ok( ret == 5, "got %d\n", ret );
4649 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4650 for (i = 16; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4651 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4652 memset( dib_bits, 0xaa, 64 * 4 );
4654 info->bmiHeader.biHeight = 16;
4655 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4656 ok( ret == 7, "got %d\n", ret );
4657 for (i = 0; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4658 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4659 memset( dib_bits, 0xaa, 64 * 4 );
4661 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, 0, -4, 1, 12, data, info, DIB_RGB_COLORS );
4662 ok( ret == 3, "got %d\n", ret );
4663 for (i = 0; i < 64; i++)
4664 if ((i >= 36 && i <= 39) || (i >= 44 && i <= 47) || (i >= 52 && i <= 55))
4665 ok( dib_bits[i] == inverted_data[i + 68], "%d: got %08x\n", i, dib_bits[i] );
4667 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4668 memset( dib_bits, 0xaa, 64 * 4 );
4670 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, -30, -30, 1, 12, data, info, DIB_RGB_COLORS );
4671 ok( ret == 0, "got %d\n", ret );
4672 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4673 memset( dib_bits, 0xaa, 64 * 4 );
4675 ret = SetDIBitsToDevice( hdc, 5, -5, 8, 16, -2, -4, 4, 12, data, info, DIB_RGB_COLORS );
4676 ok( ret == 8, "got %d\n", ret );
4677 for (i = 0; i < 64; i++)
4678 if (i == 7 || i == 15 || i == 23)
4679 ok( dib_bits[i] == inverted_data[i + 97], "%d: got %08x\n", i, dib_bits[i] );
4681 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4682 memset( dib_bits, 0xaa, 64 * 4 );
4684 info->bmiHeader.biHeight = 5;
4685 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4686 ok( ret == 2, "got %d\n", ret );
4687 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4688 for (i = 40; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4689 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4690 memset( dib_bits, 0xaa, 64 * 4 );
4692 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4693 ok( ret == 5, "got %d\n", ret );
4694 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4695 memset( dib_bits, 0xaa, 64 * 4 );
4698 DeleteObject( dib );
4699 HeapFree( GetProcessHeap(), 0, info );
4702 static void test_SetDIBitsToDevice_RLE8(void)
4706 HDC hdc = CreateCompatibleDC( 0 );
4707 BYTE rle8_data[20] = { 0x04, 0x02, 0x03, 0xf0, 0x00, 0x00, /* 2, 2, 2, 2, f0, f0, f0, <eol> */
4708 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4709 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4710 0x00, 0x01 }; /* <eod> */
4713 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4714 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4715 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4716 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4717 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4718 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4719 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4720 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4721 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4722 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4723 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4724 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4725 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4726 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4727 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4728 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4730 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4732 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4733 info->bmiHeader.biWidth = 8;
4734 info->bmiHeader.biHeight = 8;
4735 info->bmiHeader.biPlanes = 1;
4736 info->bmiHeader.biBitCount = 32;
4737 info->bmiHeader.biCompression = BI_RGB;
4739 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4740 memset( dib_bits, 0xaa, 64 * 4 );
4741 SelectObject( hdc, dib );
4743 info->bmiHeader.biBitCount = 8;
4744 info->bmiHeader.biCompression = BI_RLE8;
4745 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4747 for (i = 0; i < 256; i++)
4749 info->bmiColors[i].rgbRed = i;
4750 info->bmiColors[i].rgbGreen = i;
4751 info->bmiColors[i].rgbBlue = i;
4752 info->bmiColors[i].rgbReserved = 0;
4755 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4756 ok( ret == 8, "got %d\n", ret );
4757 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4758 memset( dib_bits, 0xaa, 64 * 4 );
4760 /* startscan and lines are ignored, unless lines == 0 */
4761 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4762 ok( ret == 8, "got %d\n", ret );
4763 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4764 memset( dib_bits, 0xaa, 64 * 4 );
4766 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4767 ok( ret == 8, "got %d\n", ret );
4768 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4769 memset( dib_bits, 0xaa, 64 * 4 );
4771 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4772 ok( ret == 0, "got %d\n", ret );
4773 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4774 memset( dib_bits, 0xaa, 64 * 4 );
4776 info->bmiHeader.biWidth = 2;
4777 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4778 ok( ret == 8, "got %d\n", ret );
4779 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4780 memset( dib_bits, 0xaa, 64 * 4 );
4782 info->bmiHeader.biWidth = 8;
4783 info->bmiHeader.biHeight = 2;
4784 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4785 ok( ret == 2, "got %d\n", ret );
4786 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4787 memset( dib_bits, 0xaa, 64 * 4 );
4789 info->bmiHeader.biHeight = 9;
4790 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4791 ok( ret == 9, "got %d\n", ret );
4792 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4793 memset( dib_bits, 0xaa, 64 * 4 );
4795 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4796 ok( ret == 9, "got %d\n", ret );
4797 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4798 memset( dib_bits, 0xaa, 64 * 4 );
4800 info->bmiHeader.biHeight = 8;
4801 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 9, rle8_data, info, DIB_RGB_COLORS );
4802 ok( ret == 8, "got %d\n", ret );
4803 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4804 memset( dib_bits, 0xaa, 64 * 4 );
4806 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4807 ok( ret == 8, "got %d\n", ret );
4808 for (i = 0; i < 40; i++) ok( dib_bits[i] == bottom_up[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4809 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4810 memset( dib_bits, 0xaa, 64 * 4 );
4812 ret = SetDIBitsToDevice( hdc, 0, 3, 4, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4813 ok( ret == 8, "got %d\n", ret );
4814 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4815 for (i = 8; i < 40; i++)
4816 if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4817 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4818 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4819 memset( dib_bits, 0xaa, 64 * 4 );
4821 ret = SetDIBitsToDevice( hdc, 3, 3, 8, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4822 ok( ret == 8, "got %d\n", ret );
4823 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4824 for (i = 8; i < 40; i++)
4825 if ((i & 7) < 3) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4826 else ok( dib_bits[i] == bottom_up[i - 11], "%d: got %08x\n", i, dib_bits[i] );
4827 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4828 memset( dib_bits, 0xaa, 64 * 4 );
4830 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 4, 2, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4831 ok( ret == 8, "got %d\n", ret );
4832 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4833 for (i = 8; i < 40; i++)
4834 if ((i & 7) < 2) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4835 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4836 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4837 memset( dib_bits, 0xaa, 64 * 4 );
4839 info->bmiHeader.biWidth = 37;
4840 info->bmiHeader.biHeight = 37;
4841 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
4842 ok( ret == 37, "got %d\n", ret );
4843 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4844 for (i = 24; i < 64; i++)
4845 if (i == 52) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
4846 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4847 else ok( dib_bits[i] == bottom_up[i - 20], "%d: got %08x\n", i, dib_bits[i] );
4848 memset( dib_bits, 0xaa, 64 * 4 );
4850 /* top-down compressed dibs are invalid */
4851 info->bmiHeader.biWidth = 8;
4852 info->bmiHeader.biHeight = -8;
4853 SetLastError( 0xdeadbeef );
4854 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4855 ok( ret == 0, "got %d\n", ret );
4856 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4860 info->bmiHeader.biHeight = -8;
4861 info->bmiHeader.biBitCount = 32;
4862 info->bmiHeader.biCompression = BI_RGB;
4863 info->bmiHeader.biSizeImage = 0;
4865 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4866 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4867 DeleteObject( SelectObject( hdc, dib ));
4869 info->bmiHeader.biHeight = 8;
4870 info->bmiHeader.biBitCount = 8;
4871 info->bmiHeader.biCompression = BI_RLE8;
4872 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4874 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4875 ok( ret == 8, "got %d\n", ret );
4876 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4877 memset( dib_bits, 0xaa, 64 * 4 );
4879 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4880 ok( ret == 8, "got %d\n", ret );
4881 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4882 memset( dib_bits, 0xaa, 64 * 4 );
4884 info->bmiHeader.biHeight = 4;
4885 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4886 ok( ret == 4, "got %d\n", ret );
4887 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4888 memset( dib_bits, 0xaa, 64 * 4 );
4890 info->bmiHeader.biHeight = 9;
4891 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4892 ok( ret == 9, "got %d\n", ret );
4893 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4894 memset( dib_bits, 0xaa, 64 * 4 );
4896 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4897 ok( ret == 9, "got %d\n", ret );
4898 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4899 memset( dib_bits, 0xaa, 64 * 4 );
4901 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 6, 2, 2, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4902 ok( ret == 9, "got %d\n", ret );
4903 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4904 for (i = 24; i < 64; i++) ok( dib_bits[i] == top_down[i - 24], "%d: got %08x\n", i, dib_bits[i] );
4905 memset( dib_bits, 0xaa, 64 * 4 );
4907 info->bmiHeader.biWidth = 37;
4908 info->bmiHeader.biHeight = 37;
4909 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
4910 ok( ret == 37, "got %d\n", ret );
4911 for (i = 0; i < 40; i++)
4912 if (i == 12) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
4913 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4914 else ok( dib_bits[i] == top_down[i + 28], "%d: got %08x\n", i, dib_bits[i] );
4915 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4916 memset( dib_bits, 0xaa, 64 * 4 );
4919 DeleteObject( dib );
4920 HeapFree( GetProcessHeap(), 0, info );
4927 hdll = GetModuleHandle("gdi32.dll");
4928 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
4929 pSetLayout = (void*)GetProcAddress(hdll, "SetLayout");
4931 test_createdibitmap();
4934 test_mono_dibsection();
4937 test_GetDIBits_selected_DIB(1);
4938 test_GetDIBits_selected_DIB(4);
4939 test_GetDIBits_selected_DIB(8);
4940 test_GetDIBits_selected_DDB(TRUE);
4941 test_GetDIBits_selected_DDB(FALSE);
4943 test_GetDIBits_BI_BITFIELDS();
4944 test_select_object();
4945 test_CreateBitmap();
4948 test_StretchDIBits();
4949 test_GdiAlphaBlend();
4950 test_32bit_bitmap_blt();
4951 test_bitmapinfoheadersize();
4954 test_GetDIBits_top_down(16);
4955 test_GetDIBits_top_down(24);
4956 test_GetDIBits_top_down(32);
4957 test_GetSetDIBits_rtl();
4958 test_GetDIBits_scanlines();
4960 test_SetDIBits_RLE4();
4961 test_SetDIBits_RLE8();
4962 test_SetDIBitsToDevice();
4963 test_SetDIBitsToDevice_RLE8();