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_todo(got, exp, txt, todo) \
342 if (!todo && got != exp && screen_depth < 24) { \
343 todo_wine ok(0, #txt " failed at %d-bit screen depth: got 0x%06x expected 0x%06x - skipping DIB tests\n", \
344 screen_depth, (UINT)got, (UINT)exp); \
346 } else if (todo) todo_wine { ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp); } \
347 else ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp) \
349 #define test_color(hdc, color, exp, todo_setp, todo_getp) \
352 c = SetPixel(hdc, 0, 0, color); \
353 test_color_todo(c, exp, SetPixel, todo_setp); \
354 c = GetPixel(hdc, 0, 0); \
355 test_color_todo(c, exp, GetPixel, todo_getp); \
358 static void test_dib_bits_access( HBITMAP hdib, void *bits )
360 MEMORY_BASIC_INFORMATION info;
361 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
363 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
365 char filename[MAX_PATH];
370 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
371 "VirtualQuery failed\n");
372 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
373 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
374 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
375 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
376 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
377 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
379 memset( pbmi, 0, sizeof(bmibuf) );
380 memset( data, 0xcc, sizeof(data) );
381 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
382 pbmi->bmiHeader.biHeight = 16;
383 pbmi->bmiHeader.biWidth = 16;
384 pbmi->bmiHeader.biBitCount = 32;
385 pbmi->bmiHeader.biPlanes = 1;
386 pbmi->bmiHeader.biCompression = BI_RGB;
390 ret = SetDIBits( hdc, hdib, 0, 16, data, pbmi, DIB_RGB_COLORS );
391 ok(ret == 16, "SetDIBits failed: expected 16 got %d\n", ret);
395 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
396 "VirtualQuery failed\n");
397 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
398 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
399 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
400 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
401 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
402 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
404 /* try writing protected bits to a file */
406 GetTempFileNameA( ".", "dib", 0, filename );
407 file = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
408 CREATE_ALWAYS, 0, 0 );
409 ok( file != INVALID_HANDLE_VALUE, "failed to open %s error %u\n", filename, GetLastError() );
410 ret = WriteFile( file, bits, 8192, &written, NULL );
411 ok( ret, "WriteFile failed error %u\n", GetLastError() );
412 if (ret) ok( written == 8192, "only wrote %u bytes\n", written );
414 DeleteFileA( filename );
417 static void test_dibsections(void)
419 HDC hdc, hdcmem, hdcmem2;
420 HBITMAP hdib, oldbm, hdib2, oldbm2;
421 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
422 char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
423 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
424 BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
430 char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
431 LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
434 HPALETTE hpal, oldpal;
439 MEMORY_BASIC_INFORMATION info;
442 screen_depth = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
444 memset(pbmi, 0, sizeof(bmibuf));
445 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
446 pbmi->bmiHeader.biHeight = 100;
447 pbmi->bmiHeader.biWidth = 512;
448 pbmi->bmiHeader.biBitCount = 24;
449 pbmi->bmiHeader.biPlanes = 1;
450 pbmi->bmiHeader.biCompression = BI_RGB;
452 SetLastError(0xdeadbeef);
454 /* invalid pointer for BITMAPINFO
455 (*bits should be NULL on error) */
456 bits = (BYTE*)0xdeadbeef;
457 hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
458 ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n");
460 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
461 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
462 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
463 ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
465 /* test the DIB memory */
466 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
467 "VirtualQuery failed\n");
468 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
469 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
470 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
471 ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
472 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
473 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
474 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
476 test_dib_bits_access( hdib, bits );
478 test_dib_info(hdib, bits, &pbmi->bmiHeader);
481 /* Test a top-down DIB. */
482 pbmi->bmiHeader.biHeight = -100;
483 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
484 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
485 test_dib_info(hdib, bits, &pbmi->bmiHeader);
488 pbmi->bmiHeader.biHeight = 100;
489 pbmi->bmiHeader.biBitCount = 8;
490 pbmi->bmiHeader.biCompression = BI_RLE8;
491 SetLastError(0xdeadbeef);
492 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
493 ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
494 ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
496 pbmi->bmiHeader.biBitCount = 16;
497 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
498 ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
499 ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
500 ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
501 SetLastError(0xdeadbeef);
502 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
503 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
505 /* test the DIB memory */
506 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
507 "VirtualQuery failed\n");
508 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
509 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
510 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
511 ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
512 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
513 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
514 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
516 test_dib_info(hdib, bits, &pbmi->bmiHeader);
519 memset(pbmi, 0, sizeof(bmibuf));
520 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
521 pbmi->bmiHeader.biHeight = 16;
522 pbmi->bmiHeader.biWidth = 16;
523 pbmi->bmiHeader.biBitCount = 1;
524 pbmi->bmiHeader.biPlanes = 1;
525 pbmi->bmiHeader.biCompression = BI_RGB;
526 pbmi->bmiColors[0].rgbRed = 0xff;
527 pbmi->bmiColors[0].rgbGreen = 0;
528 pbmi->bmiColors[0].rgbBlue = 0;
529 pbmi->bmiColors[1].rgbRed = 0;
530 pbmi->bmiColors[1].rgbGreen = 0;
531 pbmi->bmiColors[1].rgbBlue = 0xff;
533 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
534 ok(hdib != NULL, "CreateDIBSection failed\n");
535 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
536 ok(dibsec.dsBmih.biClrUsed == 2,
537 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
539 /* Test if the old BITMAPCOREINFO structure is supported */
541 pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
542 pbci->bmciHeader.bcBitCount = 0;
544 ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
545 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
546 ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
547 && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
548 "GetDIBits didn't fill in the BITMAPCOREHEADER structure properly\n");
550 ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
551 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
552 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
553 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
554 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
555 "The color table has not been translated to the old BITMAPCOREINFO format\n");
557 hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
558 ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
560 ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
561 ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
562 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
563 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
564 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
565 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
566 "The color table has not been translated to the old BITMAPCOREINFO format\n");
568 DeleteObject(hcoredib);
570 hdcmem = CreateCompatibleDC(hdc);
571 oldbm = SelectObject(hdcmem, hdib);
573 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
574 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
575 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
576 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
577 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
578 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
580 c0 = RGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen, pbmi->bmiColors[0].rgbBlue);
581 c1 = RGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen, pbmi->bmiColors[1].rgbBlue);
583 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
584 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
585 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
586 test_color(hdcmem, PALETTEINDEX(0), c0, 1, 1);
587 test_color(hdcmem, PALETTEINDEX(1), c0, 1, 1);
588 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
589 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen,
590 pbmi->bmiColors[0].rgbBlue), c0, 1, 1);
591 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen,
592 pbmi->bmiColors[1].rgbBlue), c1, 1, 1);
593 test_color(hdcmem, PALETTERGB(0, 0, 0), c0, 1, 1);
594 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
595 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1, 1, 1);
597 SelectObject(hdcmem, oldbm);
600 pbmi->bmiColors[0].rgbRed = 0xff;
601 pbmi->bmiColors[0].rgbGreen = 0xff;
602 pbmi->bmiColors[0].rgbBlue = 0xff;
603 pbmi->bmiColors[1].rgbRed = 0;
604 pbmi->bmiColors[1].rgbGreen = 0;
605 pbmi->bmiColors[1].rgbBlue = 0;
607 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
608 ok(hdib != NULL, "CreateDIBSection failed\n");
610 test_dib_info(hdib, bits, &pbmi->bmiHeader);
612 oldbm = SelectObject(hdcmem, hdib);
614 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
615 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
616 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
617 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
618 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
619 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
621 SelectObject(hdcmem, oldbm);
622 test_dib_info(hdib, bits, &pbmi->bmiHeader);
625 pbmi->bmiHeader.biBitCount = 4;
626 for (i = 0; i < 16; i++) {
627 pbmi->bmiColors[i].rgbRed = i;
628 pbmi->bmiColors[i].rgbGreen = 16-i;
629 pbmi->bmiColors[i].rgbBlue = 0;
631 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
632 ok(hdib != NULL, "CreateDIBSection failed\n");
633 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
634 ok(dibsec.dsBmih.biClrUsed == 16,
635 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
636 test_dib_info(hdib, bits, &pbmi->bmiHeader);
639 pbmi->bmiHeader.biBitCount = 8;
641 for (i = 0; i < 128; i++) {
642 pbmi->bmiColors[i].rgbRed = 255 - i * 2;
643 pbmi->bmiColors[i].rgbGreen = i * 2;
644 pbmi->bmiColors[i].rgbBlue = 0;
645 pbmi->bmiColors[255 - i].rgbRed = 0;
646 pbmi->bmiColors[255 - i].rgbGreen = i * 2;
647 pbmi->bmiColors[255 - i].rgbBlue = 255 - i * 2;
649 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
650 ok(hdib != NULL, "CreateDIBSection failed\n");
651 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
652 ok(dibsec.dsBmih.biClrUsed == 256,
653 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
655 oldbm = SelectObject(hdcmem, hdib);
657 for (i = 0; i < 256; i++) {
658 test_color(hdcmem, DIBINDEX(i),
659 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
660 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue),
661 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
664 SelectObject(hdcmem, oldbm);
665 test_dib_info(hdib, bits, &pbmi->bmiHeader);
668 pbmi->bmiHeader.biBitCount = 1;
670 /* Now create a palette and a palette indexed dib section */
671 memset(plogpal, 0, sizeof(logpalbuf));
672 plogpal->palVersion = 0x300;
673 plogpal->palNumEntries = 2;
674 plogpal->palPalEntry[0].peRed = 0xff;
675 plogpal->palPalEntry[0].peBlue = 0xff;
676 plogpal->palPalEntry[1].peGreen = 0xff;
678 index = (WORD*)pbmi->bmiColors;
681 hpal = CreatePalette(plogpal);
682 ok(hpal != NULL, "CreatePalette failed\n");
683 oldpal = SelectPalette(hdc, hpal, TRUE);
684 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
685 ok(hdib != NULL, "CreateDIBSection failed\n");
686 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
687 ok(dibsec.dsBmih.biClrUsed == 2, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
689 /* The colour table has already been grabbed from the dc, so we select back the
692 SelectPalette(hdc, oldpal, TRUE);
693 oldbm = SelectObject(hdcmem, hdib);
694 oldpal = SelectPalette(hdcmem, hpal, TRUE);
696 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
697 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
698 ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
699 rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
700 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
701 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
702 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
704 c0 = RGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen, plogpal->palPalEntry[0].peBlue);
705 c1 = RGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen, plogpal->palPalEntry[1].peBlue);
707 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
708 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
709 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
710 test_color(hdcmem, PALETTEINDEX(0), c0, 0, 1);
711 test_color(hdcmem, PALETTEINDEX(1), c1, 0, 1);
712 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
713 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen,
714 plogpal->palPalEntry[0].peBlue), c0, 1, 1);
715 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen,
716 plogpal->palPalEntry[1].peBlue), c1, 1, 1);
717 test_color(hdcmem, PALETTERGB(0, 0, 0), c1, 1, 1);
718 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
719 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0, 1, 1);
720 test_color(hdcmem, PALETTERGB(0, 1, 0), c1, 1, 1);
721 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1, 1, 1);
722 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0, 1, 1);
724 /* Bottom and 2nd row from top green, everything else magenta */
725 bits[0] = bits[1] = 0xff;
726 bits[13 * 4] = bits[13*4 + 1] = 0xff;
728 test_dib_info(hdib, bits, &pbmi->bmiHeader);
730 pbmi->bmiHeader.biBitCount = 32;
732 hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
733 ok(hdib2 != NULL, "CreateDIBSection failed\n");
734 hdcmem2 = CreateCompatibleDC(hdc);
735 oldbm2 = SelectObject(hdcmem2, hdib2);
737 BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
739 ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
740 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
742 SelectObject(hdcmem2, oldbm2);
743 test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
746 SelectObject(hdcmem, oldbm);
747 SelectPalette(hdcmem, oldpal, TRUE);
752 pbmi->bmiHeader.biBitCount = 8;
754 memset(plogpal, 0, sizeof(logpalbuf));
755 plogpal->palVersion = 0x300;
756 plogpal->palNumEntries = 256;
758 for (i = 0; i < 128; i++) {
759 plogpal->palPalEntry[i].peRed = 255 - i * 2;
760 plogpal->palPalEntry[i].peBlue = i * 2;
761 plogpal->palPalEntry[i].peGreen = 0;
762 plogpal->palPalEntry[255 - i].peRed = 0;
763 plogpal->palPalEntry[255 - i].peGreen = i * 2;
764 plogpal->palPalEntry[255 - i].peBlue = 255 - i * 2;
767 index = (WORD*)pbmi->bmiColors;
768 for (i = 0; i < 256; i++) {
772 hpal = CreatePalette(plogpal);
773 ok(hpal != NULL, "CreatePalette failed\n");
774 oldpal = SelectPalette(hdc, hpal, TRUE);
775 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
776 ok(hdib != NULL, "CreateDIBSection failed\n");
777 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
778 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
780 test_dib_info(hdib, bits, &pbmi->bmiHeader);
782 SelectPalette(hdc, oldpal, TRUE);
783 oldbm = SelectObject(hdcmem, hdib);
784 oldpal = SelectPalette(hdcmem, hpal, TRUE);
786 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
787 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
788 for (i = 0; i < 256; i++) {
789 ok(rgb[i].rgbRed == plogpal->palPalEntry[i].peRed &&
790 rgb[i].rgbBlue == plogpal->palPalEntry[i].peBlue &&
791 rgb[i].rgbGreen == plogpal->palPalEntry[i].peGreen,
792 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
793 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
796 for (i = 0; i < 256; i++) {
797 test_color(hdcmem, DIBINDEX(i),
798 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
799 test_color(hdcmem, PALETTEINDEX(i),
800 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
801 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue),
802 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
805 SelectPalette(hdcmem, oldpal, TRUE);
806 SelectObject(hdcmem, oldbm);
815 static void test_dib_formats(void)
820 int planes, bpp, compr;
826 bi = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
828 memdc = CreateCompatibleDC( 0 );
829 hbmp = CreateCompatibleBitmap( hdc, 10, 10 );
831 memset( data, 0xaa, sizeof(data) );
833 for (bpp = 0; bpp <= 64; bpp++)
835 for (planes = 0; planes <= 64; planes++)
837 for (compr = 0; compr < 8; compr++)
844 case 24: expect_ok = (compr == BI_RGB); break;
846 case 32: expect_ok = (compr == BI_RGB || compr == BI_BITFIELDS); break;
847 default: expect_ok = FALSE; break;
850 memset( bi, 0, sizeof(bi->bmiHeader) );
851 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
852 bi->bmiHeader.biWidth = 2;
853 bi->bmiHeader.biHeight = 2;
854 bi->bmiHeader.biPlanes = planes;
855 bi->bmiHeader.biBitCount = bpp;
856 bi->bmiHeader.biCompression = compr;
857 bi->bmiHeader.biSizeImage = 0;
858 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
859 ret = GetDIBits(hdc, hbmp, 0, 0, data, bi, DIB_RGB_COLORS);
860 if (expect_ok || (!bpp && compr != BI_JPEG && compr != BI_PNG) ||
861 (bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8))
862 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
864 ok( !ret || broken(!bpp && (compr == BI_JPEG || compr == BI_PNG)), /* nt4 */
865 "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
867 /* all functions check planes except GetDIBits with 0 lines */
868 if (!planes) expect_ok = FALSE;
869 memset( bi, 0, sizeof(bi->bmiHeader) );
870 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
871 bi->bmiHeader.biWidth = 2;
872 bi->bmiHeader.biHeight = 2;
873 bi->bmiHeader.biPlanes = planes;
874 bi->bmiHeader.biBitCount = bpp;
875 bi->bmiHeader.biCompression = compr;
876 bi->bmiHeader.biSizeImage = 0;
877 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
879 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
880 if (expect_ok && (planes == 1 || planes * bpp <= 16))
881 ok( hdib != NULL, "CreateDIBSection failed for %u/%u/%u\n", bpp, planes, compr );
883 ok( hdib == NULL, "CreateDIBSection succeeded for %u/%u/%u\n", bpp, planes, compr );
884 if (hdib) DeleteObject( hdib );
886 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, data, bi, DIB_RGB_COLORS );
887 /* no sanity checks in CreateDIBitmap except compression */
888 if (compr == BI_JPEG || compr == BI_PNG)
889 ok( hdib == NULL || broken(hdib != NULL), /* nt4 */
890 "CreateDIBitmap succeeded for %u/%u/%u\n", bpp, planes, compr );
892 ok( hdib != NULL, "CreateDIBitmap failed for %u/%u/%u\n", bpp, planes, compr );
893 if (hdib) DeleteObject( hdib );
895 /* RLE needs a size */
896 bi->bmiHeader.biSizeImage = 0;
897 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
899 ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
902 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
903 "SetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
904 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
906 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
909 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
910 "SetDIBitsToDevice succeeded for %u/%u/%u\n", bpp, planes, compr );
911 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
913 ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
916 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
917 "StretchDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
919 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
921 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
923 ok( !ret, "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
924 ok( bi->bmiHeader.biBitCount == bpp, "GetDIBits modified bpp %u/%u\n",
925 bpp, bi->bmiHeader.biBitCount );
927 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
928 bi->bmiHeader.biWidth = 2;
929 bi->bmiHeader.biHeight = 2;
930 bi->bmiHeader.biPlanes = planes;
931 bi->bmiHeader.biBitCount = bpp;
932 bi->bmiHeader.biCompression = compr;
933 bi->bmiHeader.biSizeImage = 1;
934 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
935 /* RLE allowed with valid biSizeImage */
936 if ((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)) expect_ok = TRUE;
938 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
940 ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
942 ok( !ret, "SetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
943 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
945 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
947 ok( !ret, "SetDIBitsToDevice succeeded for %u/%u/%u\n", bpp, planes, compr );
948 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
950 ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
952 ok( !ret, "StretchDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
954 bi->bmiHeader.biSizeImage = 0;
955 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
956 if (expect_ok || !bpp)
957 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
959 ok( !ret, "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
964 memset( bi, 0, sizeof(bi->bmiHeader) );
965 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
966 bi->bmiHeader.biWidth = 2;
967 bi->bmiHeader.biHeight = 2;
968 bi->bmiHeader.biPlanes = 1;
969 bi->bmiHeader.biBitCount = 16;
970 bi->bmiHeader.biCompression = BI_BITFIELDS;
971 bi->bmiHeader.biSizeImage = 0;
972 *(DWORD *)&bi->bmiColors[0] = 0;
973 *(DWORD *)&bi->bmiColors[1] = 0;
974 *(DWORD *)&bi->bmiColors[2] = 0;
976 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
977 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
978 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
979 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
980 /* other functions don't check */
981 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
982 ok( hdib != NULL, "CreateDIBitmap failed with null bitfields\n" );
983 DeleteObject( hdib );
984 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
985 ok( ret, "SetDIBitsToDevice failed with null bitfields\n" );
986 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
987 ok( ret, "StretchDIBits failed with null bitfields\n" );
988 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
989 ok( ret, "GetDIBits failed with null bitfields\n" );
990 bi->bmiHeader.biPlanes = 1;
991 bi->bmiHeader.biBitCount = 16;
992 bi->bmiHeader.biCompression = BI_BITFIELDS;
993 bi->bmiHeader.biSizeImage = 0;
994 *(DWORD *)&bi->bmiColors[0] = 0;
995 *(DWORD *)&bi->bmiColors[1] = 0;
996 *(DWORD *)&bi->bmiColors[2] = 0;
997 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
998 ok( ret, "GetDIBits failed with null bitfields\n" );
1000 /* all fields must be non-zero */
1001 *(DWORD *)&bi->bmiColors[0] = 3;
1002 *(DWORD *)&bi->bmiColors[1] = 0;
1003 *(DWORD *)&bi->bmiColors[2] = 7;
1004 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1005 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1006 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1007 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1009 /* garbage is ok though */
1010 *(DWORD *)&bi->bmiColors[0] = 0x55;
1011 *(DWORD *)&bi->bmiColors[1] = 0x44;
1012 *(DWORD *)&bi->bmiColors[2] = 0x33;
1013 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1014 ok( hdib != NULL, "CreateDIBSection failed with bad bitfields\n" );
1015 if (hdib) DeleteObject( hdib );
1016 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1017 ok( ret, "SetDIBits failed with bad bitfields\n" );
1019 bi->bmiHeader.biWidth = -2;
1020 bi->bmiHeader.biHeight = 2;
1021 bi->bmiHeader.biBitCount = 32;
1022 bi->bmiHeader.biCompression = BI_RGB;
1023 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1024 ok( hdib == NULL, "CreateDIBSection succeeded with negative width\n" );
1025 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1026 ok( hdib == NULL, "CreateDIBitmap succeeded with negative width\n" );
1027 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1028 ok( !ret, "SetDIBits succeeded with negative width\n" );
1029 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1030 ok( !ret, "SetDIBitsToDevice succeeded with negative width\n" );
1031 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1032 ok( !ret, "StretchDIBits succeeded with negative width\n" );
1033 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1034 ok( !ret, "GetDIBits succeeded with negative width\n" );
1035 bi->bmiHeader.biWidth = -2;
1036 bi->bmiHeader.biHeight = 2;
1037 bi->bmiHeader.biBitCount = 32;
1038 bi->bmiHeader.biCompression = BI_RGB;
1039 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1040 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with negative width\n" );
1042 bi->bmiHeader.biWidth = 0;
1043 bi->bmiHeader.biHeight = 2;
1044 bi->bmiHeader.biBitCount = 32;
1045 bi->bmiHeader.biCompression = BI_RGB;
1046 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1047 ok( hdib == NULL, "CreateDIBSection succeeded with zero width\n" );
1048 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1049 ok( hdib != NULL, "CreateDIBitmap failed with zero width\n" );
1050 DeleteObject( hdib );
1051 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1052 ok( !ret || broken(ret), /* nt4 */ "SetDIBits succeeded with zero width\n" );
1053 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1054 ok( !ret || broken(ret), /* nt4 */ "SetDIBitsToDevice succeeded with zero width\n" );
1055 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1056 ok( !ret || broken(ret), /* nt4 */ "StretchDIBits succeeded with zero width\n" );
1057 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1058 ok( !ret, "GetDIBits succeeded with zero width\n" );
1059 bi->bmiHeader.biWidth = 0;
1060 bi->bmiHeader.biHeight = 2;
1061 bi->bmiHeader.biBitCount = 32;
1062 bi->bmiHeader.biCompression = BI_RGB;
1063 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1064 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero width\n" );
1066 bi->bmiHeader.biWidth = 2;
1067 bi->bmiHeader.biHeight = 0;
1068 bi->bmiHeader.biBitCount = 32;
1069 bi->bmiHeader.biCompression = BI_RGB;
1070 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1071 ok( hdib == NULL, "CreateDIBSection succeeded with zero height\n" );
1072 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1073 ok( hdib != NULL, "CreateDIBitmap failed with zero height\n" );
1074 DeleteObject( hdib );
1075 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1076 ok( !ret, "SetDIBits succeeded with zero height\n" );
1077 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1078 ok( !ret, "SetDIBitsToDevice succeeded with zero height\n" );
1079 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1080 ok( !ret, "StretchDIBits succeeded with zero height\n" );
1081 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1082 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1083 bi->bmiHeader.biWidth = 2;
1084 bi->bmiHeader.biHeight = 0;
1085 bi->bmiHeader.biBitCount = 32;
1086 bi->bmiHeader.biCompression = BI_RGB;
1087 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1088 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1091 DeleteObject( hbmp );
1092 ReleaseDC( 0, hdc );
1093 HeapFree( GetProcessHeap(), 0, bi );
1096 static void test_mono_dibsection(void)
1099 HBITMAP old_bm, mono_ds;
1100 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
1101 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
1108 memdc = CreateCompatibleDC(hdc);
1110 memset(pbmi, 0, sizeof(bmibuf));
1111 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
1112 pbmi->bmiHeader.biHeight = 10;
1113 pbmi->bmiHeader.biWidth = 10;
1114 pbmi->bmiHeader.biBitCount = 1;
1115 pbmi->bmiHeader.biPlanes = 1;
1116 pbmi->bmiHeader.biCompression = BI_RGB;
1117 pbmi->bmiColors[0].rgbRed = 0xff;
1118 pbmi->bmiColors[0].rgbGreen = 0xff;
1119 pbmi->bmiColors[0].rgbBlue = 0xff;
1120 pbmi->bmiColors[1].rgbRed = 0x0;
1121 pbmi->bmiColors[1].rgbGreen = 0x0;
1122 pbmi->bmiColors[1].rgbBlue = 0x0;
1125 * First dib section is 'inverted' ie color[0] is white, color[1] is black
1128 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1129 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1130 old_bm = SelectObject(memdc, mono_ds);
1132 /* black border, white interior */
1133 Rectangle(memdc, 0, 0, 10, 10);
1134 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1135 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1137 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1139 memset(bits, 0, sizeof(bits));
1142 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1143 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1145 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1147 pbmi->bmiColors[0].rgbRed = 0x0;
1148 pbmi->bmiColors[0].rgbGreen = 0x0;
1149 pbmi->bmiColors[0].rgbBlue = 0x0;
1150 pbmi->bmiColors[1].rgbRed = 0xff;
1151 pbmi->bmiColors[1].rgbGreen = 0xff;
1152 pbmi->bmiColors[1].rgbBlue = 0xff;
1154 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1155 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1157 SelectObject(memdc, old_bm);
1158 DeleteObject(mono_ds);
1161 * Next dib section is 'normal' ie color[0] is black, color[1] is white
1164 pbmi->bmiColors[0].rgbRed = 0x0;
1165 pbmi->bmiColors[0].rgbGreen = 0x0;
1166 pbmi->bmiColors[0].rgbBlue = 0x0;
1167 pbmi->bmiColors[1].rgbRed = 0xff;
1168 pbmi->bmiColors[1].rgbGreen = 0xff;
1169 pbmi->bmiColors[1].rgbBlue = 0xff;
1171 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1172 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1173 old_bm = SelectObject(memdc, mono_ds);
1175 /* black border, white interior */
1176 Rectangle(memdc, 0, 0, 10, 10);
1177 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
1178 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
1180 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
1182 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1183 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1185 /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
1187 pbmi->bmiColors[0].rgbRed = 0xff;
1188 pbmi->bmiColors[0].rgbGreen = 0xff;
1189 pbmi->bmiColors[0].rgbBlue = 0xff;
1190 pbmi->bmiColors[1].rgbRed = 0x0;
1191 pbmi->bmiColors[1].rgbGreen = 0x0;
1192 pbmi->bmiColors[1].rgbBlue = 0x0;
1194 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1195 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1198 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
1201 pbmi->bmiColors[0].rgbRed = 0xff;
1202 pbmi->bmiColors[0].rgbGreen = 0xff;
1203 pbmi->bmiColors[0].rgbBlue = 0xff;
1204 pbmi->bmiColors[1].rgbRed = 0x0;
1205 pbmi->bmiColors[1].rgbGreen = 0x0;
1206 pbmi->bmiColors[1].rgbBlue = 0x0;
1207 num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors);
1208 ok(num == 2, "num = %d\n", num);
1210 /* black border, white interior */
1211 Rectangle(memdc, 0, 0, 10, 10);
1212 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1213 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1215 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1217 memset(bits, 0, sizeof(bits));
1220 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1221 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1223 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1225 pbmi->bmiColors[0].rgbRed = 0x0;
1226 pbmi->bmiColors[0].rgbGreen = 0x0;
1227 pbmi->bmiColors[0].rgbBlue = 0x0;
1228 pbmi->bmiColors[1].rgbRed = 0xff;
1229 pbmi->bmiColors[1].rgbGreen = 0xff;
1230 pbmi->bmiColors[1].rgbBlue = 0xff;
1232 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1233 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1235 SelectObject(memdc, old_bm);
1236 DeleteObject(mono_ds);
1239 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
1242 pbmi->bmiColors[0].rgbRed = 0xff;
1243 pbmi->bmiColors[0].rgbGreen = 0x0;
1244 pbmi->bmiColors[0].rgbBlue = 0x0;
1245 pbmi->bmiColors[1].rgbRed = 0xfe;
1246 pbmi->bmiColors[1].rgbGreen = 0x0;
1247 pbmi->bmiColors[1].rgbBlue = 0x0;
1249 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1250 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1251 old_bm = SelectObject(memdc, mono_ds);
1253 /* black border, white interior */
1254 Rectangle(memdc, 0, 0, 10, 10);
1255 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1256 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1258 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1260 pbmi->bmiColors[0].rgbRed = 0x0;
1261 pbmi->bmiColors[0].rgbGreen = 0x0;
1262 pbmi->bmiColors[0].rgbBlue = 0x0;
1263 pbmi->bmiColors[1].rgbRed = 0xff;
1264 pbmi->bmiColors[1].rgbGreen = 0xff;
1265 pbmi->bmiColors[1].rgbBlue = 0xff;
1267 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1268 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1270 /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
1272 pbmi->bmiColors[0].rgbRed = 0xff;
1273 pbmi->bmiColors[0].rgbGreen = 0xff;
1274 pbmi->bmiColors[0].rgbBlue = 0xff;
1275 pbmi->bmiColors[1].rgbRed = 0x0;
1276 pbmi->bmiColors[1].rgbGreen = 0x0;
1277 pbmi->bmiColors[1].rgbBlue = 0x0;
1279 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1280 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1282 SelectObject(memdc, old_bm);
1283 DeleteObject(mono_ds);
1289 static void test_bitmap(void)
1291 char buf[256], buf_cmp[256];
1292 HBITMAP hbmp, hbmp_old;
1298 hdc = CreateCompatibleDC(0);
1301 SetLastError(0xdeadbeef);
1302 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1305 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1306 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1307 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1312 SetLastError(0xdeadbeef);
1313 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1316 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1317 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1318 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1323 SetLastError(0xdeadbeef);
1324 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1325 ok(!hbmp, "CreateBitmap should fail\n");
1327 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1328 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1332 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1333 assert(hbmp != NULL);
1335 ret = GetObject(hbmp, sizeof(bm), &bm);
1336 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1338 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1339 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1340 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1341 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1342 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1343 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1344 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1346 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1347 assert(sizeof(buf) == sizeof(buf_cmp));
1349 ret = GetBitmapBits(hbmp, 0, NULL);
1350 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1352 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1353 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1355 memset(buf, 0xAA, sizeof(buf));
1356 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1357 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1358 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1360 hbmp_old = SelectObject(hdc, hbmp);
1362 ret = GetObject(hbmp, sizeof(bm), &bm);
1363 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1365 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1366 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1367 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1368 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1369 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1370 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1371 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1373 memset(buf, 0xAA, sizeof(buf));
1374 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1375 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1376 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1378 hbmp_old = SelectObject(hdc, hbmp_old);
1379 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1381 /* test various buffer sizes for GetObject */
1382 ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
1383 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1385 ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1386 ok(ret == 0, "%d != 0\n", ret);
1388 ret = GetObject(hbmp, 0, &bm);
1389 ok(ret == 0, "%d != 0\n", ret);
1391 ret = GetObject(hbmp, 1, &bm);
1392 ok(ret == 0, "%d != 0\n", ret);
1398 static void test_bmBits(void)
1404 memset(bits, 0, sizeof(bits));
1405 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1406 ok(hbmp != NULL, "CreateBitmap failed\n");
1408 memset(&bmp, 0xFF, sizeof(bmp));
1409 ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1410 "GetObject failed or returned a wrong structure size\n");
1411 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1416 static void test_GetDIBits_selected_DIB(UINT bpp)
1423 UINT dib_size, dib32_size;
1430 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1431 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1433 /* Create a DIB section with a color table */
1435 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1436 info->bmiHeader.biWidth = 32;
1437 info->bmiHeader.biHeight = 32;
1438 info->bmiHeader.biPlanes = 1;
1439 info->bmiHeader.biBitCount = bpp;
1440 info->bmiHeader.biCompression = BI_RGB;
1441 info->bmiHeader.biXPelsPerMeter = 0;
1442 info->bmiHeader.biYPelsPerMeter = 0;
1443 info->bmiHeader.biClrUsed = 0;
1444 info->bmiHeader.biClrImportant = 0;
1446 for (i=0; i < (1u << bpp); i++)
1448 BYTE c = i * (1 << (8 - bpp));
1449 info->bmiColors[i].rgbRed = c;
1450 info->bmiColors[i].rgbGreen = c;
1451 info->bmiColors[i].rgbBlue = c;
1452 info->bmiColors[i].rgbReserved = 0;
1455 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1456 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1457 dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1459 /* Set the bits of the DIB section */
1460 for (i=0; i < dib_size; i++)
1462 ((BYTE *)bits)[i] = i % 256;
1465 /* Select the DIB into a DC */
1466 dib_dc = CreateCompatibleDC(NULL);
1467 old_bmp = SelectObject(dib_dc, dib);
1468 dc = CreateCompatibleDC(NULL);
1469 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
1471 /* Copy the DIB attributes but not the color table */
1472 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1474 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1475 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1477 /* Compare the color table and the bits */
1478 for (i=0; i < (1u << bpp); i++)
1479 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1480 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1481 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1482 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1483 "color table entry %d differs (bpp %d)\n", i, bpp );
1485 ok( !memcmp( bits, bits2, dib_size ), "bit mismatch (bpp %d)\n", bpp );
1487 /* Test various combinations of lines = 0 and bits2 = NULL */
1488 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1489 res = GetDIBits( dc, dib, 0, 0, bits2, info2, DIB_RGB_COLORS );
1490 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1491 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1492 "color table mismatch (bpp %d)\n", bpp );
1494 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1495 res = GetDIBits( dc, dib, 0, 0, NULL, info2, DIB_RGB_COLORS );
1496 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1497 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1498 "color table mismatch (bpp %d)\n", bpp );
1500 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1501 res = GetDIBits( dc, dib, 0, info->bmiHeader.biHeight, NULL, info2, DIB_RGB_COLORS );
1502 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1503 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1504 "color table mismatch (bpp %d)\n", bpp );
1506 /* Map into a 32bit-DIB */
1507 info2->bmiHeader.biBitCount = 32;
1508 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1509 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1511 /* Check if last pixel was set */
1512 pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
1513 ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
1515 HeapFree(GetProcessHeap(), 0, bits2);
1518 SelectObject(dib_dc, old_bmp);
1521 HeapFree(GetProcessHeap(), 0, info2);
1522 HeapFree(GetProcessHeap(), 0, info);
1525 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1539 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1540 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1542 width = height = 16;
1544 /* Create a DDB (device-dependent bitmap) */
1548 ddb = CreateBitmap(width, height, 1, 1, NULL);
1552 HDC screen_dc = GetDC(NULL);
1553 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1554 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1555 ReleaseDC(NULL, screen_dc);
1558 /* Set the pixels */
1559 ddb_dc = CreateCompatibleDC(NULL);
1560 old_bmp = SelectObject(ddb_dc, ddb);
1561 for (i = 0; i < width; i++)
1563 for (j=0; j < height; j++)
1565 BYTE c = (i * width + j) % 256;
1566 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1569 SelectObject(ddb_dc, old_bmp);
1571 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1572 info->bmiHeader.biWidth = width;
1573 info->bmiHeader.biHeight = height;
1574 info->bmiHeader.biPlanes = 1;
1575 info->bmiHeader.biBitCount = bpp;
1576 info->bmiHeader.biCompression = BI_RGB;
1578 dc = CreateCompatibleDC(NULL);
1580 /* Fill in biSizeImage */
1581 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1582 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1584 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1585 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1588 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1589 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1591 /* Copy the DIB attributes but not the color table */
1592 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1594 /* Select the DDB into another DC */
1595 old_bmp = SelectObject(ddb_dc, ddb);
1598 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1599 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1601 /* Compare the color table and the bits */
1604 for (i=0; i < (1u << bpp); i++)
1605 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1606 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1607 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1608 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1609 "color table entry %d differs (bpp %d)\n", i, bpp );
1612 ok( !memcmp( bits, bits2, info->bmiHeader.biSizeImage ), "bit mismatch (bpp %d)\n", bpp );
1614 /* Test the palette */
1615 if (info2->bmiHeader.biBitCount <= 8)
1617 WORD *colors = (WORD*)info2->bmiColors;
1619 /* Get the palette indices */
1620 res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1621 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1623 for (i = 0; i < (1 << info->bmiHeader.biBitCount); i++)
1624 ok( colors[i] == i, "%d: got %d (bpp %d)\n", i, colors[i], bpp );
1627 HeapFree(GetProcessHeap(), 0, bits2);
1628 HeapFree(GetProcessHeap(), 0, bits);
1631 SelectObject(ddb_dc, old_bmp);
1634 HeapFree(GetProcessHeap(), 0, info2);
1635 HeapFree(GetProcessHeap(), 0, info);
1638 static void test_GetDIBits(void)
1640 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1641 static const BYTE bmp_bits_1[16 * 2] =
1643 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1644 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1645 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1646 0xff,0xff, 0,0, 0xff,0xff, 0,0
1648 /* 4-bytes aligned 1-bit DIB data: 16x16 */
1649 static const BYTE dib_bits_1[16 * 4] =
1651 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1652 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1653 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1654 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1656 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1657 static const BYTE bmp_bits_24[16 * 16*3] =
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,
1683 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1684 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1685 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1686 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1687 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1688 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1689 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1690 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1692 /* 4-bytes aligned 24-bit DIB data: 16x16 */
1693 static const BYTE dib_bits_24[16 * 16*3] =
1695 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1696 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1697 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1698 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1699 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1700 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1701 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1702 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1703 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1704 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1705 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1706 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1707 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1708 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1709 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1710 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1711 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1712 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1713 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1714 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1715 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1716 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1717 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1718 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1719 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1720 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1721 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1722 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1723 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1724 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1725 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1726 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1731 int i, bytes, lines;
1733 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1734 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1735 PALETTEENTRY pal_ents[20];
1739 /* 1-bit source bitmap data */
1740 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1741 ok(hbmp != 0, "CreateBitmap failed\n");
1743 memset(&bm, 0xAA, sizeof(bm));
1744 bytes = GetObject(hbmp, sizeof(bm), &bm);
1745 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1746 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1747 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1748 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1749 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1750 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1751 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1752 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1754 bytes = GetBitmapBits(hbmp, 0, NULL);
1755 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1756 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1757 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1758 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1760 /* retrieve 1-bit DIB data */
1761 memset(bi, 0, sizeof(*bi));
1762 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1763 bi->bmiHeader.biWidth = bm.bmWidth;
1764 bi->bmiHeader.biHeight = bm.bmHeight;
1765 bi->bmiHeader.biPlanes = 1;
1766 bi->bmiHeader.biBitCount = 1;
1767 bi->bmiHeader.biCompression = BI_RGB;
1768 bi->bmiHeader.biSizeImage = 0;
1769 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1770 SetLastError(0xdeadbeef);
1771 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1772 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1773 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1774 broken(GetLastError() == 0xdeadbeef), /* winnt */
1775 "wrong error %u\n", GetLastError());
1776 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1778 memset(buf, 0xAA, sizeof(buf));
1779 SetLastError(0xdeadbeef);
1780 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1781 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1782 lines, bm.bmHeight, GetLastError());
1783 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1785 /* the color table consists of black and white */
1786 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1787 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1788 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1789 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1790 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1791 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1792 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1793 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1794 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1795 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1796 for (i = 2; i < 256; i++)
1798 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1799 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1800 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1801 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1802 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1805 /* returned bits are DWORD aligned and upside down */
1806 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1808 /* Test the palette indices */
1809 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1810 SetLastError(0xdeadbeef);
1811 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1812 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1813 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1814 for (i = 2; i < 256; i++)
1815 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[1]);
1817 /* retrieve 24-bit DIB data */
1818 memset(bi, 0, sizeof(*bi));
1819 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1820 bi->bmiHeader.biWidth = bm.bmWidth;
1821 bi->bmiHeader.biHeight = bm.bmHeight;
1822 bi->bmiHeader.biPlanes = 1;
1823 bi->bmiHeader.biBitCount = 24;
1824 bi->bmiHeader.biCompression = BI_RGB;
1825 bi->bmiHeader.biSizeImage = 0;
1826 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1827 memset(buf, 0xAA, sizeof(buf));
1828 SetLastError(0xdeadbeef);
1829 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1830 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1831 lines, bm.bmHeight, GetLastError());
1832 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1834 /* the color table doesn't exist for 24-bit images */
1835 for (i = 0; i < 256; i++)
1837 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1838 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1839 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1840 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1841 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1844 /* returned bits are DWORD aligned and upside down */
1845 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1848 /* 24-bit source bitmap data */
1849 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1850 ok(hbmp != 0, "CreateBitmap failed\n");
1851 SetLastError(0xdeadbeef);
1852 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1853 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1854 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1855 lines, bm.bmHeight, GetLastError());
1857 memset(&bm, 0xAA, sizeof(bm));
1858 bytes = GetObject(hbmp, sizeof(bm), &bm);
1859 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1860 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1861 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1862 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1863 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1864 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1865 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1866 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1868 bytes = GetBitmapBits(hbmp, 0, NULL);
1869 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
1870 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1871 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1872 bm.bmWidthBytes * bm.bmHeight, bytes);
1874 /* retrieve 1-bit DIB data */
1875 memset(bi, 0, sizeof(*bi));
1876 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1877 bi->bmiHeader.biWidth = bm.bmWidth;
1878 bi->bmiHeader.biHeight = bm.bmHeight;
1879 bi->bmiHeader.biPlanes = 1;
1880 bi->bmiHeader.biBitCount = 1;
1881 bi->bmiHeader.biCompression = BI_RGB;
1882 bi->bmiHeader.biSizeImage = 0;
1883 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1884 memset(buf, 0xAA, sizeof(buf));
1885 SetLastError(0xdeadbeef);
1886 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1887 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1888 lines, bm.bmHeight, GetLastError());
1889 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1891 /* the color table consists of black and white */
1892 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1893 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1894 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1895 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1896 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1897 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1898 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1899 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1900 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1901 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1902 for (i = 2; i < 256; i++)
1904 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1905 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1906 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1907 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1908 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1911 /* returned bits are DWORD aligned and upside down */
1912 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1914 /* Test the palette indices */
1915 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1916 SetLastError(0xdeadbeef);
1917 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1918 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1919 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1920 for (i = 2; i < 256; i++)
1921 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[i]);
1923 /* retrieve 4-bit DIB data */
1924 memset(bi, 0, sizeof(*bi));
1925 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1926 bi->bmiHeader.biWidth = bm.bmWidth;
1927 bi->bmiHeader.biHeight = bm.bmHeight;
1928 bi->bmiHeader.biPlanes = 1;
1929 bi->bmiHeader.biBitCount = 4;
1930 bi->bmiHeader.biCompression = BI_RGB;
1931 bi->bmiHeader.biSizeImage = 0;
1932 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1933 memset(buf, 0xAA, sizeof(buf));
1934 SetLastError(0xdeadbeef);
1935 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1936 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1937 lines, bm.bmHeight, GetLastError());
1939 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
1941 for (i = 0; i < 16; i++)
1944 int entry = i < 8 ? i : i + 4;
1946 if(entry == 7) entry = 12;
1947 else if(entry == 12) entry = 7;
1949 expect.rgbRed = pal_ents[entry].peRed;
1950 expect.rgbGreen = pal_ents[entry].peGreen;
1951 expect.rgbBlue = pal_ents[entry].peBlue;
1952 expect.rgbReserved = 0;
1954 ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
1955 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
1956 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
1957 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1958 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1961 /* retrieve 8-bit DIB data */
1962 memset(bi, 0, sizeof(*bi));
1963 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1964 bi->bmiHeader.biWidth = bm.bmWidth;
1965 bi->bmiHeader.biHeight = bm.bmHeight;
1966 bi->bmiHeader.biPlanes = 1;
1967 bi->bmiHeader.biBitCount = 8;
1968 bi->bmiHeader.biCompression = BI_RGB;
1969 bi->bmiHeader.biSizeImage = 0;
1970 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1971 memset(buf, 0xAA, sizeof(buf));
1972 SetLastError(0xdeadbeef);
1973 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1974 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1975 lines, bm.bmHeight, GetLastError());
1977 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
1979 for (i = 0; i < 256; i++)
1983 if (i < 10 || i >= 246)
1985 int entry = i < 10 ? i : i - 236;
1986 expect.rgbRed = pal_ents[entry].peRed;
1987 expect.rgbGreen = pal_ents[entry].peGreen;
1988 expect.rgbBlue = pal_ents[entry].peBlue;
1992 expect.rgbRed = (i & 0x07) << 5;
1993 expect.rgbGreen = (i & 0x38) << 2;
1994 expect.rgbBlue = i & 0xc0;
1996 expect.rgbReserved = 0;
1998 ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
1999 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2000 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2001 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
2002 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
2005 /* retrieve 24-bit DIB data */
2006 memset(bi, 0, sizeof(*bi));
2007 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2008 bi->bmiHeader.biWidth = bm.bmWidth;
2009 bi->bmiHeader.biHeight = bm.bmHeight;
2010 bi->bmiHeader.biPlanes = 1;
2011 bi->bmiHeader.biBitCount = 24;
2012 bi->bmiHeader.biCompression = BI_RGB;
2013 bi->bmiHeader.biSizeImage = 0;
2014 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
2015 memset(buf, 0xAA, sizeof(buf));
2016 SetLastError(0xdeadbeef);
2017 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2018 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2019 lines, bm.bmHeight, GetLastError());
2020 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2022 /* the color table doesn't exist for 24-bit images */
2023 for (i = 0; i < 256; i++)
2025 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
2026 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
2027 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2028 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
2029 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
2032 /* returned bits are DWORD aligned and upside down */
2033 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2039 static void test_GetDIBits_BI_BITFIELDS(void)
2041 /* Try a screen resolution detection technique
2042 * from the September 1999 issue of Windows Developer's Journal
2043 * which seems to be in widespread use.
2044 * http://www.lesher.ws/highcolor.html
2045 * http://www.lesher.ws/vidfmt.c
2046 * It hinges on being able to retrieve the bitmaps
2047 * for the three primary colors in non-paletted 16 bit mode.
2049 char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
2051 LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
2052 DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
2058 memset(dibinfo, 0, sizeof(dibinfo_buf));
2059 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2062 ok(hdc != NULL, "GetDC failed?\n");
2063 hbm = CreateCompatibleBitmap(hdc, 1, 1);
2064 ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
2066 /* Call GetDIBits to fill in bmiHeader. */
2067 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2068 ok(ret == 1, "GetDIBits failed\n");
2069 if (dibinfo->bmiHeader.biBitCount > 8)
2071 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2072 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2073 "compression is %u (%d bpp)\n", dibinfo->bmiHeader.biCompression, dibinfo->bmiHeader.biBitCount );
2075 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2077 ok( !bitmasks[0], "red mask is set\n" );
2078 ok( !bitmasks[1], "green mask is set\n" );
2079 ok( !bitmasks[2], "blue mask is set\n" );
2081 /* test with NULL bits pointer and correct bpp */
2082 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2083 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2084 ok(ret == 1, "GetDIBits failed\n");
2086 ok( bitmasks[0] != 0, "red mask is not set\n" );
2087 ok( bitmasks[1] != 0, "green mask is not set\n" );
2088 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2089 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2091 /* test with valid bits pointer */
2092 memset(dibinfo, 0, sizeof(dibinfo_buf));
2093 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2094 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2095 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2096 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2097 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2098 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2100 ok( bitmasks[0] != 0, "red mask is not set\n" );
2101 ok( bitmasks[1] != 0, "green mask is not set\n" );
2102 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2103 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2105 /* now with bits and 0 lines */
2106 memset(dibinfo, 0, sizeof(dibinfo_buf));
2107 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2108 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2109 SetLastError(0xdeadbeef);
2110 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2111 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2113 ok( !bitmasks[0], "red mask is set\n" );
2114 ok( !bitmasks[1], "green mask is set\n" );
2115 ok( !bitmasks[2], "blue mask is set\n" );
2116 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2118 memset(bitmasks, 0, 3*sizeof(DWORD));
2119 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2120 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2121 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2123 ok( bitmasks[0] != 0, "red mask is not set\n" );
2124 ok( bitmasks[1] != 0, "green mask is not set\n" );
2125 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2126 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2129 else skip("bitmap in colortable mode, skipping BI_BITFIELDS tests\n");
2133 /* same thing now with a 32-bpp DIB section */
2135 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2136 dibinfo->bmiHeader.biWidth = 1;
2137 dibinfo->bmiHeader.biHeight = 1;
2138 dibinfo->bmiHeader.biPlanes = 1;
2139 dibinfo->bmiHeader.biBitCount = 32;
2140 dibinfo->bmiHeader.biCompression = BI_RGB;
2141 dibinfo->bmiHeader.biSizeImage = 0;
2142 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2143 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2144 dibinfo->bmiHeader.biClrUsed = 0;
2145 dibinfo->bmiHeader.biClrImportant = 0;
2146 bitmasks[0] = 0x0000ff;
2147 bitmasks[1] = 0x00ff00;
2148 bitmasks[2] = 0xff0000;
2149 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2150 ok( hbm != 0, "failed to create bitmap\n" );
2152 memset(dibinfo, 0, sizeof(dibinfo_buf));
2153 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2154 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2155 ok(ret == 1, "GetDIBits failed\n");
2156 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2158 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2159 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2160 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2161 ok( !bitmasks[0], "red mask is set\n" );
2162 ok( !bitmasks[1], "green mask is set\n" );
2163 ok( !bitmasks[2], "blue mask is set\n" );
2165 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2166 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2167 ok(ret == 1, "GetDIBits failed\n");
2168 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2169 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2170 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2171 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2172 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2174 ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
2175 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2176 ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
2178 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2182 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2183 dibinfo->bmiHeader.biWidth = 1;
2184 dibinfo->bmiHeader.biHeight = 1;
2185 dibinfo->bmiHeader.biPlanes = 1;
2186 dibinfo->bmiHeader.biBitCount = 32;
2187 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2188 dibinfo->bmiHeader.biSizeImage = 0;
2189 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2190 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2191 dibinfo->bmiHeader.biClrUsed = 0;
2192 dibinfo->bmiHeader.biClrImportant = 0;
2193 bitmasks[0] = 0x0000ff;
2194 bitmasks[1] = 0x00ff00;
2195 bitmasks[2] = 0xff0000;
2196 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2197 ok( hbm != 0, "failed to create bitmap\n" );
2201 memset(dibinfo, 0, sizeof(dibinfo_buf));
2202 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2203 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2204 ok(ret == 1, "GetDIBits failed\n");
2206 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
2207 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2208 ok( !bitmasks[0], "red mask is set\n" );
2209 ok( !bitmasks[1], "green mask is set\n" );
2210 ok( !bitmasks[2], "blue mask is set\n" );
2212 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2213 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2214 ok(ret == 1, "GetDIBits failed\n");
2215 ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
2216 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2217 ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
2218 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2223 /* 24-bpp DIB sections don't have bitfields */
2225 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2226 dibinfo->bmiHeader.biWidth = 1;
2227 dibinfo->bmiHeader.biHeight = 1;
2228 dibinfo->bmiHeader.biPlanes = 1;
2229 dibinfo->bmiHeader.biBitCount = 24;
2230 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2231 dibinfo->bmiHeader.biSizeImage = 0;
2232 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2233 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2234 dibinfo->bmiHeader.biClrUsed = 0;
2235 dibinfo->bmiHeader.biClrImportant = 0;
2236 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2237 ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
2238 dibinfo->bmiHeader.biCompression = BI_RGB;
2239 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2240 ok( hbm != 0, "failed to create bitmap\n" );
2242 memset(dibinfo, 0, sizeof(dibinfo_buf));
2243 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2244 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2245 ok(ret == 1, "GetDIBits failed\n");
2246 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2248 ok( dibinfo->bmiHeader.biCompression == BI_RGB,
2249 "compression is %u\n", dibinfo->bmiHeader.biCompression );
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" );
2254 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2255 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2256 ok(ret == 1, "GetDIBits failed\n");
2257 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2258 ok( !bitmasks[0], "red mask is set\n" );
2259 ok( !bitmasks[1], "green mask is set\n" );
2260 ok( !bitmasks[2], "blue mask is set\n" );
2261 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2264 ReleaseDC(NULL, hdc);
2267 static void test_select_object(void)
2270 HBITMAP hbm, hbm_old;
2272 DWORD depths[] = {8, 15, 16, 24, 32};
2277 ok(hdc != 0, "GetDC(0) failed\n");
2278 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2279 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2281 hbm_old = SelectObject(hdc, hbm);
2282 ok(hbm_old == 0, "SelectObject should fail\n");
2287 hdc = CreateCompatibleDC(0);
2288 ok(hdc != 0, "GetDC(0) failed\n");
2289 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2290 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2292 hbm_old = SelectObject(hdc, hbm);
2293 ok(hbm_old != 0, "SelectObject failed\n");
2294 hbm_old = SelectObject(hdc, hbm_old);
2295 ok(hbm_old == hbm, "SelectObject failed\n");
2299 /* test an 1-bpp bitmap */
2300 planes = GetDeviceCaps(hdc, PLANES);
2303 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
2304 ok(hbm != 0, "CreateBitmap failed\n");
2306 hbm_old = SelectObject(hdc, hbm);
2307 ok(hbm_old != 0, "SelectObject failed\n");
2308 hbm_old = SelectObject(hdc, hbm_old);
2309 ok(hbm_old == hbm, "SelectObject failed\n");
2313 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
2314 /* test a color bitmap to dc bpp matching */
2315 planes = GetDeviceCaps(hdc, PLANES);
2316 bpp = GetDeviceCaps(hdc, BITSPIXEL);
2318 hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
2319 ok(hbm != 0, "CreateBitmap failed\n");
2321 hbm_old = SelectObject(hdc, hbm);
2322 if(depths[i] == bpp ||
2323 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
2325 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
2326 SelectObject(hdc, hbm_old);
2328 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
2331 memset(&bm, 0xAA, sizeof(bm));
2332 bytes = GetObject(hbm, sizeof(bm), &bm);
2333 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2334 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2335 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
2336 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
2337 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2338 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
2339 if(depths[i] == 15) {
2340 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
2342 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2344 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2352 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
2357 ret = GetObjectType(hbmp);
2358 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
2360 ret = GetObject(hbmp, 0, 0);
2361 ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
2363 memset(&bm, 0xDA, sizeof(bm));
2364 SetLastError(0xdeadbeef);
2365 ret = GetObject(hbmp, sizeof(bm), &bm);
2366 if (!ret) /* XP, only for curObj2 */ return;
2367 ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
2368 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2369 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2370 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2371 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2372 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2373 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2374 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2377 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2379 static void test_CreateBitmap(void)
2382 HDC screenDC = GetDC(0);
2383 HDC hdc = CreateCompatibleDC(screenDC);
2386 /* all of these are the stock monochrome bitmap */
2387 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2388 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2389 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2390 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2391 HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2392 HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2394 /* these 2 are not the stock monochrome bitmap */
2395 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2396 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2398 HBITMAP old1 = SelectObject(hdc, bm2);
2399 HBITMAP old2 = SelectObject(screenDC, bm3);
2400 SelectObject(hdc, old1);
2401 SelectObject(screenDC, old2);
2403 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2404 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2405 bm, bm1, bm4, bm5, curObj1, old1);
2406 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2408 ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
2409 ok(old2 == 0, "old2 %p\n", old2);
2411 test_mono_1x1_bmp(bm);
2412 test_mono_1x1_bmp(bm1);
2413 test_mono_1x1_bmp(bm2);
2414 test_mono_1x1_bmp(bm3);
2415 test_mono_1x1_bmp(bm4);
2416 test_mono_1x1_bmp(bm5);
2417 test_mono_1x1_bmp(old1);
2418 test_mono_1x1_bmp(curObj1);
2428 ReleaseDC(0, screenDC);
2430 /* show that Windows ignores the provided bm.bmWidthBytes */
2434 bmp.bmWidthBytes = 28;
2436 bmp.bmBitsPixel = 1;
2438 bm = CreateBitmapIndirect(&bmp);
2439 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2440 test_mono_1x1_bmp(bm);
2443 /* Test how the bmBitsPixel field is treated */
2444 for(i = 1; i <= 33; i++) {
2448 bmp.bmWidthBytes = 28;
2450 bmp.bmBitsPixel = i;
2452 SetLastError(0xdeadbeef);
2453 bm = CreateBitmapIndirect(&bmp);
2455 DWORD error = GetLastError();
2456 ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
2457 ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2461 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2462 GetObject(bm, sizeof(bmp), &bmp);
2469 } else if(i <= 16) {
2471 } else if(i <= 24) {
2473 } else if(i <= 32) {
2476 ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2477 i, bmp.bmBitsPixel, expect);
2482 static void test_bitmapinfoheadersize(void)
2489 memset(&bmi, 0, sizeof(BITMAPINFO));
2490 bmi.bmiHeader.biHeight = 100;
2491 bmi.bmiHeader.biWidth = 512;
2492 bmi.bmiHeader.biBitCount = 24;
2493 bmi.bmiHeader.biPlanes = 1;
2495 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2497 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2498 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2500 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2502 SetLastError(0xdeadbeef);
2503 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2504 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2507 bmi.bmiHeader.biSize++;
2509 SetLastError(0xdeadbeef);
2510 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2512 broken(!hdib), /* Win98, WinMe */
2513 "CreateDIBSection error %d\n", GetLastError());
2516 bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2518 SetLastError(0xdeadbeef);
2519 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2521 broken(!hdib), /* Win98, WinMe */
2522 "CreateDIBSection error %d\n", GetLastError());
2525 bmi.bmiHeader.biSize++;
2527 SetLastError(0xdeadbeef);
2528 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2530 broken(!hdib), /* Win98, WinMe */
2531 "CreateDIBSection error %d\n", GetLastError());
2534 bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2536 SetLastError(0xdeadbeef);
2537 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2538 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2541 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2543 SetLastError(0xdeadbeef);
2544 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2546 broken(!hdib), /* Win95 */
2547 "CreateDIBSection error %d\n", GetLastError());
2550 memset(&bci, 0, sizeof(BITMAPCOREINFO));
2551 bci.bmciHeader.bcHeight = 100;
2552 bci.bmciHeader.bcWidth = 512;
2553 bci.bmciHeader.bcBitCount = 24;
2554 bci.bmciHeader.bcPlanes = 1;
2556 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2558 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2559 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2561 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2563 SetLastError(0xdeadbeef);
2564 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2565 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2568 bci.bmciHeader.bcSize++;
2570 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2571 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2573 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2575 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2576 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2581 static void test_get16dibits(void)
2583 BYTE bits[4 * (16 / sizeof(BYTE))];
2585 HDC screen_dc = GetDC(NULL);
2588 int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2590 int overwritten_bytes = 0;
2592 memset(bits, 0, sizeof(bits));
2593 hbmp = CreateBitmap(2, 2, 1, 16, bits);
2594 ok(hbmp != NULL, "CreateBitmap failed\n");
2596 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2599 memset(info, '!', info_len);
2600 memset(info, 0, sizeof(info->bmiHeader));
2602 info->bmiHeader.biSize = sizeof(info->bmiHeader);
2603 info->bmiHeader.biWidth = 2;
2604 info->bmiHeader.biHeight = 2;
2605 info->bmiHeader.biPlanes = 1;
2606 info->bmiHeader.biCompression = BI_RGB;
2608 ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2609 ok(ret != 0, "GetDIBits failed got %d\n", ret);
2611 for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2613 overwritten_bytes++;
2614 ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2616 HeapFree(GetProcessHeap(), 0, info);
2618 ReleaseDC(NULL, screen_dc);
2621 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2622 DWORD dwRop, UINT32 expected, int line)
2624 *srcBuffer = 0xFEDCBA98;
2625 *dstBuffer = 0x89ABCDEF;
2626 Rectangle(hdcSrc, 0, 0, 1, 1); /* A null operation to ensure dibs are coerced to X11 */
2627 BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
2628 ok(expected == *dstBuffer,
2629 "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2630 dwRop, expected, *dstBuffer, line);
2633 static void test_BitBlt(void)
2635 HBITMAP bmpDst, bmpSrc;
2636 HBITMAP oldDst, oldSrc;
2637 HDC hdcScreen, hdcDst, hdcSrc;
2638 UINT32 *dstBuffer, *srcBuffer;
2639 HBRUSH hBrush, hOldBrush;
2640 BITMAPINFO bitmapInfo;
2642 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2643 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2644 bitmapInfo.bmiHeader.biWidth = 1;
2645 bitmapInfo.bmiHeader.biHeight = 1;
2646 bitmapInfo.bmiHeader.biPlanes = 1;
2647 bitmapInfo.bmiHeader.biBitCount = 32;
2648 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2649 bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2651 hdcScreen = CreateCompatibleDC(0);
2652 hdcDst = CreateCompatibleDC(hdcScreen);
2653 hdcSrc = CreateCompatibleDC(hdcDst);
2655 /* Setup the destination dib section */
2656 bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
2658 oldDst = SelectObject(hdcDst, bmpDst);
2660 hBrush = CreateSolidBrush(0x012345678);
2661 hOldBrush = SelectObject(hdcDst, hBrush);
2663 /* Setup the source dib section */
2664 bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
2666 oldSrc = SelectObject(hdcSrc, bmpSrc);
2668 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2669 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2670 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2671 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2672 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2673 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2674 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2675 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2676 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2677 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2678 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2679 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2680 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2681 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2682 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2685 SelectObject(hdcSrc, oldSrc);
2686 DeleteObject(bmpSrc);
2689 SelectObject(hdcDst, hOldBrush);
2690 DeleteObject(hBrush);
2691 SelectObject(hdcDst, oldDst);
2692 DeleteObject(bmpDst);
2696 DeleteDC(hdcScreen);
2699 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2700 DWORD dwRop, UINT32 expected, int line)
2702 *srcBuffer = 0xFEDCBA98;
2703 *dstBuffer = 0x89ABCDEF;
2704 StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
2705 ok(expected == *dstBuffer,
2706 "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2707 dwRop, expected, *dstBuffer, line);
2710 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, BITMAPINFO *dst_info, UINT32 *dstBuffer, UINT32 *srcBuffer,
2711 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2712 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2713 UINT32 *expected, int line)
2715 int dst_size = get_dib_image_size( dst_info );
2717 memset(dstBuffer, 0, dst_size);
2718 StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2719 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
2720 ok(memcmp(dstBuffer, expected, dst_size) == 0,
2721 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2722 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2723 expected[0], expected[1], expected[2], expected[3],
2724 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2725 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2726 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2729 static void test_StretchBlt(void)
2731 HBITMAP bmpDst, bmpSrc;
2732 HBITMAP oldDst, oldSrc;
2733 HDC hdcScreen, hdcDst, hdcSrc;
2734 UINT32 *dstBuffer, *srcBuffer;
2735 HBRUSH hBrush, hOldBrush;
2736 BITMAPINFO biDst, biSrc;
2737 UINT32 expected[256];
2740 memset(&biDst, 0, sizeof(BITMAPINFO));
2741 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2742 biDst.bmiHeader.biWidth = 16;
2743 biDst.bmiHeader.biHeight = -16;
2744 biDst.bmiHeader.biPlanes = 1;
2745 biDst.bmiHeader.biBitCount = 32;
2746 biDst.bmiHeader.biCompression = BI_RGB;
2747 memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
2749 hdcScreen = CreateCompatibleDC(0);
2750 hdcDst = CreateCompatibleDC(hdcScreen);
2751 hdcSrc = CreateCompatibleDC(hdcDst);
2754 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2756 oldDst = SelectObject(hdcDst, bmpDst);
2758 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2760 oldSrc = SelectObject(hdcSrc, bmpSrc);
2762 hBrush = CreateSolidBrush(0x012345678);
2763 hOldBrush = SelectObject(hdcDst, hBrush);
2765 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2766 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2767 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2768 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2769 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2770 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2771 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2772 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2773 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2774 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2775 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2776 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2777 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2778 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2779 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2781 SelectObject(hdcDst, hOldBrush);
2782 DeleteObject(hBrush);
2784 /* Top-down to top-down tests */
2785 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2786 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2788 memset( expected, 0, get_dib_image_size( &biDst ) );
2789 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2790 expected[16] = 0xFEDCBA98, expected[17] = 0x76543210;
2791 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2792 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2794 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2795 expected[16] = 0x00000000, expected[17] = 0x00000000;
2796 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2797 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
2799 expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
2800 expected[16] = 0xCAFED00D, expected[17] = 0xCAFED00D;
2801 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2802 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
2804 /* This is an example of the dst width (height) == 1 exception, explored below */
2805 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2806 expected[16] = 0x00000000, expected[17] = 0x00000000;
2807 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2808 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
2810 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2811 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
2812 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2813 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2815 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2816 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
2817 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2818 1, 1, -2, -2, 0, 0, 2, 2, expected, __LINE__);
2820 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2821 expected[16] = 0x00000000, expected[17] = 0x00000000;
2822 todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2823 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
2825 expected[0] = 0x00000000, expected[1] = 0x00000000;
2826 expected[16] = 0x00000000, expected[17] = 0xCAFED00D, expected[18] = 0xFEEDFACE;
2827 expected[32] = 0x00000000, expected[33] = 0xFEDCBA98, expected[34] = 0x76543210;
2829 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2830 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2832 /* when dst width is 1 merge src width - 1 pixels */
2833 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
2834 srcBuffer[0] = 0x0000ff00, srcBuffer[1] = 0x0000f0f0, srcBuffer[2] = 0x0000cccc, srcBuffer[3] = 0x0000aaaa;
2835 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2837 memset( expected, 0, get_dib_image_size( &biDst ) );
2838 expected[0] = srcBuffer[0];
2839 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2840 0, 0, 1, 1, 0, 0, 2, 1, expected, __LINE__);
2842 expected[0] = srcBuffer[0] & srcBuffer[1];
2843 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2844 0, 0, 1, 1, 0, 0, 3, 1, expected, __LINE__);
2846 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
2847 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2848 0, 0, 1, 1, 0, 0, 4, 1, expected, __LINE__);
2850 /* this doesn't happen if the src width is -ve */
2851 expected[0] = srcBuffer[1] & srcBuffer[2];
2852 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2853 0, 0, 1, 1, 2, 0, -2, 1, expected, __LINE__);
2855 /* when dst width > 1 behaviour reverts to what one would expect */
2856 expected[0] = srcBuffer[0] & srcBuffer[1], expected[1] = srcBuffer[2] & srcBuffer[3];
2857 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2858 0, 0, 2, 1, 0, 0, 4, 1, expected, __LINE__);
2860 /* similarly in the vertical direction */
2861 memset( expected, 0, get_dib_image_size( &biDst ) );
2862 expected[0] = srcBuffer[0];
2863 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2864 0, 0, 1, 1, 0, 0, 1, 2, expected, __LINE__);
2866 /* check that it's the dst size in device units that needs to be 1 */
2867 SetMapMode( hdcDst, MM_ISOTROPIC );
2868 SetWindowExtEx( hdcDst, 200, 200, NULL );
2869 SetViewportExtEx( hdcDst, 100, 100, NULL );
2871 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
2872 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2873 0, 0, 2, 2, 0, 0, 4, 1, expected, __LINE__);
2874 SetMapMode( hdcDst, MM_TEXT );
2876 SelectObject(hdcDst, oldDst);
2877 DeleteObject(bmpDst);
2879 /* Top-down to bottom-up tests */
2880 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
2881 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2882 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2884 biDst.bmiHeader.biHeight = 16;
2885 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2887 oldDst = SelectObject(hdcDst, bmpDst);
2889 memset( expected, 0, get_dib_image_size( &biDst ) );
2891 expected[224] = 0xFEDCBA98, expected[225] = 0x76543210;
2892 expected[240] = 0xCAFED00D, expected[241] = 0xFEEDFACE;
2893 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2894 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2896 expected[224] = 0xFEEDFACE, expected[225] = 0xCAFED00D;
2897 expected[240] = 0x76543210, expected[241] = 0xFEDCBA98;
2898 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2899 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2901 SelectObject(hdcSrc, oldSrc);
2902 DeleteObject(bmpSrc);
2904 /* Bottom-up to bottom-up tests */
2905 biSrc.bmiHeader.biHeight = 16;
2906 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2908 srcBuffer[224] = 0xCAFED00D, srcBuffer[225] = 0xFEEDFACE;
2909 srcBuffer[240] = 0xFEDCBA98, srcBuffer[241] = 0x76543210;
2910 oldSrc = SelectObject(hdcSrc, bmpSrc);
2912 memset( expected, 0, get_dib_image_size( &biDst ) );
2914 expected[224] = 0xCAFED00D, expected[225] = 0xFEEDFACE;
2915 expected[240] = 0xFEDCBA98, expected[241] = 0x76543210;
2916 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2917 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2919 expected[224] = 0x76543210, expected[225] = 0xFEDCBA98;
2920 expected[240] = 0xFEEDFACE, expected[241] = 0xCAFED00D;
2921 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2922 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2924 SelectObject(hdcDst, oldDst);
2925 DeleteObject(bmpDst);
2927 /* Bottom-up to top-down tests */
2928 biDst.bmiHeader.biHeight = -16;
2929 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2931 oldDst = SelectObject(hdcDst, bmpDst);
2933 memset( expected, 0, get_dib_image_size( &biDst ) );
2934 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2935 expected[16] = 0xCAFED00D, expected[17] = 0xFEEDFACE;
2936 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2937 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2939 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2940 expected[16] = 0x76543210, expected[17] = 0xFEDCBA98;
2941 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2942 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2944 SelectObject(hdcSrc, oldSrc);
2945 DeleteObject(bmpSrc);
2947 biSrc.bmiHeader.biHeight = -2;
2948 biSrc.bmiHeader.biBitCount = 24;
2949 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
2950 oldSrc = SelectObject(hdcSrc, bmpSrc);
2952 memset( expected, 0, get_dib_image_size( &biDst ) );
2953 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2954 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2955 memcpy(dstBuffer, expected, 4 * sizeof(*dstBuffer));
2956 StretchBlt(hdcSrc, 0, 0, 4, 1, hdcDst, 0, 0, 4, 1, SRCCOPY );
2957 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
2958 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
2959 expected[0] = 0x00EDFACE, expected[1] = 0x00FED00D;
2960 expected[2] = 0x00543210, expected[3] = 0x00DCBA98;
2961 ok(!memcmp(dstBuffer, expected, 16),
2962 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
2963 expected[0], expected[1], expected[2], expected[3],
2964 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
2966 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2967 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2968 memcpy(srcBuffer, expected, 4 * sizeof(*dstBuffer));
2969 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
2970 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
2971 expected[0] = 0x00EDFACE, expected[1] = 0x00D00DFE;
2972 expected[2] = 0x0010CAFE, expected[3] = 0x00765432;
2973 ok(!memcmp(dstBuffer, expected, 16),
2974 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
2975 expected[0], expected[1], expected[2], expected[3],
2976 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
2978 SelectObject(hdcSrc, oldSrc);
2979 DeleteObject(bmpSrc);
2981 biSrc.bmiHeader.biBitCount = 1;
2982 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
2983 oldSrc = SelectObject(hdcSrc, bmpSrc);
2984 *((DWORD *)colors + 0) = 0x123456;
2985 *((DWORD *)colors + 1) = 0x335577;
2986 SetDIBColorTable( hdcSrc, 0, 2, colors );
2987 srcBuffer[0] = 0x55555555;
2988 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
2989 SetTextColor( hdcDst, 0 );
2990 SetBkColor( hdcDst, 0 );
2991 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
2992 expected[0] = expected[2] = 0x00123456;
2993 expected[1] = expected[3] = 0x00335577;
2994 ok(!memcmp(dstBuffer, expected, 16),
2995 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
2996 expected[0], expected[1], expected[2], expected[3],
2997 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
2999 SelectObject(hdcSrc, oldSrc);
3000 DeleteObject(bmpSrc);
3002 bmpSrc = CreateBitmap( 16, 16, 1, 1, 0 );
3003 oldSrc = SelectObject(hdcSrc, bmpSrc);
3004 SetPixel( hdcSrc, 0, 0, 0 );
3005 SetPixel( hdcSrc, 1, 0, 0xffffff );
3006 SetPixel( hdcSrc, 2, 0, 0xffffff );
3007 SetPixel( hdcSrc, 3, 0, 0 );
3008 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
3009 SetTextColor( hdcDst, RGB(0x22,0x44,0x66) );
3010 SetBkColor( hdcDst, RGB(0x65,0x43,0x21) );
3011 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3012 expected[0] = expected[3] = 0x00224466;
3013 expected[1] = expected[2] = 0x00654321;
3014 ok(!memcmp(dstBuffer, expected, 16),
3015 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3016 expected[0], expected[1], expected[2], expected[3],
3017 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3019 SelectObject(hdcSrc, oldSrc);
3020 DeleteObject(bmpSrc);
3024 SelectObject(hdcDst, oldDst);
3025 DeleteObject(bmpDst);
3028 DeleteDC(hdcScreen);
3031 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3032 DWORD dwRop, UINT32 expected, int line)
3034 const UINT32 buffer[2] = { 0xFEDCBA98, 0 };
3035 BITMAPINFO bitmapInfo;
3037 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3038 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3039 bitmapInfo.bmiHeader.biWidth = 2;
3040 bitmapInfo.bmiHeader.biHeight = 1;
3041 bitmapInfo.bmiHeader.biPlanes = 1;
3042 bitmapInfo.bmiHeader.biBitCount = 32;
3043 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3044 bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer);
3046 *dstBuffer = 0x89ABCDEF;
3048 StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop);
3049 ok(expected == *dstBuffer,
3050 "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
3051 dwRop, expected, *dstBuffer, line);
3054 static void check_StretchDIBits_stretch(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3055 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
3056 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
3057 UINT32 expected[4], UINT32 legacy_expected[4], int line)
3059 BITMAPINFO bitmapInfo;
3061 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3062 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3063 bitmapInfo.bmiHeader.biWidth = 2;
3064 bitmapInfo.bmiHeader.biHeight = -2;
3065 bitmapInfo.bmiHeader.biPlanes = 1;
3066 bitmapInfo.bmiHeader.biBitCount = 32;
3067 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3069 memset(dstBuffer, 0, 16);
3070 StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
3071 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3072 srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
3073 ok(memcmp(dstBuffer, expected, 16) == 0,
3074 "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
3075 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
3076 expected[0], expected[1], expected[2], expected[3],
3077 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
3078 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3079 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
3082 static void test_StretchDIBits(void)
3086 HDC hdcScreen, hdcDst;
3087 UINT32 *dstBuffer, srcBuffer[4];
3088 HBRUSH hBrush, hOldBrush;
3090 UINT32 expected[4], legacy_expected[4];
3092 memset(&biDst, 0, sizeof(BITMAPINFO));
3093 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3094 biDst.bmiHeader.biWidth = 2;
3095 biDst.bmiHeader.biHeight = -2;
3096 biDst.bmiHeader.biPlanes = 1;
3097 biDst.bmiHeader.biBitCount = 32;
3098 biDst.bmiHeader.biCompression = BI_RGB;
3100 hdcScreen = CreateCompatibleDC(0);
3101 hdcDst = CreateCompatibleDC(hdcScreen);
3104 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3106 oldDst = SelectObject(hdcDst, bmpDst);
3108 hBrush = CreateSolidBrush(0x012345678);
3109 hOldBrush = SelectObject(hdcDst, hBrush);
3111 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3112 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3113 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3114 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3115 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3116 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3117 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3118 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3119 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3120 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3121 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3122 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3123 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3124 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3125 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3127 SelectObject(hdcDst, hOldBrush);
3128 DeleteObject(hBrush);
3130 /* Top-down destination tests */
3131 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3132 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
3134 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
3135 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
3136 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3137 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
3139 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3140 expected[2] = 0x00000000, expected[3] = 0x00000000;
3141 legacy_expected[0] = 0xFEDCBA98, legacy_expected[1] = 0x00000000;
3142 legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
3143 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3144 0, 0, 1, 1, 0, 0, 1, 1, expected, legacy_expected, __LINE__);
3146 expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
3147 expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
3148 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3149 0, 0, 2, 2, 0, 0, 1, 1, expected, expected, __LINE__);
3151 expected[0] = 0x42441000, expected[1] = 0x00000000;
3152 expected[2] = 0x00000000, expected[3] = 0x00000000;
3153 legacy_expected[0] = 0x00543210, legacy_expected[1] = 0x00000000;
3154 legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
3155 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3156 0, 0, 1, 1, 0, 0, 2, 2, expected, legacy_expected, __LINE__);
3158 expected[0] = 0x00000000, expected[1] = 0x00000000;
3159 expected[2] = 0x00000000, expected[3] = 0x00000000;
3160 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3161 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
3163 expected[0] = 0x00000000, expected[1] = 0x00000000;
3164 expected[2] = 0x00000000, expected[3] = 0x00000000;
3165 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3166 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
3168 expected[0] = 0x00000000, expected[1] = 0x00000000;
3169 expected[2] = 0x00000000, expected[3] = 0x00000000;
3170 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3171 1, 1, -2, -2, 1, 1, -2, -2, expected, expected, __LINE__);
3173 expected[0] = 0x00000000, expected[1] = 0x00000000;
3174 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
3175 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3176 1, 1, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
3178 SelectObject(hdcDst, oldDst);
3179 DeleteObject(bmpDst);
3181 /* Bottom up destination tests */
3182 biDst.bmiHeader.biHeight = 2;
3183 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3185 oldDst = SelectObject(hdcDst, bmpDst);
3187 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3188 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
3189 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3190 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
3193 SelectObject(hdcDst, oldDst);
3194 DeleteObject(bmpDst);
3197 DeleteDC(hdcScreen);
3200 static void test_GdiAlphaBlend(void)
3212 BLENDFUNCTION blend;
3214 if (!pGdiAlphaBlend)
3216 win_skip("GdiAlphaBlend() is not implemented\n");
3220 hdcNull = GetDC(NULL);
3221 hdcDst = CreateCompatibleDC(hdcNull);
3222 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
3223 hdcSrc = CreateCompatibleDC(hdcNull);
3225 bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3226 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3227 bmi->bmiHeader.biHeight = 20;
3228 bmi->bmiHeader.biWidth = 20;
3229 bmi->bmiHeader.biBitCount = 32;
3230 bmi->bmiHeader.biPlanes = 1;
3231 bmi->bmiHeader.biCompression = BI_RGB;
3232 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3233 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3235 oldDst = SelectObject(hdcDst, bmpDst);
3236 oldSrc = SelectObject(hdcSrc, bmpSrc);
3238 blend.BlendOp = AC_SRC_OVER;
3239 blend.BlendFlags = 0;
3240 blend.SourceConstantAlpha = 128;
3241 blend.AlphaFormat = 0;
3243 SetLastError(0xdeadbeef);
3244 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3245 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3247 SetLastError(0xdeadbeef);
3248 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3249 ok( !ret, "GdiAlphaBlend succeeded\n" );
3250 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3252 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3253 ok( !ret, "GdiAlphaBlend succeeded\n" );
3254 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend);
3255 ok( !ret, "GdiAlphaBlend succeeded\n" );
3256 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3257 ok( !ret, "GdiAlphaBlend succeeded\n" );
3258 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3259 ok( !ret, "GdiAlphaBlend succeeded\n" );
3261 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
3262 SetLastError(0xdeadbeef);
3263 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3264 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3265 SetLastError(0xdeadbeef);
3266 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3267 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3268 SetMapMode(hdcSrc, MM_ANISOTROPIC);
3269 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
3270 SetLastError(0xdeadbeef);
3271 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend);
3272 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3273 SetLastError(0xdeadbeef);
3274 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend);
3275 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3277 SetLastError(0xdeadbeef);
3278 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend);
3279 ok( !ret, "GdiAlphaBlend succeeded\n" );
3280 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3282 /* overlapping source and dest not allowed */
3284 SetLastError(0xdeadbeef);
3285 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 19, 19, 20, 20, blend);
3286 ok( !ret, "GdiAlphaBlend succeeded\n" );
3287 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3289 SetLastError(0xdeadbeef);
3290 ret = pGdiAlphaBlend(hdcDst, 20, 20, 20, 20, hdcDst, 1, 1, 20, 20, blend);
3291 ok( !ret, "GdiAlphaBlend succeeded\n" );
3292 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3294 SetLastError(0xdeadbeef);
3295 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 20, 10, 20, 20, blend);
3296 ok( ret, "GdiAlphaBlend succeeded\n" );
3297 SetLastError(0xdeadbeef);
3298 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 10, 20, 20, 20, blend);
3299 ok( ret, "GdiAlphaBlend succeeded\n" );
3301 /* AC_SRC_ALPHA requires 32-bpp BI_RGB format */
3303 blend.AlphaFormat = AC_SRC_ALPHA;
3304 SetLastError(0xdeadbeef);
3305 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3306 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3308 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3309 ((DWORD *)bmi->bmiColors)[0] = 0xff0000;
3310 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3311 ((DWORD *)bmi->bmiColors)[2] = 0x0000ff;
3312 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3313 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3314 oldSrc = SelectObject(hdcSrc, bmpSrc);
3315 DeleteObject( oldSrc );
3317 SetLastError(0xdeadbeef);
3318 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3319 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3321 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3322 ((DWORD *)bmi->bmiColors)[0] = 0x0000ff;
3323 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3324 ((DWORD *)bmi->bmiColors)[2] = 0xff0000;
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 = 24;
3336 bmi->bmiHeader.biCompression = BI_RGB;
3337 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3338 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3339 oldSrc = SelectObject(hdcSrc, bmpSrc);
3340 DeleteObject( oldSrc );
3342 SetLastError(0xdeadbeef);
3343 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3344 ok( !ret, "GdiAlphaBlend succeeded\n" );
3345 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3347 bmi->bmiHeader.biBitCount = 1;
3348 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3349 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3350 oldSrc = SelectObject(hdcSrc, bmpSrc);
3351 DeleteObject( oldSrc );
3353 SetLastError(0xdeadbeef);
3354 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3355 ok( !ret, "GdiAlphaBlend succeeded\n" );
3356 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3358 bmpSrc = CreateBitmap( 100, 100, 1, 1, NULL );
3359 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3360 oldSrc = SelectObject(hdcSrc, bmpSrc);
3361 DeleteObject( oldSrc );
3363 SetLastError(0xdeadbeef);
3364 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3365 ok( !ret, "GdiAlphaBlend succeeded\n" );
3366 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3368 SelectObject(hdcDst, oldDst);
3369 SelectObject(hdcSrc, oldSrc);
3370 DeleteObject(bmpSrc);
3371 DeleteObject(bmpDst);
3375 ReleaseDC(NULL, hdcNull);
3379 static void test_clipping(void)
3387 HDC hdcDst = CreateCompatibleDC( NULL );
3388 HDC hdcSrc = CreateCompatibleDC( NULL );
3390 BITMAPINFO bmpinfo={{0}};
3391 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3392 bmpinfo.bmiHeader.biWidth = 100;
3393 bmpinfo.bmiHeader.biHeight = 100;
3394 bmpinfo.bmiHeader.biPlanes = 1;
3395 bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3396 bmpinfo.bmiHeader.biCompression = BI_RGB;
3398 bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3399 ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3400 SelectObject( hdcDst, bmpDst );
3402 bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3403 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3404 SelectObject( hdcSrc, bmpSrc );
3406 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3407 ok(result, "BitBlt failed\n");
3409 hRgn = CreateRectRgn( 0,0,0,0 );
3410 SelectClipRgn( hdcDst, hRgn );
3412 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3413 ok(result, "BitBlt failed\n");
3415 DeleteObject( bmpDst );
3416 DeleteObject( bmpSrc );
3417 DeleteObject( hRgn );
3422 static void test_32bit_bitmap_blt(void)
3425 HBITMAP bmpSrc, bmpDst;
3426 HBITMAP oldSrc, oldDst;
3427 HDC hdcSrc, hdcDst, hdcScreen;
3429 DWORD colorSrc = 0x11223344;
3431 memset(&biDst, 0, sizeof(BITMAPINFO));
3432 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3433 biDst.bmiHeader.biWidth = 2;
3434 biDst.bmiHeader.biHeight = -2;
3435 biDst.bmiHeader.biPlanes = 1;
3436 biDst.bmiHeader.biBitCount = 32;
3437 biDst.bmiHeader.biCompression = BI_RGB;
3439 hdcScreen = CreateCompatibleDC(0);
3440 if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3442 DeleteDC(hdcScreen);
3443 trace("Skipping 32-bit DDB test\n");
3447 hdcSrc = CreateCompatibleDC(hdcScreen);
3448 bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3449 oldSrc = SelectObject(hdcSrc, bmpSrc);
3451 hdcDst = CreateCompatibleDC(hdcScreen);
3452 bmpDst = CreateDIBSection(hdcDst, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3453 oldDst = SelectObject(hdcDst, bmpDst);
3455 StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3456 ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3459 SelectObject(hdcDst, oldDst);
3460 DeleteObject(bmpDst);
3463 SelectObject(hdcSrc, oldSrc);
3464 DeleteObject(bmpSrc);
3467 DeleteDC(hdcScreen);
3471 * Used by test_GetDIBits_top_down to create the bitmap to test against.
3473 static void setup_picture(char *picture, int bpp)
3481 /*Set the first byte in each pixel to the index of that pixel.*/
3482 for (i = 0; i < 4; i++)
3483 picture[i * (bpp / 8)] = i;
3488 /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
3495 static void test_GetDIBits_top_down(int bpp)
3498 HBITMAP bmptb, bmpbt;
3504 memset( &bi, 0, sizeof(bi) );
3505 bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
3506 bi.bmiHeader.biWidth=2;
3507 bi.bmiHeader.biHeight=2;
3508 bi.bmiHeader.biPlanes=1;
3509 bi.bmiHeader.biBitCount=bpp;
3510 bi.bmiHeader.biCompression=BI_RGB;
3512 /*Get the device context for the screen.*/
3514 ok(hdc != NULL, "Could not get a handle to a device context.\n");
3516 /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
3517 bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3518 ok(bmpbt != NULL, "Could not create a DIB section.\n");
3519 /*Now that we have a pointer to the pixels, we write to them.*/
3520 setup_picture((char*)picture, bpp);
3521 /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
3522 bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
3523 bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3524 ok(bmptb != NULL, "Could not create a DIB section.\n");
3525 /*Write to this top to bottom bitmap.*/
3526 setup_picture((char*)picture, bpp);
3528 bi.bmiHeader.biWidth = 1;
3530 bi.bmiHeader.biHeight = 2;
3531 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3532 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3533 /*Check the first byte of the pixel.*/
3534 ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3535 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3536 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3537 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3538 /*Check second scanline.*/
3539 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3540 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3541 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3542 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3543 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3544 ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3545 /*Check both scanlines.*/
3546 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3547 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3548 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3549 ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3550 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3551 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3552 ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3553 ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3555 /*Make destination bitmap top-down.*/
3556 bi.bmiHeader.biHeight = -2;
3557 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3558 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3559 ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3560 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3561 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3562 ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3563 /*Check second scanline.*/
3564 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3565 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3566 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3567 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3568 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3569 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3570 /*Check both scanlines.*/
3571 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3572 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3573 ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3574 ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3575 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3576 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3577 ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3578 ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3580 DeleteObject(bmpbt);
3581 DeleteObject(bmptb);
3584 static void test_GetSetDIBits_rtl(void)
3587 HBITMAP bitmap, orig_bitmap;
3590 DWORD bits_1[8 * 8], bits_2[8 * 8];
3594 win_skip("Don't have SetLayout\n");
3598 hdc = GetDC( NULL );
3599 hdc_mem = CreateCompatibleDC( hdc );
3600 pSetLayout( hdc_mem, LAYOUT_LTR );
3602 bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
3603 orig_bitmap = SelectObject( hdc_mem, bitmap );
3604 SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
3605 SelectObject( hdc_mem, orig_bitmap );
3607 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3608 info.bmiHeader.biWidth = 8;
3609 info.bmiHeader.biHeight = 8;
3610 info.bmiHeader.biPlanes = 1;
3611 info.bmiHeader.biBitCount = 32;
3612 info.bmiHeader.biCompression = BI_RGB;
3614 /* First show that GetDIBits ignores the layout mode. */
3616 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3617 ok(ret == 8, "got %d\n", ret);
3618 ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
3620 pSetLayout( hdc_mem, LAYOUT_RTL );
3622 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3623 ok(ret == 8, "got %d\n", ret);
3625 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3627 /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
3628 followed by a GetDIBits and show that the bits remain unchanged. */
3630 pSetLayout( hdc_mem, LAYOUT_LTR );
3632 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3633 ok(ret == 8, "got %d\n", ret);
3634 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3635 ok(ret == 8, "got %d\n", ret);
3636 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3638 pSetLayout( hdc_mem, LAYOUT_RTL );
3640 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3641 ok(ret == 8, "got %d\n", ret);
3642 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3643 ok(ret == 8, "got %d\n", ret);
3644 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3646 DeleteObject( bitmap );
3647 DeleteDC( hdc_mem );
3648 ReleaseDC( NULL, hdc );
3651 static void test_GetDIBits_scanlines(void)
3655 HDC hdc = GetDC( NULL );
3657 DWORD data[128], inverted_bits[64];
3660 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
3662 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3663 info->bmiHeader.biWidth = 8;
3664 info->bmiHeader.biHeight = 8;
3665 info->bmiHeader.biPlanes = 1;
3666 info->bmiHeader.biBitCount = 32;
3667 info->bmiHeader.biCompression = BI_RGB;
3669 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3671 for (i = 0; i < 64; i++)
3674 inverted_bits[56 - (i & ~7) + (i & 7)] = i;
3679 memset( data, 0xaa, sizeof(data) );
3681 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3682 ok( ret == 8, "got %d\n", ret );
3683 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3684 memset( data, 0xaa, sizeof(data) );
3686 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3687 ok( ret == 5, "got %d\n", ret );
3688 ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
3689 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3690 memset( data, 0xaa, sizeof(data) );
3692 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3693 ok( ret == 7, "got %d\n", ret );
3694 ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
3695 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3696 memset( data, 0xaa, sizeof(data) );
3698 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3699 ok( ret == 1, "got %d\n", ret );
3700 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3701 memset( data, 0xaa, sizeof(data) );
3703 info->bmiHeader.biHeight = 16;
3704 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3705 ok( ret == 5, "got %d\n", ret );
3706 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3707 ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
3708 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3709 memset( data, 0xaa, sizeof(data) );
3711 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3712 ok( ret == 6, "got %d\n", ret );
3713 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3714 ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
3715 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3716 memset( data, 0xaa, sizeof(data) );
3718 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3719 ok( ret == 0, "got %d\n", ret );
3720 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3721 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3722 memset( data, 0xaa, sizeof(data) );
3724 info->bmiHeader.biHeight = 5;
3725 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3726 ok( ret == 2, "got %d\n", ret );
3727 ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
3728 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3729 memset( data, 0xaa, sizeof(data) );
3733 info->bmiHeader.biHeight = -8;
3734 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3735 ok( ret == 8, "got %d\n", ret );
3736 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3737 memset( data, 0xaa, sizeof(data) );
3739 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3740 ok( ret == 5, "got %d\n", ret );
3741 ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
3742 for (i = 40; 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, 1, 12, data, info, DIB_RGB_COLORS );
3746 ok( ret == 7, "got %d\n", ret );
3747 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3748 for (i = 56; 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, 4, 12, data, info, DIB_RGB_COLORS );
3752 ok( ret == 4, "got %d\n", ret );
3753 ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
3754 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3755 memset( data, 0xaa, sizeof(data) );
3757 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3758 ok( ret == 5, "got %d\n", ret );
3759 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3760 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3761 memset( data, 0xaa, sizeof(data) );
3763 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3764 ok( ret == 5, "got %d\n", ret );
3765 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3766 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3767 memset( data, 0xaa, sizeof(data) );
3769 info->bmiHeader.biHeight = -16;
3770 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3771 ok( ret == 8, "got %d\n", ret );
3772 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3773 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3774 memset( data, 0xaa, sizeof(data) );
3776 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3777 ok( ret == 5, "got %d\n", ret );
3778 ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
3779 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3780 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3781 memset( data, 0xaa, sizeof(data) );
3783 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3784 ok( ret == 8, "got %d\n", ret );
3785 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3786 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3787 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3788 memset( data, 0xaa, sizeof(data) );
3790 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3791 ok( ret == 8, "got %d\n", ret );
3792 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3793 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3794 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3795 memset( data, 0xaa, sizeof(data) );
3797 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3798 ok( ret == 7, "got %d\n", ret );
3799 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3800 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3801 memset( data, 0xaa, sizeof(data) );
3803 ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
3804 ok( ret == 1, "got %d\n", ret );
3805 for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3806 memset( data, 0xaa, sizeof(data) );
3808 info->bmiHeader.biHeight = -5;
3809 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3810 ok( ret == 2, "got %d\n", ret );
3811 ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
3812 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3813 memset( data, 0xaa, sizeof(data) );
3815 DeleteObject( dib );
3817 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3818 info->bmiHeader.biWidth = 8;
3819 info->bmiHeader.biHeight = -8;
3820 info->bmiHeader.biPlanes = 1;
3821 info->bmiHeader.biBitCount = 32;
3822 info->bmiHeader.biCompression = BI_RGB;
3824 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3826 for (i = 0; i < 64; i++) dib_bits[i] = i;
3830 info->bmiHeader.biHeight = -8;
3831 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3832 ok( ret == 8, "got %d\n", ret );
3833 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3834 memset( data, 0xaa, sizeof(data) );
3836 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3837 ok( ret == 5, "got %d\n", ret );
3838 ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
3839 for (i = 40; 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, 1, 12, data, info, DIB_RGB_COLORS );
3843 ok( ret == 7, "got %d\n", ret );
3844 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3845 for (i = 56; 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, 4, 12, data, info, DIB_RGB_COLORS );
3849 ok( ret == 4, "got %d\n", ret );
3850 ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
3851 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3852 memset( data, 0xaa, sizeof(data) );
3854 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3855 ok( ret == 5, "got %d\n", ret );
3856 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3857 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3858 memset( data, 0xaa, sizeof(data) );
3860 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3861 ok( ret == 5, "got %d\n", ret );
3862 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3863 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3864 memset( data, 0xaa, sizeof(data) );
3866 info->bmiHeader.biHeight = -16;
3867 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3868 ok( ret == 8, "got %d\n", ret );
3869 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3870 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3871 memset( data, 0xaa, sizeof(data) );
3873 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3874 ok( ret == 5, "got %d\n", ret );
3875 ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
3876 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3877 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3878 memset( data, 0xaa, sizeof(data) );
3880 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3881 ok( ret == 8, "got %d\n", ret );
3882 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3883 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3884 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3885 memset( data, 0xaa, sizeof(data) );
3887 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3888 ok( ret == 8, "got %d\n", ret );
3889 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3890 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3891 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3892 memset( data, 0xaa, sizeof(data) );
3894 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3895 ok( ret == 7, "got %d\n", ret );
3896 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3897 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3898 memset( data, 0xaa, sizeof(data) );
3900 info->bmiHeader.biHeight = -5;
3901 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3902 ok( ret == 2, "got %d\n", ret );
3903 ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
3904 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3905 memset( data, 0xaa, sizeof(data) );
3910 info->bmiHeader.biHeight = 8;
3912 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3913 ok( ret == 8, "got %d\n", ret );
3914 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3915 memset( data, 0xaa, sizeof(data) );
3917 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3918 ok( ret == 5, "got %d\n", ret );
3919 ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
3920 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3921 memset( data, 0xaa, sizeof(data) );
3923 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3924 ok( ret == 7, "got %d\n", ret );
3925 ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
3926 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3927 memset( data, 0xaa, sizeof(data) );
3929 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3930 ok( ret == 1, "got %d\n", ret );
3931 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3932 memset( data, 0xaa, sizeof(data) );
3934 info->bmiHeader.biHeight = 16;
3935 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3936 ok( ret == 5, "got %d\n", ret );
3937 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3938 ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
3939 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3940 memset( data, 0xaa, sizeof(data) );
3942 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3943 ok( ret == 6, "got %d\n", ret );
3944 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3945 ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
3946 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3947 memset( data, 0xaa, sizeof(data) );
3949 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3950 ok( ret == 0, "got %d\n", ret );
3951 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3952 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3953 memset( data, 0xaa, sizeof(data) );
3955 info->bmiHeader.biHeight = 5;
3956 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3957 ok( ret == 2, "got %d\n", ret );
3958 ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
3959 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3960 memset( data, 0xaa, sizeof(data) );
3962 DeleteObject( dib );
3964 ReleaseDC( NULL, hdc );
3965 HeapFree( GetProcessHeap(), 0, info );
3969 static void test_SetDIBits(void)
3973 HDC hdc = GetDC( NULL );
3974 DWORD data[128], inverted_data[128];
3978 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
3980 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3981 info->bmiHeader.biWidth = 8;
3982 info->bmiHeader.biHeight = 8;
3983 info->bmiHeader.biPlanes = 1;
3984 info->bmiHeader.biBitCount = 32;
3985 info->bmiHeader.biCompression = BI_RGB;
3987 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3988 memset( dib_bits, 0xaa, 64 * 4 );
3990 for (i = 0; i < 128; i++)
3993 inverted_data[120 - (i & ~7) + (i & 7)] = i;
3998 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3999 ok( ret == 8, "got %d\n", ret );
4000 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4001 memset( dib_bits, 0xaa, 64 * 4 );
4003 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4004 ok( ret == 5, "got %d\n", ret );
4005 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4006 ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
4007 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4008 memset( dib_bits, 0xaa, 64 * 4 );
4010 /* top of dst is aligned with startscans down for the top of the src.
4011 Then starting from the bottom of src, lines rows are copied across. */
4013 info->bmiHeader.biHeight = 16;
4014 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4015 ok( ret == 12, "got %d\n", ret );
4016 ok( !memcmp( dib_bits, data + 56, 40 * 4 ), "bits differ\n");
4017 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4018 memset( dib_bits, 0xaa, 64 * 4 );
4020 info->bmiHeader.biHeight = 5;
4021 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4022 ok( ret == 2, "got %d\n", ret );
4023 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4024 ok( !memcmp( dib_bits + 32, data, 16 * 4 ), "bits differ\n");
4025 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4026 memset( dib_bits, 0xaa, 64 * 4 );
4029 info->bmiHeader.biHeight = -8;
4030 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4031 ok( ret == 8, "got %d\n", ret );
4032 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4033 memset( dib_bits, 0xaa, 64 * 4 );
4035 /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
4036 we copy lines rows from the top of the src */
4038 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4039 ok( ret == 5, "got %d\n", ret );
4040 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4041 ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
4042 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4043 memset( dib_bits, 0xaa, 64 * 4 );
4045 info->bmiHeader.biHeight = -16;
4046 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4047 ok( ret == 12, "got %d\n", ret );
4048 ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
4049 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4050 memset( dib_bits, 0xaa, 64 * 4 );
4052 ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4053 ok( ret == 12, "got %d\n", ret );
4054 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4055 memset( dib_bits, 0xaa, 64 * 4 );
4057 ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4058 ok( ret == 12, "got %d\n", ret );
4059 ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
4060 memset( dib_bits, 0xaa, 64 * 4 );
4062 info->bmiHeader.biHeight = -5;
4063 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4064 ok( ret == 2, "got %d\n", ret );
4065 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4066 ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
4067 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4068 memset( dib_bits, 0xaa, 64 * 4 );
4070 DeleteObject( dib );
4072 info->bmiHeader.biHeight = -8;
4074 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4075 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4079 /* like the t-d -> b-u case. */
4081 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4082 ok( ret == 8, "got %d\n", ret );
4083 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4084 memset( dib_bits, 0xaa, 64 * 4 );
4086 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4087 ok( ret == 5, "got %d\n", ret );
4088 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4089 ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
4090 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4091 memset( dib_bits, 0xaa, 64 * 4 );
4093 info->bmiHeader.biHeight = -16;
4094 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4095 ok( ret == 12, "got %d\n", ret );
4096 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4097 ok( !memcmp( dib_bits + 24, data, 40 * 4 ), "bits differ\n");
4098 memset( dib_bits, 0xaa, 64 * 4 );
4100 info->bmiHeader.biHeight = -5;
4101 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4102 ok( ret == 2, "got %d\n", ret );
4103 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4104 ok( !memcmp( dib_bits + 16, data, 16 * 4 ), "bits differ\n");
4105 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4106 memset( dib_bits, 0xaa, 64 * 4 );
4109 /* like the b-u -> b-u case */
4111 info->bmiHeader.biHeight = 8;
4112 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4113 ok( ret == 8, "got %d\n", ret );
4114 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4115 memset( dib_bits, 0xaa, 64 * 4 );
4117 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4118 ok( ret == 5, "got %d\n", ret );
4119 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4120 ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
4121 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4122 memset( dib_bits, 0xaa, 64 * 4 );
4124 info->bmiHeader.biHeight = 16;
4125 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4126 ok( ret == 12, "got %d\n", ret );
4127 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4128 ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
4129 memset( dib_bits, 0xaa, 64 * 4 );
4131 info->bmiHeader.biHeight = 5;
4132 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4133 ok( ret == 2, "got %d\n", ret );
4134 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4135 ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
4136 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4137 memset( dib_bits, 0xaa, 64 * 4 );
4139 DeleteObject( dib );
4140 ReleaseDC( NULL, hdc );
4141 HeapFree( GetProcessHeap(), 0, info );
4144 static void test_SetDIBits_RLE4(void)
4148 HDC hdc = GetDC( NULL );
4149 BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00, /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
4150 0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
4151 0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00, /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
4152 0x00, 0x02, 0x01, 0x02, 0x05, 0x87, /* dx=1, dy=2, 8, 7, 8, 7, 8 */
4153 0x00, 0x01 }; /* <eod> */
4156 DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
4157 0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
4158 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4159 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4160 0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
4161 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4162 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4163 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4165 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4167 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4168 info->bmiHeader.biWidth = 8;
4169 info->bmiHeader.biHeight = 8;
4170 info->bmiHeader.biPlanes = 1;
4171 info->bmiHeader.biBitCount = 32;
4172 info->bmiHeader.biCompression = BI_RGB;
4174 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4175 memset( dib_bits, 0xaa, 64 * 4 );
4177 info->bmiHeader.biBitCount = 4;
4178 info->bmiHeader.biCompression = BI_RLE4;
4179 info->bmiHeader.biSizeImage = sizeof(rle4_data);
4181 for (i = 0; i < 16; i++)
4183 info->bmiColors[i].rgbRed = i;
4184 info->bmiColors[i].rgbGreen = i;
4185 info->bmiColors[i].rgbBlue = i;
4186 info->bmiColors[i].rgbReserved = 0;
4189 ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
4190 ok( ret == 8, "got %d\n", ret );
4191 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
4192 memset( dib_bits, 0xaa, 64 * 4 );
4194 DeleteObject( dib );
4195 ReleaseDC( NULL, hdc );
4196 HeapFree( GetProcessHeap(), 0, info );
4199 static void test_SetDIBits_RLE8(void)
4203 HDC hdc = GetDC( NULL );
4204 BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00, /* 2, 2, 2, f0, f0, f0, f0, <eol> */
4205 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4206 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4207 0x00, 0x01 }; /* <eod> */
4210 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4211 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4212 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4213 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4214 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4215 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4216 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4217 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4218 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4219 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4220 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4221 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4222 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4223 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4224 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4225 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4227 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4229 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4230 info->bmiHeader.biWidth = 8;
4231 info->bmiHeader.biHeight = 8;
4232 info->bmiHeader.biPlanes = 1;
4233 info->bmiHeader.biBitCount = 32;
4234 info->bmiHeader.biCompression = BI_RGB;
4236 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4237 memset( dib_bits, 0xaa, 64 * 4 );
4239 info->bmiHeader.biBitCount = 8;
4240 info->bmiHeader.biCompression = BI_RLE8;
4241 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4243 for (i = 0; i < 256; i++)
4245 info->bmiColors[i].rgbRed = i;
4246 info->bmiColors[i].rgbGreen = i;
4247 info->bmiColors[i].rgbBlue = i;
4248 info->bmiColors[i].rgbReserved = 0;
4251 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4252 ok( ret == 8, "got %d\n", ret );
4253 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4254 memset( dib_bits, 0xaa, 64 * 4 );
4256 /* startscan and lines are ignored, unless lines == 0 */
4257 ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4258 ok( ret == 8, "got %d\n", ret );
4259 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4260 memset( dib_bits, 0xaa, 64 * 4 );
4262 ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4263 ok( ret == 8, "got %d\n", ret );
4264 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4265 memset( dib_bits, 0xaa, 64 * 4 );
4267 ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4268 ok( ret == 0, "got %d\n", ret );
4269 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4270 memset( dib_bits, 0xaa, 64 * 4 );
4272 /* reduce width to 4, left-hand side of dst is touched. */
4273 info->bmiHeader.biWidth = 4;
4274 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4275 ok( ret == 8, "got %d\n", ret );
4276 for (i = 0; i < 64; i++)
4278 DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4279 ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4281 memset( dib_bits, 0xaa, 64 * 4 );
4283 /* Show that the top lines are aligned by adjusting the height of the src */
4285 /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4286 info->bmiHeader.biWidth = 8;
4287 info->bmiHeader.biHeight = 4;
4288 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4289 ok( ret == 4, "got %d\n", ret );
4290 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4291 ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4292 memset( dib_bits, 0xaa, 64 * 4 );
4294 /* increase the height to 9 -> everything moves down one row. */
4295 info->bmiHeader.biHeight = 9;
4296 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4297 ok( ret == 9, "got %d\n", ret );
4298 ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4299 for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4300 memset( dib_bits, 0xaa, 64 * 4 );
4302 /* top-down compressed dibs are invalid */
4303 info->bmiHeader.biHeight = -8;
4304 SetLastError( 0xdeadbeef );
4305 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4306 ok( ret == 0, "got %d\n", ret );
4307 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4308 DeleteObject( dib );
4312 info->bmiHeader.biHeight = -8;
4313 info->bmiHeader.biBitCount = 32;
4314 info->bmiHeader.biCompression = BI_RGB;
4315 info->bmiHeader.biSizeImage = 0;
4317 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4318 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4320 info->bmiHeader.biHeight = 8;
4321 info->bmiHeader.biBitCount = 8;
4322 info->bmiHeader.biCompression = BI_RLE8;
4323 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4325 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4326 ok( ret == 8, "got %d\n", ret );
4327 ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4328 memset( dib_bits, 0xaa, 64 * 4 );
4330 info->bmiHeader.biHeight = 4;
4331 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4332 ok( ret == 4, "got %d\n", ret );
4333 ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4334 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4335 memset( dib_bits, 0xaa, 64 * 4 );
4337 info->bmiHeader.biHeight = 9;
4338 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4339 ok( ret == 9, "got %d\n", ret );
4340 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4341 ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4342 memset( dib_bits, 0xaa, 64 * 4 );
4344 DeleteObject( dib );
4345 ReleaseDC( NULL, hdc );
4346 HeapFree( GetProcessHeap(), 0, info );
4349 static void test_SetDIBitsToDevice(void)
4353 HDC hdc = CreateCompatibleDC( 0 );
4354 DWORD data[128], inverted_data[128];
4358 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4360 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4361 info->bmiHeader.biWidth = 8;
4362 info->bmiHeader.biHeight = 8;
4363 info->bmiHeader.biPlanes = 1;
4364 info->bmiHeader.biBitCount = 32;
4365 info->bmiHeader.biCompression = BI_RGB;
4367 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4368 memset( dib_bits, 0xaa, 64 * 4 );
4369 SelectObject( hdc, dib );
4371 for (i = 0; i < 128; i++)
4374 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4379 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4380 ok( ret == 8, "got %d\n", ret );
4381 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4382 memset( dib_bits, 0xaa, 64 * 4 );
4384 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4385 ok( ret == 5, "got %d\n", ret );
4386 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4387 for (i = 8; i < 48; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4388 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4389 memset( dib_bits, 0xaa, 64 * 4 );
4391 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 3, 1, 5, data, info, DIB_RGB_COLORS );
4392 ok( ret == 5, "got %d\n", ret );
4393 for (i = 0; i < 24; i++) ok( dib_bits[i] == data[i + 16], "%d: got %08x\n", i, dib_bits[i] );
4394 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4395 memset( dib_bits, 0xaa, 64 * 4 );
4397 info->bmiHeader.biHeight = 16;
4398 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4399 ok( ret == 7, "got %d\n", ret );
4400 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4401 for (i = 8; i < 64; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4402 memset( dib_bits, 0xaa, 64 * 4 );
4404 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 8, 0, 6, 1, 12, data, info, DIB_RGB_COLORS );
4405 ok( ret == 12, "got %d\n", ret );
4406 for (i = 0; i < 40; i++) ok( dib_bits[i] == data[i + 56], "%d: got %08x\n", i, dib_bits[i] );
4407 for (i = 40; 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, -4, 8, 8, 0, 3, 1, 12, data, info, DIB_RGB_COLORS );
4411 ok( ret == 10, "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 < 64; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4414 memset( dib_bits, 0xaa, 64 * 4 );
4416 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, -3, 1, 12, data, info, DIB_RGB_COLORS );
4417 ok( ret == 4, "got %d\n", ret );
4418 for (i = 0; i < 32; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4419 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4420 memset( dib_bits, 0xaa, 64 * 4 );
4422 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 5, 0, -2, 1, 12, data, info, DIB_RGB_COLORS );
4423 ok( ret == 2, "got %d\n", ret );
4424 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4425 for (i = 32; i < 48; i++) ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4426 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4427 memset( dib_bits, 0xaa, 64 * 4 );
4429 info->bmiHeader.biHeight = 5;
4430 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 2, 2, data, info, DIB_RGB_COLORS );
4431 ok( ret == 2, "got %d\n", ret );
4432 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4433 for (i = 16; i < 32; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4434 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4435 memset( dib_bits, 0xaa, 64 * 4 );
4437 ret = SetDIBitsToDevice( hdc, 3, 3, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4438 ok( ret == 3, "got %d\n", ret );
4439 for (i = 0; i < 64; i++)
4440 if (i == 27 || i == 28 || i == 35 || i == 36)
4441 ok( dib_bits[i] == data[i - 18], "%d: got %08x\n", i, dib_bits[i] );
4443 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4444 memset( dib_bits, 0xaa, 64 * 4 );
4446 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4447 ok( ret == 5, "got %d\n", ret );
4448 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4449 memset( dib_bits, 0xaa, 64 * 4 );
4451 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4452 ok( ret == 0, "got %d\n", ret );
4453 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4454 memset( dib_bits, 0xaa, 64 * 4 );
4456 SetMapMode( hdc, MM_ANISOTROPIC );
4457 SetWindowExtEx( hdc, 3, 3, NULL );
4458 ret = SetDIBitsToDevice( hdc, 2, 2, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4459 ok( ret == 3, "got %d\n", ret );
4460 for (i = 0; i < 64; i++)
4461 if (i == 41 || i == 42 || i == 49 || i == 50)
4462 ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4464 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4465 memset( dib_bits, 0xaa, 64 * 4 );
4467 SetWindowExtEx( hdc, -1, -1, NULL );
4468 ret = SetDIBitsToDevice( hdc, 2, 2, 4, 4, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4469 ok( ret == 4, "got %d\n", ret );
4470 for (i = 0; i < 64; i++)
4471 if (i == 48 || i == 49 || i == 56 || i == 57)
4472 ok( dib_bits[i] == data[i - 37], "%d: got %08x\n", i, dib_bits[i] );
4474 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4475 memset( dib_bits, 0xaa, 64 * 4 );
4476 SetMapMode( hdc, MM_TEXT );
4480 pSetLayout( hdc, LAYOUT_RTL );
4481 ret = SetDIBitsToDevice( hdc, 1, 2, 3, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4482 ok( ret == 3, "got %d\n", ret );
4483 for (i = 0; i < 64; i++)
4484 if (i == 36 || i == 37 || i == 38 || i == 44 || i == 45 || i == 46)
4485 ok( dib_bits[i] == data[i - 27], "%d: got %08x\n", i, dib_bits[i] );
4487 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4488 memset( dib_bits, 0xaa, 64 * 4 );
4489 pSetLayout( hdc, LAYOUT_LTR );
4493 info->bmiHeader.biHeight = -8;
4494 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4495 ok( ret == 8, "got %d\n", ret );
4496 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4497 memset( dib_bits, 0xaa, 64 * 4 );
4499 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4500 ok( ret == 5, "got %d\n", ret );
4501 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4502 for (i = 8; i < 48; i++) ok( dib_bits[i] == inverted_data[i + 80], "%d: got %08x\n", i, dib_bits[i] );
4503 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4504 memset( dib_bits, 0xaa, 64 * 4 );
4506 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 4, 1, 5, data, info, DIB_RGB_COLORS );
4507 ok( ret == 5, "got %d\n", ret );
4508 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4509 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4510 memset( dib_bits, 0xaa, 64 * 4 );
4512 info->bmiHeader.biHeight = -16;
4513 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4514 ok( ret == 12, "got %d\n", ret );
4515 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4516 for (i = 8; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4517 memset( dib_bits, 0xaa, 64 * 4 );
4519 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, 7, 1, 12, data, info, DIB_RGB_COLORS );
4520 ok( ret == 12, "got %d\n", ret );
4521 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4522 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4523 memset( dib_bits, 0xaa, 64 * 4 );
4525 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 4, 12, data, info, DIB_RGB_COLORS );
4526 ok( ret == 12, "got %d\n", ret );
4527 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4528 for (i = 32; i < 64; i++) ok( dib_bits[i] == inverted_data[i], "%d: got %08x\n", i, dib_bits[i] );
4529 memset( dib_bits, 0xaa, 64 * 4 );
4531 ret = SetDIBitsToDevice( hdc, 0, -3, 8, 8, 0, 2, 4, 12, data, info, DIB_RGB_COLORS );
4532 ok( ret == 12, "got %d\n", ret );
4533 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4534 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4535 memset( dib_bits, 0xaa, 64 * 4 );
4537 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, -2, 4, 12, data, info, DIB_RGB_COLORS );
4538 ok( ret == 12, "got %d\n", ret );
4539 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4540 for (i = 24; i < 40; i++) ok( dib_bits[i] == inverted_data[i + 8], "%d: got %08x\n", i, dib_bits[i] );
4541 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4542 memset( dib_bits, 0xaa, 64 * 4 );
4544 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 5, 12, data, info, DIB_RGB_COLORS );
4545 ok( ret == 12, "got %d\n", ret );
4546 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4547 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4548 memset( dib_bits, 0xaa, 64 * 4 );
4550 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4551 ok( ret == 12, "got %d\n", ret );
4552 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4553 memset( dib_bits, 0xaa, 64 * 4 );
4555 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -2, -4, 0, 12, data, info, DIB_RGB_COLORS );
4556 ok( ret == 12, "got %d\n", ret );
4557 for (i = 0; i < 64; i++)
4558 if (i == 31 || i == 39 || i == 47 || i == 55 || i == 63)
4559 ok( dib_bits[i] == inverted_data[i + 1], "%d: got %08x\n", i, dib_bits[i] );
4561 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4562 memset( dib_bits, 0xaa, 64 * 4 );
4564 info->bmiHeader.biHeight = -5;
4565 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4566 ok( ret == 2, "got %d\n", ret );
4567 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4568 for (i = 8; i < 24; i++) ok( dib_bits[i] == inverted_data[i + 104], "%d: got %08x\n", i, dib_bits[i] );
4569 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4570 memset( dib_bits, 0xaa, 64 * 4 );
4572 ret = SetDIBitsToDevice( hdc, 5, 4, 2, 2, 6, 3, 1, 5, data, info, DIB_RGB_COLORS );
4573 ok( ret == 5, "got %d\n", ret );
4574 for (i = 0; i < 64; i++)
4575 if (i == 21 || i == 22 || i == 29 || i == 30)
4576 ok( dib_bits[i] == inverted_data[i + 89], "%d: got %08x\n", i, dib_bits[i] );
4578 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4579 memset( dib_bits, 0xaa, 64 * 4 );
4581 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4582 ok( ret == 5, "got %d\n", ret );
4583 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4584 memset( dib_bits, 0xaa, 64 * 4 );
4586 info->bmiHeader.biHeight = -8;
4588 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4589 DeleteObject( SelectObject( hdc, dib ));
4590 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4594 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4595 ok( ret == 8, "got %d\n", ret );
4596 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4597 memset( dib_bits, 0xaa, 64 * 4 );
4599 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4600 ok( ret == 5, "got %d\n", ret );
4601 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4602 for (i = 16; i < 56; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4603 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4604 memset( dib_bits, 0xaa, 64 * 4 );
4606 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 3, 0, 2, 1, 5, data, info, DIB_RGB_COLORS );
4607 ok( ret == 5, "got %d\n", ret );
4608 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4609 for (i = 24; i < 48; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4610 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4611 memset( dib_bits, 0xaa, 64 * 4 );
4613 info->bmiHeader.biHeight = -16;
4614 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4615 ok( ret == 12, "got %d\n", ret );
4616 for (i = 0; i < 56; i++) ok( dib_bits[i] == data[i + 40], "%d: got %08x\n", i, dib_bits[i] );
4617 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4618 memset( dib_bits, 0xaa, 64 * 4 );
4620 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -1, -8, 0, 12, data, info, DIB_RGB_COLORS );
4621 ok( ret == 12, "got %d\n", ret );
4622 for (i = 0; i < 64; i++)
4623 if (i == 6 || i == 7)
4624 ok( dib_bits[i] == data[i + 82], "%d: got %08x\n", i, dib_bits[i] );
4626 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4627 memset( dib_bits, 0xaa, 64 * 4 );
4629 info->bmiHeader.biHeight = -5;
4630 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4631 ok( ret == 2, "got %d\n", ret );
4632 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4633 for (i = 40; i < 56; i++) ok( dib_bits[i] == data[i - 40], "%d: got %08x\n", i, dib_bits[i] );
4634 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4635 memset( dib_bits, 0xaa, 64 * 4 );
4637 ret = SetDIBitsToDevice( hdc, 7, 2, 8, 8, 1, 0, 0, 5, data, info, DIB_RGB_COLORS );
4638 ok( ret == 5, "got %d\n", ret );
4639 for (i = 0; i < 64; i++)
4640 if (i == 47 || i == 55 || i == 63)
4641 ok( dib_bits[i] == data[i - 46], "%d: got %08x\n", i, dib_bits[i] );
4643 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4644 memset( dib_bits, 0xaa, 64 * 4 );
4646 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4647 ok( ret == 5, "got %d\n", ret );
4648 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4649 memset( dib_bits, 0xaa, 64 * 4 );
4653 info->bmiHeader.biHeight = 8;
4654 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4655 ok( ret == 8, "got %d\n", ret );
4656 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4657 memset( dib_bits, 0xaa, 64 * 4 );
4659 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4660 ok( ret == 5, "got %d\n", ret );
4661 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4662 for (i = 16; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4663 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4664 memset( dib_bits, 0xaa, 64 * 4 );
4666 info->bmiHeader.biHeight = 16;
4667 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4668 ok( ret == 7, "got %d\n", ret );
4669 for (i = 0; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4670 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4671 memset( dib_bits, 0xaa, 64 * 4 );
4673 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, 0, -4, 1, 12, data, info, DIB_RGB_COLORS );
4674 ok( ret == 3, "got %d\n", ret );
4675 for (i = 0; i < 64; i++)
4676 if ((i >= 36 && i <= 39) || (i >= 44 && i <= 47) || (i >= 52 && i <= 55))
4677 ok( dib_bits[i] == inverted_data[i + 68], "%d: got %08x\n", i, dib_bits[i] );
4679 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4680 memset( dib_bits, 0xaa, 64 * 4 );
4682 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, -30, -30, 1, 12, data, info, DIB_RGB_COLORS );
4683 ok( ret == 0, "got %d\n", ret );
4684 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4685 memset( dib_bits, 0xaa, 64 * 4 );
4687 ret = SetDIBitsToDevice( hdc, 5, -5, 8, 16, -2, -4, 4, 12, data, info, DIB_RGB_COLORS );
4688 ok( ret == 8, "got %d\n", ret );
4689 for (i = 0; i < 64; i++)
4690 if (i == 7 || i == 15 || i == 23)
4691 ok( dib_bits[i] == inverted_data[i + 97], "%d: got %08x\n", i, dib_bits[i] );
4693 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4694 memset( dib_bits, 0xaa, 64 * 4 );
4696 info->bmiHeader.biHeight = 5;
4697 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4698 ok( ret == 2, "got %d\n", ret );
4699 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4700 for (i = 40; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4701 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4702 memset( dib_bits, 0xaa, 64 * 4 );
4704 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4705 ok( ret == 5, "got %d\n", ret );
4706 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4707 memset( dib_bits, 0xaa, 64 * 4 );
4710 DeleteObject( dib );
4711 HeapFree( GetProcessHeap(), 0, info );
4714 static void test_SetDIBitsToDevice_RLE8(void)
4718 HDC hdc = CreateCompatibleDC( 0 );
4719 BYTE rle8_data[20] = { 0x04, 0x02, 0x03, 0xf0, 0x00, 0x00, /* 2, 2, 2, 2, f0, f0, f0, <eol> */
4720 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4721 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4722 0x00, 0x01 }; /* <eod> */
4725 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4726 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4727 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4728 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4729 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4730 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4731 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4732 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4733 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4734 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4735 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4736 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4737 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4738 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4739 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4740 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4742 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4744 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4745 info->bmiHeader.biWidth = 8;
4746 info->bmiHeader.biHeight = 8;
4747 info->bmiHeader.biPlanes = 1;
4748 info->bmiHeader.biBitCount = 32;
4749 info->bmiHeader.biCompression = BI_RGB;
4751 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4752 memset( dib_bits, 0xaa, 64 * 4 );
4753 SelectObject( hdc, dib );
4755 info->bmiHeader.biBitCount = 8;
4756 info->bmiHeader.biCompression = BI_RLE8;
4757 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4759 for (i = 0; i < 256; i++)
4761 info->bmiColors[i].rgbRed = i;
4762 info->bmiColors[i].rgbGreen = i;
4763 info->bmiColors[i].rgbBlue = i;
4764 info->bmiColors[i].rgbReserved = 0;
4767 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4768 ok( ret == 8, "got %d\n", ret );
4769 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4770 memset( dib_bits, 0xaa, 64 * 4 );
4772 /* startscan and lines are ignored, unless lines == 0 */
4773 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4774 ok( ret == 8, "got %d\n", ret );
4775 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4776 memset( dib_bits, 0xaa, 64 * 4 );
4778 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4779 ok( ret == 8, "got %d\n", ret );
4780 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4781 memset( dib_bits, 0xaa, 64 * 4 );
4783 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4784 ok( ret == 0, "got %d\n", ret );
4785 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4786 memset( dib_bits, 0xaa, 64 * 4 );
4788 info->bmiHeader.biWidth = 2;
4789 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4790 ok( ret == 8, "got %d\n", ret );
4791 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4792 memset( dib_bits, 0xaa, 64 * 4 );
4794 info->bmiHeader.biWidth = 8;
4795 info->bmiHeader.biHeight = 2;
4796 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4797 ok( ret == 2, "got %d\n", ret );
4798 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4799 memset( dib_bits, 0xaa, 64 * 4 );
4801 info->bmiHeader.biHeight = 9;
4802 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4803 ok( ret == 9, "got %d\n", ret );
4804 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4805 memset( dib_bits, 0xaa, 64 * 4 );
4807 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4808 ok( ret == 9, "got %d\n", ret );
4809 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4810 memset( dib_bits, 0xaa, 64 * 4 );
4812 info->bmiHeader.biHeight = 8;
4813 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 9, rle8_data, info, DIB_RGB_COLORS );
4814 ok( ret == 8, "got %d\n", ret );
4815 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4816 memset( dib_bits, 0xaa, 64 * 4 );
4818 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4819 ok( ret == 8, "got %d\n", ret );
4820 for (i = 0; i < 40; i++) ok( dib_bits[i] == bottom_up[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4821 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4822 memset( dib_bits, 0xaa, 64 * 4 );
4824 ret = SetDIBitsToDevice( hdc, 0, 3, 4, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4825 ok( ret == 8, "got %d\n", ret );
4826 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4827 for (i = 8; i < 40; i++)
4828 if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4829 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4830 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4831 memset( dib_bits, 0xaa, 64 * 4 );
4833 ret = SetDIBitsToDevice( hdc, 3, 3, 8, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4834 ok( ret == 8, "got %d\n", ret );
4835 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4836 for (i = 8; i < 40; i++)
4837 if ((i & 7) < 3) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4838 else ok( dib_bits[i] == bottom_up[i - 11], "%d: got %08x\n", i, dib_bits[i] );
4839 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4840 memset( dib_bits, 0xaa, 64 * 4 );
4842 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 4, 2, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4843 ok( ret == 8, "got %d\n", ret );
4844 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4845 for (i = 8; i < 40; i++)
4846 if ((i & 7) < 2) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4847 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4848 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4849 memset( dib_bits, 0xaa, 64 * 4 );
4851 info->bmiHeader.biWidth = 37;
4852 info->bmiHeader.biHeight = 37;
4853 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
4854 ok( ret == 37, "got %d\n", ret );
4855 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4856 for (i = 24; i < 64; i++)
4857 if (i == 52) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
4858 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4859 else ok( dib_bits[i] == bottom_up[i - 20], "%d: got %08x\n", i, dib_bits[i] );
4860 memset( dib_bits, 0xaa, 64 * 4 );
4862 /* top-down compressed dibs are invalid */
4863 info->bmiHeader.biWidth = 8;
4864 info->bmiHeader.biHeight = -8;
4865 SetLastError( 0xdeadbeef );
4866 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4867 ok( ret == 0, "got %d\n", ret );
4868 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4872 info->bmiHeader.biHeight = -8;
4873 info->bmiHeader.biBitCount = 32;
4874 info->bmiHeader.biCompression = BI_RGB;
4875 info->bmiHeader.biSizeImage = 0;
4877 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4878 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4879 DeleteObject( SelectObject( hdc, dib ));
4881 info->bmiHeader.biHeight = 8;
4882 info->bmiHeader.biBitCount = 8;
4883 info->bmiHeader.biCompression = BI_RLE8;
4884 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4886 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4887 ok( ret == 8, "got %d\n", ret );
4888 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4889 memset( dib_bits, 0xaa, 64 * 4 );
4891 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4892 ok( ret == 8, "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 info->bmiHeader.biHeight = 4;
4897 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4898 ok( ret == 4, "got %d\n", ret );
4899 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4900 memset( dib_bits, 0xaa, 64 * 4 );
4902 info->bmiHeader.biHeight = 9;
4903 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4904 ok( ret == 9, "got %d\n", ret );
4905 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4906 memset( dib_bits, 0xaa, 64 * 4 );
4908 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4909 ok( ret == 9, "got %d\n", ret );
4910 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4911 memset( dib_bits, 0xaa, 64 * 4 );
4913 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 6, 2, 2, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4914 ok( ret == 9, "got %d\n", ret );
4915 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4916 for (i = 24; i < 64; i++) ok( dib_bits[i] == top_down[i - 24], "%d: got %08x\n", i, dib_bits[i] );
4917 memset( dib_bits, 0xaa, 64 * 4 );
4919 info->bmiHeader.biWidth = 37;
4920 info->bmiHeader.biHeight = 37;
4921 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
4922 ok( ret == 37, "got %d\n", ret );
4923 for (i = 0; i < 40; i++)
4924 if (i == 12) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
4925 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4926 else ok( dib_bits[i] == top_down[i + 28], "%d: got %08x\n", i, dib_bits[i] );
4927 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4928 memset( dib_bits, 0xaa, 64 * 4 );
4931 DeleteObject( dib );
4932 HeapFree( GetProcessHeap(), 0, info );
4939 hdll = GetModuleHandle("gdi32.dll");
4940 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
4941 pSetLayout = (void*)GetProcAddress(hdll, "SetLayout");
4943 test_createdibitmap();
4946 test_mono_dibsection();
4949 test_GetDIBits_selected_DIB(1);
4950 test_GetDIBits_selected_DIB(4);
4951 test_GetDIBits_selected_DIB(8);
4952 test_GetDIBits_selected_DDB(TRUE);
4953 test_GetDIBits_selected_DDB(FALSE);
4955 test_GetDIBits_BI_BITFIELDS();
4956 test_select_object();
4957 test_CreateBitmap();
4960 test_StretchDIBits();
4961 test_GdiAlphaBlend();
4962 test_32bit_bitmap_blt();
4963 test_bitmapinfoheadersize();
4966 test_GetDIBits_top_down(16);
4967 test_GetDIBits_top_down(24);
4968 test_GetDIBits_top_down(32);
4969 test_GetSetDIBits_rtl();
4970 test_GetDIBits_scanlines();
4972 test_SetDIBits_RLE4();
4973 test_SetDIBits_RLE8();
4974 test_SetDIBitsToDevice();
4975 test_SetDIBitsToDevice_RLE8();