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, 0);
584 test_color(hdcmem, DIBINDEX(1), c1, 0, 0);
585 test_color(hdcmem, DIBINDEX(2), c0, 0, 0);
586 test_color(hdcmem, PALETTEINDEX(0), c0, 0, 0);
587 test_color(hdcmem, PALETTEINDEX(1), c0, 0, 0);
588 test_color(hdcmem, PALETTEINDEX(2), c0, 0, 0);
589 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen,
590 pbmi->bmiColors[0].rgbBlue), c0, 0, 0);
591 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen,
592 pbmi->bmiColors[1].rgbBlue), c1, 0, 0);
593 test_color(hdcmem, PALETTERGB(0, 0, 0), c0, 0, 0);
594 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 0, 0);
595 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1, 0, 0);
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, 0);
708 test_color(hdcmem, DIBINDEX(1), c1, 0, 0);
709 test_color(hdcmem, DIBINDEX(2), c0, 0, 0);
710 test_color(hdcmem, PALETTEINDEX(0), c0, 0, 0);
711 test_color(hdcmem, PALETTEINDEX(1), c1, 0, 0);
712 test_color(hdcmem, PALETTEINDEX(2), c0, 0, 0);
713 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen,
714 plogpal->palPalEntry[0].peBlue), c0, 0, 0);
715 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen,
716 plogpal->palPalEntry[1].peBlue), c1, 0, 0);
717 test_color(hdcmem, PALETTERGB(0, 0, 0), c1, 0, 0);
718 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 0, 0);
719 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0, 0, 0);
720 test_color(hdcmem, PALETTERGB(0, 1, 0), c1, 0, 0);
721 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1, 0, 0);
722 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0, 0, 0);
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], 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;
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, __LINE__);
3139 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3140 expected[2] = 0x00000000, expected[3] = 0x00000000;
3141 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3142 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
3144 expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
3145 expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
3146 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3147 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
3149 expected[0] = 0x42441000, expected[1] = 0x00000000;
3150 expected[2] = 0x00000000, expected[3] = 0x00000000;
3151 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3152 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
3154 expected[0] = 0x00000000, expected[1] = 0x00000000;
3155 expected[2] = 0x00000000, expected[3] = 0x00000000;
3156 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3157 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3159 expected[0] = 0x00000000, expected[1] = 0x00000000;
3160 expected[2] = 0x00000000, expected[3] = 0x00000000;
3161 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3162 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3164 expected[0] = 0x00000000, expected[1] = 0x00000000;
3165 expected[2] = 0x00000000, expected[3] = 0x00000000;
3166 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3167 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
3169 expected[0] = 0x00000000, expected[1] = 0x00000000;
3170 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
3171 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3172 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3174 SelectObject(hdcDst, oldDst);
3175 DeleteObject(bmpDst);
3177 /* Bottom up destination tests */
3178 biDst.bmiHeader.biHeight = 2;
3179 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3181 oldDst = SelectObject(hdcDst, bmpDst);
3183 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3184 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
3185 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3186 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3189 SelectObject(hdcDst, oldDst);
3190 DeleteObject(bmpDst);
3193 DeleteDC(hdcScreen);
3196 static void test_GdiAlphaBlend(void)
3208 BLENDFUNCTION blend;
3210 if (!pGdiAlphaBlend)
3212 win_skip("GdiAlphaBlend() is not implemented\n");
3216 hdcNull = GetDC(NULL);
3217 hdcDst = CreateCompatibleDC(hdcNull);
3218 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
3219 hdcSrc = CreateCompatibleDC(hdcNull);
3221 bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3222 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3223 bmi->bmiHeader.biHeight = 20;
3224 bmi->bmiHeader.biWidth = 20;
3225 bmi->bmiHeader.biBitCount = 32;
3226 bmi->bmiHeader.biPlanes = 1;
3227 bmi->bmiHeader.biCompression = BI_RGB;
3228 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3229 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3231 oldDst = SelectObject(hdcDst, bmpDst);
3232 oldSrc = SelectObject(hdcSrc, bmpSrc);
3234 blend.BlendOp = AC_SRC_OVER;
3235 blend.BlendFlags = 0;
3236 blend.SourceConstantAlpha = 128;
3237 blend.AlphaFormat = 0;
3239 SetLastError(0xdeadbeef);
3240 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3241 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3243 SetLastError(0xdeadbeef);
3244 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3245 ok( !ret, "GdiAlphaBlend succeeded\n" );
3246 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3248 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3249 ok( !ret, "GdiAlphaBlend succeeded\n" );
3250 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend);
3251 ok( !ret, "GdiAlphaBlend succeeded\n" );
3252 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3253 ok( !ret, "GdiAlphaBlend succeeded\n" );
3254 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3255 ok( !ret, "GdiAlphaBlend succeeded\n" );
3257 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
3258 SetLastError(0xdeadbeef);
3259 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3260 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3261 SetLastError(0xdeadbeef);
3262 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3263 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3264 SetMapMode(hdcSrc, MM_ANISOTROPIC);
3265 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
3266 SetLastError(0xdeadbeef);
3267 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend);
3268 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3269 SetLastError(0xdeadbeef);
3270 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend);
3271 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3273 SetLastError(0xdeadbeef);
3274 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend);
3275 ok( !ret, "GdiAlphaBlend succeeded\n" );
3276 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3278 /* overlapping source and dest not allowed */
3280 SetLastError(0xdeadbeef);
3281 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 19, 19, 20, 20, blend);
3282 ok( !ret, "GdiAlphaBlend succeeded\n" );
3283 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3285 SetLastError(0xdeadbeef);
3286 ret = pGdiAlphaBlend(hdcDst, 20, 20, 20, 20, hdcDst, 1, 1, 20, 20, blend);
3287 ok( !ret, "GdiAlphaBlend succeeded\n" );
3288 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3290 SetLastError(0xdeadbeef);
3291 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 20, 10, 20, 20, blend);
3292 ok( ret, "GdiAlphaBlend succeeded\n" );
3293 SetLastError(0xdeadbeef);
3294 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 10, 20, 20, 20, blend);
3295 ok( ret, "GdiAlphaBlend succeeded\n" );
3297 /* AC_SRC_ALPHA requires 32-bpp BI_RGB format */
3299 blend.AlphaFormat = AC_SRC_ALPHA;
3300 SetLastError(0xdeadbeef);
3301 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3302 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3304 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3305 ((DWORD *)bmi->bmiColors)[0] = 0xff0000;
3306 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3307 ((DWORD *)bmi->bmiColors)[2] = 0x0000ff;
3308 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3309 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3310 oldSrc = SelectObject(hdcSrc, bmpSrc);
3311 DeleteObject( oldSrc );
3313 SetLastError(0xdeadbeef);
3314 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3315 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3317 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3318 ((DWORD *)bmi->bmiColors)[0] = 0x0000ff;
3319 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3320 ((DWORD *)bmi->bmiColors)[2] = 0xff0000;
3321 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3322 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3323 oldSrc = SelectObject(hdcSrc, bmpSrc);
3324 DeleteObject( oldSrc );
3326 SetLastError(0xdeadbeef);
3327 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3328 ok( !ret, "GdiAlphaBlend succeeded\n" );
3329 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3331 bmi->bmiHeader.biBitCount = 24;
3332 bmi->bmiHeader.biCompression = BI_RGB;
3333 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3334 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3335 oldSrc = SelectObject(hdcSrc, bmpSrc);
3336 DeleteObject( oldSrc );
3338 SetLastError(0xdeadbeef);
3339 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3340 ok( !ret, "GdiAlphaBlend succeeded\n" );
3341 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3343 bmi->bmiHeader.biBitCount = 1;
3344 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3345 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3346 oldSrc = SelectObject(hdcSrc, bmpSrc);
3347 DeleteObject( oldSrc );
3349 SetLastError(0xdeadbeef);
3350 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3351 ok( !ret, "GdiAlphaBlend succeeded\n" );
3352 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3354 bmpSrc = CreateBitmap( 100, 100, 1, 1, NULL );
3355 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3356 oldSrc = SelectObject(hdcSrc, bmpSrc);
3357 DeleteObject( oldSrc );
3359 SetLastError(0xdeadbeef);
3360 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3361 ok( !ret, "GdiAlphaBlend succeeded\n" );
3362 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3364 SelectObject(hdcDst, oldDst);
3365 SelectObject(hdcSrc, oldSrc);
3366 DeleteObject(bmpSrc);
3367 DeleteObject(bmpDst);
3371 ReleaseDC(NULL, hdcNull);
3375 static void test_clipping(void)
3383 HDC hdcDst = CreateCompatibleDC( NULL );
3384 HDC hdcSrc = CreateCompatibleDC( NULL );
3386 BITMAPINFO bmpinfo={{0}};
3387 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3388 bmpinfo.bmiHeader.biWidth = 100;
3389 bmpinfo.bmiHeader.biHeight = 100;
3390 bmpinfo.bmiHeader.biPlanes = 1;
3391 bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3392 bmpinfo.bmiHeader.biCompression = BI_RGB;
3394 bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3395 ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3396 SelectObject( hdcDst, bmpDst );
3398 bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3399 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3400 SelectObject( hdcSrc, bmpSrc );
3402 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3403 ok(result, "BitBlt failed\n");
3405 hRgn = CreateRectRgn( 0,0,0,0 );
3406 SelectClipRgn( hdcDst, hRgn );
3408 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3409 ok(result, "BitBlt failed\n");
3411 DeleteObject( bmpDst );
3412 DeleteObject( bmpSrc );
3413 DeleteObject( hRgn );
3418 static void test_32bit_bitmap_blt(void)
3421 HBITMAP bmpSrc, bmpDst;
3422 HBITMAP oldSrc, oldDst;
3423 HDC hdcSrc, hdcDst, hdcScreen;
3425 DWORD colorSrc = 0x11223344;
3427 memset(&biDst, 0, sizeof(BITMAPINFO));
3428 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3429 biDst.bmiHeader.biWidth = 2;
3430 biDst.bmiHeader.biHeight = -2;
3431 biDst.bmiHeader.biPlanes = 1;
3432 biDst.bmiHeader.biBitCount = 32;
3433 biDst.bmiHeader.biCompression = BI_RGB;
3435 hdcScreen = CreateCompatibleDC(0);
3436 if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3438 DeleteDC(hdcScreen);
3439 trace("Skipping 32-bit DDB test\n");
3443 hdcSrc = CreateCompatibleDC(hdcScreen);
3444 bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3445 oldSrc = SelectObject(hdcSrc, bmpSrc);
3447 hdcDst = CreateCompatibleDC(hdcScreen);
3448 bmpDst = CreateDIBSection(hdcDst, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3449 oldDst = SelectObject(hdcDst, bmpDst);
3451 StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3452 ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3455 SelectObject(hdcDst, oldDst);
3456 DeleteObject(bmpDst);
3459 SelectObject(hdcSrc, oldSrc);
3460 DeleteObject(bmpSrc);
3463 DeleteDC(hdcScreen);
3467 * Used by test_GetDIBits_top_down to create the bitmap to test against.
3469 static void setup_picture(char *picture, int bpp)
3477 /*Set the first byte in each pixel to the index of that pixel.*/
3478 for (i = 0; i < 4; i++)
3479 picture[i * (bpp / 8)] = i;
3484 /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
3491 static void test_GetDIBits_top_down(int bpp)
3494 HBITMAP bmptb, bmpbt;
3500 memset( &bi, 0, sizeof(bi) );
3501 bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
3502 bi.bmiHeader.biWidth=2;
3503 bi.bmiHeader.biHeight=2;
3504 bi.bmiHeader.biPlanes=1;
3505 bi.bmiHeader.biBitCount=bpp;
3506 bi.bmiHeader.biCompression=BI_RGB;
3508 /*Get the device context for the screen.*/
3510 ok(hdc != NULL, "Could not get a handle to a device context.\n");
3512 /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
3513 bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3514 ok(bmpbt != NULL, "Could not create a DIB section.\n");
3515 /*Now that we have a pointer to the pixels, we write to them.*/
3516 setup_picture((char*)picture, bpp);
3517 /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
3518 bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
3519 bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3520 ok(bmptb != NULL, "Could not create a DIB section.\n");
3521 /*Write to this top to bottom bitmap.*/
3522 setup_picture((char*)picture, bpp);
3524 bi.bmiHeader.biWidth = 1;
3526 bi.bmiHeader.biHeight = 2;
3527 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3528 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3529 /*Check the first byte of the pixel.*/
3530 ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3531 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3532 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3533 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3534 /*Check second scanline.*/
3535 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3536 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3537 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3538 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3539 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3540 ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3541 /*Check both scanlines.*/
3542 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3543 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3544 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3545 ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3546 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3547 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3548 ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3549 ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3551 /*Make destination bitmap top-down.*/
3552 bi.bmiHeader.biHeight = -2;
3553 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3554 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3555 ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3556 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3557 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3558 ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3559 /*Check second scanline.*/
3560 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3561 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3562 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3563 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3564 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3565 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3566 /*Check both scanlines.*/
3567 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3568 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3569 ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3570 ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3571 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3572 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3573 ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3574 ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3576 DeleteObject(bmpbt);
3577 DeleteObject(bmptb);
3580 static void test_GetSetDIBits_rtl(void)
3583 HBITMAP bitmap, orig_bitmap;
3586 DWORD bits_1[8 * 8], bits_2[8 * 8];
3590 win_skip("Don't have SetLayout\n");
3594 hdc = GetDC( NULL );
3595 hdc_mem = CreateCompatibleDC( hdc );
3596 pSetLayout( hdc_mem, LAYOUT_LTR );
3598 bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
3599 orig_bitmap = SelectObject( hdc_mem, bitmap );
3600 SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
3601 SelectObject( hdc_mem, orig_bitmap );
3603 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3604 info.bmiHeader.biWidth = 8;
3605 info.bmiHeader.biHeight = 8;
3606 info.bmiHeader.biPlanes = 1;
3607 info.bmiHeader.biBitCount = 32;
3608 info.bmiHeader.biCompression = BI_RGB;
3610 /* First show that GetDIBits ignores the layout mode. */
3612 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3613 ok(ret == 8, "got %d\n", ret);
3614 ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
3616 pSetLayout( hdc_mem, LAYOUT_RTL );
3618 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3619 ok(ret == 8, "got %d\n", ret);
3621 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3623 /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
3624 followed by a GetDIBits and show that the bits remain unchanged. */
3626 pSetLayout( hdc_mem, LAYOUT_LTR );
3628 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3629 ok(ret == 8, "got %d\n", ret);
3630 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3631 ok(ret == 8, "got %d\n", ret);
3632 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3634 pSetLayout( hdc_mem, LAYOUT_RTL );
3636 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3637 ok(ret == 8, "got %d\n", ret);
3638 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3639 ok(ret == 8, "got %d\n", ret);
3640 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3642 DeleteObject( bitmap );
3643 DeleteDC( hdc_mem );
3644 ReleaseDC( NULL, hdc );
3647 static void test_GetDIBits_scanlines(void)
3651 HDC hdc = GetDC( NULL );
3653 DWORD data[128], inverted_bits[64];
3656 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
3658 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3659 info->bmiHeader.biWidth = 8;
3660 info->bmiHeader.biHeight = 8;
3661 info->bmiHeader.biPlanes = 1;
3662 info->bmiHeader.biBitCount = 32;
3663 info->bmiHeader.biCompression = BI_RGB;
3665 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3667 for (i = 0; i < 64; i++)
3670 inverted_bits[56 - (i & ~7) + (i & 7)] = i;
3675 memset( data, 0xaa, sizeof(data) );
3677 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3678 ok( ret == 8, "got %d\n", ret );
3679 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3680 memset( data, 0xaa, sizeof(data) );
3682 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3683 ok( ret == 5, "got %d\n", ret );
3684 ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
3685 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3686 memset( data, 0xaa, sizeof(data) );
3688 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3689 ok( ret == 7, "got %d\n", ret );
3690 ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
3691 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3692 memset( data, 0xaa, sizeof(data) );
3694 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3695 ok( ret == 1, "got %d\n", ret );
3696 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3697 memset( data, 0xaa, sizeof(data) );
3699 info->bmiHeader.biHeight = 16;
3700 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3701 ok( ret == 5, "got %d\n", ret );
3702 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3703 ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
3704 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3705 memset( data, 0xaa, sizeof(data) );
3707 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3708 ok( ret == 6, "got %d\n", ret );
3709 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3710 ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
3711 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3712 memset( data, 0xaa, sizeof(data) );
3714 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3715 ok( ret == 0, "got %d\n", ret );
3716 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3717 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3718 memset( data, 0xaa, sizeof(data) );
3720 info->bmiHeader.biHeight = 5;
3721 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3722 ok( ret == 2, "got %d\n", ret );
3723 ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
3724 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3725 memset( data, 0xaa, sizeof(data) );
3729 info->bmiHeader.biHeight = -8;
3730 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3731 ok( ret == 8, "got %d\n", ret );
3732 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3733 memset( data, 0xaa, sizeof(data) );
3735 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3736 ok( ret == 5, "got %d\n", ret );
3737 ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
3738 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3739 memset( data, 0xaa, sizeof(data) );
3741 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3742 ok( ret == 7, "got %d\n", ret );
3743 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3744 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3745 memset( data, 0xaa, sizeof(data) );
3747 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3748 ok( ret == 4, "got %d\n", ret );
3749 ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
3750 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3751 memset( data, 0xaa, sizeof(data) );
3753 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3754 ok( ret == 5, "got %d\n", ret );
3755 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3756 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3757 memset( data, 0xaa, sizeof(data) );
3759 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3760 ok( ret == 5, "got %d\n", ret );
3761 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3762 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3763 memset( data, 0xaa, sizeof(data) );
3765 info->bmiHeader.biHeight = -16;
3766 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3767 ok( ret == 8, "got %d\n", ret );
3768 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3769 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3770 memset( data, 0xaa, sizeof(data) );
3772 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3773 ok( ret == 5, "got %d\n", ret );
3774 ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
3775 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3776 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3777 memset( data, 0xaa, sizeof(data) );
3779 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3780 ok( ret == 8, "got %d\n", ret );
3781 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3782 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3783 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3784 memset( data, 0xaa, sizeof(data) );
3786 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3787 ok( ret == 8, "got %d\n", ret );
3788 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3789 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3790 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3791 memset( data, 0xaa, sizeof(data) );
3793 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3794 ok( ret == 7, "got %d\n", ret );
3795 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3796 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3797 memset( data, 0xaa, sizeof(data) );
3799 ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
3800 ok( ret == 1, "got %d\n", ret );
3801 for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3802 memset( data, 0xaa, sizeof(data) );
3804 info->bmiHeader.biHeight = -5;
3805 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3806 ok( ret == 2, "got %d\n", ret );
3807 ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
3808 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3809 memset( data, 0xaa, sizeof(data) );
3811 DeleteObject( dib );
3813 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3814 info->bmiHeader.biWidth = 8;
3815 info->bmiHeader.biHeight = -8;
3816 info->bmiHeader.biPlanes = 1;
3817 info->bmiHeader.biBitCount = 32;
3818 info->bmiHeader.biCompression = BI_RGB;
3820 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3822 for (i = 0; i < 64; i++) dib_bits[i] = i;
3826 info->bmiHeader.biHeight = -8;
3827 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3828 ok( ret == 8, "got %d\n", ret );
3829 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3830 memset( data, 0xaa, sizeof(data) );
3832 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3833 ok( ret == 5, "got %d\n", ret );
3834 ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
3835 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3836 memset( data, 0xaa, sizeof(data) );
3838 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3839 ok( ret == 7, "got %d\n", ret );
3840 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3841 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3842 memset( data, 0xaa, sizeof(data) );
3844 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3845 ok( ret == 4, "got %d\n", ret );
3846 ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
3847 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3848 memset( data, 0xaa, sizeof(data) );
3850 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3851 ok( ret == 5, "got %d\n", ret );
3852 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3853 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3854 memset( data, 0xaa, sizeof(data) );
3856 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3857 ok( ret == 5, "got %d\n", ret );
3858 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3859 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3860 memset( data, 0xaa, sizeof(data) );
3862 info->bmiHeader.biHeight = -16;
3863 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3864 ok( ret == 8, "got %d\n", ret );
3865 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3866 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3867 memset( data, 0xaa, sizeof(data) );
3869 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3870 ok( ret == 5, "got %d\n", ret );
3871 ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
3872 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3873 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3874 memset( data, 0xaa, sizeof(data) );
3876 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3877 ok( ret == 8, "got %d\n", ret );
3878 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3879 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3880 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3881 memset( data, 0xaa, sizeof(data) );
3883 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3884 ok( ret == 8, "got %d\n", ret );
3885 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3886 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3887 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3888 memset( data, 0xaa, sizeof(data) );
3890 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3891 ok( ret == 7, "got %d\n", ret );
3892 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3893 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3894 memset( data, 0xaa, sizeof(data) );
3896 info->bmiHeader.biHeight = -5;
3897 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3898 ok( ret == 2, "got %d\n", ret );
3899 ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
3900 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3901 memset( data, 0xaa, sizeof(data) );
3906 info->bmiHeader.biHeight = 8;
3908 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3909 ok( ret == 8, "got %d\n", ret );
3910 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3911 memset( data, 0xaa, sizeof(data) );
3913 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3914 ok( ret == 5, "got %d\n", ret );
3915 ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
3916 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3917 memset( data, 0xaa, sizeof(data) );
3919 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3920 ok( ret == 7, "got %d\n", ret );
3921 ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
3922 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3923 memset( data, 0xaa, sizeof(data) );
3925 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3926 ok( ret == 1, "got %d\n", ret );
3927 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3928 memset( data, 0xaa, sizeof(data) );
3930 info->bmiHeader.biHeight = 16;
3931 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3932 ok( ret == 5, "got %d\n", ret );
3933 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3934 ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
3935 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3936 memset( data, 0xaa, sizeof(data) );
3938 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3939 ok( ret == 6, "got %d\n", ret );
3940 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3941 ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
3942 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3943 memset( data, 0xaa, sizeof(data) );
3945 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3946 ok( ret == 0, "got %d\n", ret );
3947 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3948 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3949 memset( data, 0xaa, sizeof(data) );
3951 info->bmiHeader.biHeight = 5;
3952 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3953 ok( ret == 2, "got %d\n", ret );
3954 ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
3955 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3956 memset( data, 0xaa, sizeof(data) );
3958 DeleteObject( dib );
3960 ReleaseDC( NULL, hdc );
3961 HeapFree( GetProcessHeap(), 0, info );
3965 static void test_SetDIBits(void)
3969 HDC hdc = GetDC( NULL );
3970 DWORD data[128], inverted_data[128];
3974 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
3976 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3977 info->bmiHeader.biWidth = 8;
3978 info->bmiHeader.biHeight = 8;
3979 info->bmiHeader.biPlanes = 1;
3980 info->bmiHeader.biBitCount = 32;
3981 info->bmiHeader.biCompression = BI_RGB;
3983 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3984 memset( dib_bits, 0xaa, 64 * 4 );
3986 for (i = 0; i < 128; i++)
3989 inverted_data[120 - (i & ~7) + (i & 7)] = i;
3994 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3995 ok( ret == 8, "got %d\n", ret );
3996 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
3997 memset( dib_bits, 0xaa, 64 * 4 );
3999 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4000 ok( ret == 5, "got %d\n", ret );
4001 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4002 ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
4003 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4004 memset( dib_bits, 0xaa, 64 * 4 );
4006 /* top of dst is aligned with startscans down for the top of the src.
4007 Then starting from the bottom of src, lines rows are copied across. */
4009 info->bmiHeader.biHeight = 16;
4010 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4011 ok( ret == 12, "got %d\n", ret );
4012 ok( !memcmp( dib_bits, data + 56, 40 * 4 ), "bits differ\n");
4013 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4014 memset( dib_bits, 0xaa, 64 * 4 );
4016 info->bmiHeader.biHeight = 5;
4017 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4018 ok( ret == 2, "got %d\n", ret );
4019 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4020 ok( !memcmp( dib_bits + 32, data, 16 * 4 ), "bits differ\n");
4021 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4022 memset( dib_bits, 0xaa, 64 * 4 );
4025 info->bmiHeader.biHeight = -8;
4026 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4027 ok( ret == 8, "got %d\n", ret );
4028 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4029 memset( dib_bits, 0xaa, 64 * 4 );
4031 /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
4032 we copy lines rows from the top of the src */
4034 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4035 ok( ret == 5, "got %d\n", ret );
4036 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4037 ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
4038 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4039 memset( dib_bits, 0xaa, 64 * 4 );
4041 info->bmiHeader.biHeight = -16;
4042 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4043 ok( ret == 12, "got %d\n", ret );
4044 ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
4045 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4046 memset( dib_bits, 0xaa, 64 * 4 );
4048 ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4049 ok( ret == 12, "got %d\n", ret );
4050 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4051 memset( dib_bits, 0xaa, 64 * 4 );
4053 ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4054 ok( ret == 12, "got %d\n", ret );
4055 ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
4056 memset( dib_bits, 0xaa, 64 * 4 );
4058 info->bmiHeader.biHeight = -5;
4059 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4060 ok( ret == 2, "got %d\n", ret );
4061 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4062 ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
4063 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4064 memset( dib_bits, 0xaa, 64 * 4 );
4066 DeleteObject( dib );
4068 info->bmiHeader.biHeight = -8;
4070 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4071 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4075 /* like the t-d -> b-u case. */
4077 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4078 ok( ret == 8, "got %d\n", ret );
4079 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4080 memset( dib_bits, 0xaa, 64 * 4 );
4082 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4083 ok( ret == 5, "got %d\n", ret );
4084 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4085 ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
4086 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4087 memset( dib_bits, 0xaa, 64 * 4 );
4089 info->bmiHeader.biHeight = -16;
4090 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4091 ok( ret == 12, "got %d\n", ret );
4092 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4093 ok( !memcmp( dib_bits + 24, data, 40 * 4 ), "bits differ\n");
4094 memset( dib_bits, 0xaa, 64 * 4 );
4096 info->bmiHeader.biHeight = -5;
4097 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4098 ok( ret == 2, "got %d\n", ret );
4099 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4100 ok( !memcmp( dib_bits + 16, data, 16 * 4 ), "bits differ\n");
4101 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4102 memset( dib_bits, 0xaa, 64 * 4 );
4105 /* like the b-u -> b-u case */
4107 info->bmiHeader.biHeight = 8;
4108 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4109 ok( ret == 8, "got %d\n", ret );
4110 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4111 memset( dib_bits, 0xaa, 64 * 4 );
4113 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4114 ok( ret == 5, "got %d\n", ret );
4115 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4116 ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
4117 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4118 memset( dib_bits, 0xaa, 64 * 4 );
4120 info->bmiHeader.biHeight = 16;
4121 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4122 ok( ret == 12, "got %d\n", ret );
4123 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4124 ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
4125 memset( dib_bits, 0xaa, 64 * 4 );
4127 info->bmiHeader.biHeight = 5;
4128 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4129 ok( ret == 2, "got %d\n", ret );
4130 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4131 ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
4132 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4133 memset( dib_bits, 0xaa, 64 * 4 );
4135 DeleteObject( dib );
4136 ReleaseDC( NULL, hdc );
4137 HeapFree( GetProcessHeap(), 0, info );
4140 static void test_SetDIBits_RLE4(void)
4144 HDC hdc = GetDC( NULL );
4145 BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00, /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
4146 0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
4147 0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00, /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
4148 0x00, 0x02, 0x01, 0x02, 0x05, 0x87, /* dx=1, dy=2, 8, 7, 8, 7, 8 */
4149 0x00, 0x01 }; /* <eod> */
4152 DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
4153 0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
4154 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4155 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4156 0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
4157 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4158 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4159 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4161 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4163 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4164 info->bmiHeader.biWidth = 8;
4165 info->bmiHeader.biHeight = 8;
4166 info->bmiHeader.biPlanes = 1;
4167 info->bmiHeader.biBitCount = 32;
4168 info->bmiHeader.biCompression = BI_RGB;
4170 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4171 memset( dib_bits, 0xaa, 64 * 4 );
4173 info->bmiHeader.biBitCount = 4;
4174 info->bmiHeader.biCompression = BI_RLE4;
4175 info->bmiHeader.biSizeImage = sizeof(rle4_data);
4177 for (i = 0; i < 16; i++)
4179 info->bmiColors[i].rgbRed = i;
4180 info->bmiColors[i].rgbGreen = i;
4181 info->bmiColors[i].rgbBlue = i;
4182 info->bmiColors[i].rgbReserved = 0;
4185 ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
4186 ok( ret == 8, "got %d\n", ret );
4187 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
4188 memset( dib_bits, 0xaa, 64 * 4 );
4190 DeleteObject( dib );
4191 ReleaseDC( NULL, hdc );
4192 HeapFree( GetProcessHeap(), 0, info );
4195 static void test_SetDIBits_RLE8(void)
4199 HDC hdc = GetDC( NULL );
4200 BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00, /* 2, 2, 2, f0, f0, f0, f0, <eol> */
4201 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4202 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4203 0x00, 0x01 }; /* <eod> */
4206 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4207 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4208 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4209 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4210 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4211 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4212 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4213 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4214 DWORD top_down[64] = { 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 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4219 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4220 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4221 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4223 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4225 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4226 info->bmiHeader.biWidth = 8;
4227 info->bmiHeader.biHeight = 8;
4228 info->bmiHeader.biPlanes = 1;
4229 info->bmiHeader.biBitCount = 32;
4230 info->bmiHeader.biCompression = BI_RGB;
4232 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4233 memset( dib_bits, 0xaa, 64 * 4 );
4235 info->bmiHeader.biBitCount = 8;
4236 info->bmiHeader.biCompression = BI_RLE8;
4237 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4239 for (i = 0; i < 256; i++)
4241 info->bmiColors[i].rgbRed = i;
4242 info->bmiColors[i].rgbGreen = i;
4243 info->bmiColors[i].rgbBlue = i;
4244 info->bmiColors[i].rgbReserved = 0;
4247 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4248 ok( ret == 8, "got %d\n", ret );
4249 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4250 memset( dib_bits, 0xaa, 64 * 4 );
4252 /* startscan and lines are ignored, unless lines == 0 */
4253 ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4254 ok( ret == 8, "got %d\n", ret );
4255 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4256 memset( dib_bits, 0xaa, 64 * 4 );
4258 ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4259 ok( ret == 8, "got %d\n", ret );
4260 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4261 memset( dib_bits, 0xaa, 64 * 4 );
4263 ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4264 ok( ret == 0, "got %d\n", ret );
4265 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4266 memset( dib_bits, 0xaa, 64 * 4 );
4268 /* reduce width to 4, left-hand side of dst is touched. */
4269 info->bmiHeader.biWidth = 4;
4270 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4271 ok( ret == 8, "got %d\n", ret );
4272 for (i = 0; i < 64; i++)
4274 DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4275 ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4277 memset( dib_bits, 0xaa, 64 * 4 );
4279 /* Show that the top lines are aligned by adjusting the height of the src */
4281 /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4282 info->bmiHeader.biWidth = 8;
4283 info->bmiHeader.biHeight = 4;
4284 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4285 ok( ret == 4, "got %d\n", ret );
4286 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4287 ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4288 memset( dib_bits, 0xaa, 64 * 4 );
4290 /* increase the height to 9 -> everything moves down one row. */
4291 info->bmiHeader.biHeight = 9;
4292 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4293 ok( ret == 9, "got %d\n", ret );
4294 ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4295 for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4296 memset( dib_bits, 0xaa, 64 * 4 );
4298 /* top-down compressed dibs are invalid */
4299 info->bmiHeader.biHeight = -8;
4300 SetLastError( 0xdeadbeef );
4301 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4302 ok( ret == 0, "got %d\n", ret );
4303 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4304 DeleteObject( dib );
4308 info->bmiHeader.biHeight = -8;
4309 info->bmiHeader.biBitCount = 32;
4310 info->bmiHeader.biCompression = BI_RGB;
4311 info->bmiHeader.biSizeImage = 0;
4313 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4314 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4316 info->bmiHeader.biHeight = 8;
4317 info->bmiHeader.biBitCount = 8;
4318 info->bmiHeader.biCompression = BI_RLE8;
4319 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4321 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4322 ok( ret == 8, "got %d\n", ret );
4323 ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4324 memset( dib_bits, 0xaa, 64 * 4 );
4326 info->bmiHeader.biHeight = 4;
4327 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4328 ok( ret == 4, "got %d\n", ret );
4329 ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4330 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4331 memset( dib_bits, 0xaa, 64 * 4 );
4333 info->bmiHeader.biHeight = 9;
4334 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4335 ok( ret == 9, "got %d\n", ret );
4336 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4337 ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4338 memset( dib_bits, 0xaa, 64 * 4 );
4340 DeleteObject( dib );
4341 ReleaseDC( NULL, hdc );
4342 HeapFree( GetProcessHeap(), 0, info );
4345 static void test_SetDIBitsToDevice(void)
4349 HDC hdc = CreateCompatibleDC( 0 );
4350 DWORD data[128], inverted_data[128];
4354 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4356 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4357 info->bmiHeader.biWidth = 8;
4358 info->bmiHeader.biHeight = 8;
4359 info->bmiHeader.biPlanes = 1;
4360 info->bmiHeader.biBitCount = 32;
4361 info->bmiHeader.biCompression = BI_RGB;
4363 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4364 memset( dib_bits, 0xaa, 64 * 4 );
4365 SelectObject( hdc, dib );
4367 for (i = 0; i < 128; i++)
4370 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4375 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4376 ok( ret == 8, "got %d\n", ret );
4377 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4378 memset( dib_bits, 0xaa, 64 * 4 );
4380 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4381 ok( ret == 5, "got %d\n", ret );
4382 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4383 for (i = 8; i < 48; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4384 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4385 memset( dib_bits, 0xaa, 64 * 4 );
4387 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 3, 1, 5, data, info, DIB_RGB_COLORS );
4388 ok( ret == 5, "got %d\n", ret );
4389 for (i = 0; i < 24; i++) ok( dib_bits[i] == data[i + 16], "%d: got %08x\n", i, dib_bits[i] );
4390 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4391 memset( dib_bits, 0xaa, 64 * 4 );
4393 info->bmiHeader.biHeight = 16;
4394 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4395 ok( ret == 7, "got %d\n", ret );
4396 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4397 for (i = 8; i < 64; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4398 memset( dib_bits, 0xaa, 64 * 4 );
4400 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 8, 0, 6, 1, 12, data, info, DIB_RGB_COLORS );
4401 ok( ret == 12, "got %d\n", ret );
4402 for (i = 0; i < 40; i++) ok( dib_bits[i] == data[i + 56], "%d: got %08x\n", i, dib_bits[i] );
4403 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4404 memset( dib_bits, 0xaa, 64 * 4 );
4406 ret = SetDIBitsToDevice( hdc, 0, -4, 8, 8, 0, 3, 1, 12, data, info, DIB_RGB_COLORS );
4407 ok( ret == 10, "got %d\n", ret );
4408 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4409 for (i = 32; i < 64; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4410 memset( dib_bits, 0xaa, 64 * 4 );
4412 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, -3, 1, 12, data, info, DIB_RGB_COLORS );
4413 ok( ret == 4, "got %d\n", ret );
4414 for (i = 0; i < 32; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4415 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4416 memset( dib_bits, 0xaa, 64 * 4 );
4418 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 5, 0, -2, 1, 12, data, info, DIB_RGB_COLORS );
4419 ok( ret == 2, "got %d\n", ret );
4420 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4421 for (i = 32; i < 48; i++) ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4422 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4423 memset( dib_bits, 0xaa, 64 * 4 );
4425 info->bmiHeader.biHeight = 5;
4426 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 2, 2, data, info, DIB_RGB_COLORS );
4427 ok( ret == 2, "got %d\n", ret );
4428 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4429 for (i = 16; i < 32; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4430 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4431 memset( dib_bits, 0xaa, 64 * 4 );
4433 ret = SetDIBitsToDevice( hdc, 3, 3, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4434 ok( ret == 3, "got %d\n", ret );
4435 for (i = 0; i < 64; i++)
4436 if (i == 27 || i == 28 || i == 35 || i == 36)
4437 ok( dib_bits[i] == data[i - 18], "%d: got %08x\n", i, dib_bits[i] );
4439 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4440 memset( dib_bits, 0xaa, 64 * 4 );
4442 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4443 ok( ret == 5, "got %d\n", ret );
4444 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4445 memset( dib_bits, 0xaa, 64 * 4 );
4447 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4448 ok( ret == 0, "got %d\n", ret );
4449 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4450 memset( dib_bits, 0xaa, 64 * 4 );
4452 SetMapMode( hdc, MM_ANISOTROPIC );
4453 SetWindowExtEx( hdc, 3, 3, NULL );
4454 ret = SetDIBitsToDevice( hdc, 2, 2, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4455 ok( ret == 3, "got %d\n", ret );
4456 for (i = 0; i < 64; i++)
4457 if (i == 41 || i == 42 || i == 49 || i == 50)
4458 ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4460 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4461 memset( dib_bits, 0xaa, 64 * 4 );
4463 SetWindowExtEx( hdc, -1, -1, NULL );
4464 ret = SetDIBitsToDevice( hdc, 2, 2, 4, 4, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4465 ok( ret == 4, "got %d\n", ret );
4466 for (i = 0; i < 64; i++)
4467 if (i == 48 || i == 49 || i == 56 || i == 57)
4468 ok( dib_bits[i] == data[i - 37], "%d: got %08x\n", i, dib_bits[i] );
4470 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4471 memset( dib_bits, 0xaa, 64 * 4 );
4472 SetMapMode( hdc, MM_TEXT );
4476 pSetLayout( hdc, LAYOUT_RTL );
4477 ret = SetDIBitsToDevice( hdc, 1, 2, 3, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4478 ok( ret == 3, "got %d\n", ret );
4479 for (i = 0; i < 64; i++)
4480 if (i == 36 || i == 37 || i == 38 || i == 44 || i == 45 || i == 46)
4481 ok( dib_bits[i] == data[i - 27], "%d: got %08x\n", i, dib_bits[i] );
4483 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4484 memset( dib_bits, 0xaa, 64 * 4 );
4485 pSetLayout( hdc, LAYOUT_LTR );
4489 info->bmiHeader.biHeight = -8;
4490 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4491 ok( ret == 8, "got %d\n", ret );
4492 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4493 memset( dib_bits, 0xaa, 64 * 4 );
4495 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4496 ok( ret == 5, "got %d\n", ret );
4497 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4498 for (i = 8; i < 48; i++) ok( dib_bits[i] == inverted_data[i + 80], "%d: got %08x\n", i, dib_bits[i] );
4499 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4500 memset( dib_bits, 0xaa, 64 * 4 );
4502 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 4, 1, 5, data, info, DIB_RGB_COLORS );
4503 ok( ret == 5, "got %d\n", ret );
4504 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4505 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4506 memset( dib_bits, 0xaa, 64 * 4 );
4508 info->bmiHeader.biHeight = -16;
4509 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4510 ok( ret == 12, "got %d\n", ret );
4511 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4512 for (i = 8; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4513 memset( dib_bits, 0xaa, 64 * 4 );
4515 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, 7, 1, 12, data, info, DIB_RGB_COLORS );
4516 ok( ret == 12, "got %d\n", ret );
4517 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4518 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4519 memset( dib_bits, 0xaa, 64 * 4 );
4521 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 4, 12, data, info, DIB_RGB_COLORS );
4522 ok( ret == 12, "got %d\n", ret );
4523 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4524 for (i = 32; i < 64; i++) ok( dib_bits[i] == inverted_data[i], "%d: got %08x\n", i, dib_bits[i] );
4525 memset( dib_bits, 0xaa, 64 * 4 );
4527 ret = SetDIBitsToDevice( hdc, 0, -3, 8, 8, 0, 2, 4, 12, data, info, DIB_RGB_COLORS );
4528 ok( ret == 12, "got %d\n", ret );
4529 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4530 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4531 memset( dib_bits, 0xaa, 64 * 4 );
4533 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, -2, 4, 12, data, info, DIB_RGB_COLORS );
4534 ok( ret == 12, "got %d\n", ret );
4535 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4536 for (i = 24; i < 40; i++) ok( dib_bits[i] == inverted_data[i + 8], "%d: got %08x\n", i, dib_bits[i] );
4537 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4538 memset( dib_bits, 0xaa, 64 * 4 );
4540 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 5, 12, data, info, DIB_RGB_COLORS );
4541 ok( ret == 12, "got %d\n", ret );
4542 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4543 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4544 memset( dib_bits, 0xaa, 64 * 4 );
4546 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4547 ok( ret == 12, "got %d\n", ret );
4548 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4549 memset( dib_bits, 0xaa, 64 * 4 );
4551 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -2, -4, 0, 12, data, info, DIB_RGB_COLORS );
4552 ok( ret == 12, "got %d\n", ret );
4553 for (i = 0; i < 64; i++)
4554 if (i == 31 || i == 39 || i == 47 || i == 55 || i == 63)
4555 ok( dib_bits[i] == inverted_data[i + 1], "%d: got %08x\n", i, dib_bits[i] );
4557 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4558 memset( dib_bits, 0xaa, 64 * 4 );
4560 info->bmiHeader.biHeight = -5;
4561 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4562 ok( ret == 2, "got %d\n", ret );
4563 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4564 for (i = 8; i < 24; i++) ok( dib_bits[i] == inverted_data[i + 104], "%d: got %08x\n", i, dib_bits[i] );
4565 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4566 memset( dib_bits, 0xaa, 64 * 4 );
4568 ret = SetDIBitsToDevice( hdc, 5, 4, 2, 2, 6, 3, 1, 5, data, info, DIB_RGB_COLORS );
4569 ok( ret == 5, "got %d\n", ret );
4570 for (i = 0; i < 64; i++)
4571 if (i == 21 || i == 22 || i == 29 || i == 30)
4572 ok( dib_bits[i] == inverted_data[i + 89], "%d: got %08x\n", i, dib_bits[i] );
4574 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4575 memset( dib_bits, 0xaa, 64 * 4 );
4577 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4578 ok( ret == 5, "got %d\n", ret );
4579 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4580 memset( dib_bits, 0xaa, 64 * 4 );
4582 info->bmiHeader.biHeight = -8;
4584 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4585 DeleteObject( SelectObject( hdc, dib ));
4586 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4590 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4591 ok( ret == 8, "got %d\n", ret );
4592 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4593 memset( dib_bits, 0xaa, 64 * 4 );
4595 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4596 ok( ret == 5, "got %d\n", ret );
4597 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4598 for (i = 16; i < 56; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4599 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4600 memset( dib_bits, 0xaa, 64 * 4 );
4602 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 3, 0, 2, 1, 5, data, info, DIB_RGB_COLORS );
4603 ok( ret == 5, "got %d\n", ret );
4604 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4605 for (i = 24; i < 48; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4606 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4607 memset( dib_bits, 0xaa, 64 * 4 );
4609 info->bmiHeader.biHeight = -16;
4610 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4611 ok( ret == 12, "got %d\n", ret );
4612 for (i = 0; i < 56; i++) ok( dib_bits[i] == data[i + 40], "%d: got %08x\n", i, dib_bits[i] );
4613 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4614 memset( dib_bits, 0xaa, 64 * 4 );
4616 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -1, -8, 0, 12, data, info, DIB_RGB_COLORS );
4617 ok( ret == 12, "got %d\n", ret );
4618 for (i = 0; i < 64; i++)
4619 if (i == 6 || i == 7)
4620 ok( dib_bits[i] == data[i + 82], "%d: got %08x\n", i, dib_bits[i] );
4622 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4623 memset( dib_bits, 0xaa, 64 * 4 );
4625 info->bmiHeader.biHeight = -5;
4626 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4627 ok( ret == 2, "got %d\n", ret );
4628 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4629 for (i = 40; i < 56; i++) ok( dib_bits[i] == data[i - 40], "%d: got %08x\n", i, dib_bits[i] );
4630 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4631 memset( dib_bits, 0xaa, 64 * 4 );
4633 ret = SetDIBitsToDevice( hdc, 7, 2, 8, 8, 1, 0, 0, 5, data, info, DIB_RGB_COLORS );
4634 ok( ret == 5, "got %d\n", ret );
4635 for (i = 0; i < 64; i++)
4636 if (i == 47 || i == 55 || i == 63)
4637 ok( dib_bits[i] == data[i - 46], "%d: got %08x\n", i, dib_bits[i] );
4639 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4640 memset( dib_bits, 0xaa, 64 * 4 );
4642 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4643 ok( ret == 5, "got %d\n", ret );
4644 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4645 memset( dib_bits, 0xaa, 64 * 4 );
4649 info->bmiHeader.biHeight = 8;
4650 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4651 ok( ret == 8, "got %d\n", ret );
4652 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4653 memset( dib_bits, 0xaa, 64 * 4 );
4655 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4656 ok( ret == 5, "got %d\n", ret );
4657 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4658 for (i = 16; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4659 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4660 memset( dib_bits, 0xaa, 64 * 4 );
4662 info->bmiHeader.biHeight = 16;
4663 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4664 ok( ret == 7, "got %d\n", ret );
4665 for (i = 0; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4666 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4667 memset( dib_bits, 0xaa, 64 * 4 );
4669 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, 0, -4, 1, 12, data, info, DIB_RGB_COLORS );
4670 ok( ret == 3, "got %d\n", ret );
4671 for (i = 0; i < 64; i++)
4672 if ((i >= 36 && i <= 39) || (i >= 44 && i <= 47) || (i >= 52 && i <= 55))
4673 ok( dib_bits[i] == inverted_data[i + 68], "%d: got %08x\n", i, dib_bits[i] );
4675 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4676 memset( dib_bits, 0xaa, 64 * 4 );
4678 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, -30, -30, 1, 12, data, info, DIB_RGB_COLORS );
4679 ok( ret == 0, "got %d\n", ret );
4680 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4681 memset( dib_bits, 0xaa, 64 * 4 );
4683 ret = SetDIBitsToDevice( hdc, 5, -5, 8, 16, -2, -4, 4, 12, data, info, DIB_RGB_COLORS );
4684 ok( ret == 8, "got %d\n", ret );
4685 for (i = 0; i < 64; i++)
4686 if (i == 7 || i == 15 || i == 23)
4687 ok( dib_bits[i] == inverted_data[i + 97], "%d: got %08x\n", i, dib_bits[i] );
4689 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4690 memset( dib_bits, 0xaa, 64 * 4 );
4692 info->bmiHeader.biHeight = 5;
4693 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4694 ok( ret == 2, "got %d\n", ret );
4695 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4696 for (i = 40; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4697 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4698 memset( dib_bits, 0xaa, 64 * 4 );
4700 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4701 ok( ret == 5, "got %d\n", ret );
4702 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4703 memset( dib_bits, 0xaa, 64 * 4 );
4706 DeleteObject( dib );
4707 HeapFree( GetProcessHeap(), 0, info );
4710 static void test_SetDIBitsToDevice_RLE8(void)
4714 HDC hdc = CreateCompatibleDC( 0 );
4715 BYTE rle8_data[20] = { 0x04, 0x02, 0x03, 0xf0, 0x00, 0x00, /* 2, 2, 2, 2, f0, f0, f0, <eol> */
4716 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4717 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4718 0x00, 0x01 }; /* <eod> */
4721 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4722 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4723 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4724 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4725 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4726 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4727 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4728 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4729 DWORD top_down[64] = { 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 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4734 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4735 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4736 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4738 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4740 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4741 info->bmiHeader.biWidth = 8;
4742 info->bmiHeader.biHeight = 8;
4743 info->bmiHeader.biPlanes = 1;
4744 info->bmiHeader.biBitCount = 32;
4745 info->bmiHeader.biCompression = BI_RGB;
4747 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4748 memset( dib_bits, 0xaa, 64 * 4 );
4749 SelectObject( hdc, dib );
4751 info->bmiHeader.biBitCount = 8;
4752 info->bmiHeader.biCompression = BI_RLE8;
4753 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4755 for (i = 0; i < 256; i++)
4757 info->bmiColors[i].rgbRed = i;
4758 info->bmiColors[i].rgbGreen = i;
4759 info->bmiColors[i].rgbBlue = i;
4760 info->bmiColors[i].rgbReserved = 0;
4763 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4764 ok( ret == 8, "got %d\n", ret );
4765 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4766 memset( dib_bits, 0xaa, 64 * 4 );
4768 /* startscan and lines are ignored, unless lines == 0 */
4769 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4770 ok( ret == 8, "got %d\n", ret );
4771 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4772 memset( dib_bits, 0xaa, 64 * 4 );
4774 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4775 ok( ret == 8, "got %d\n", ret );
4776 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4777 memset( dib_bits, 0xaa, 64 * 4 );
4779 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4780 ok( ret == 0, "got %d\n", ret );
4781 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4782 memset( dib_bits, 0xaa, 64 * 4 );
4784 info->bmiHeader.biWidth = 2;
4785 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4786 ok( ret == 8, "got %d\n", ret );
4787 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4788 memset( dib_bits, 0xaa, 64 * 4 );
4790 info->bmiHeader.biWidth = 8;
4791 info->bmiHeader.biHeight = 2;
4792 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4793 ok( ret == 2, "got %d\n", ret );
4794 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4795 memset( dib_bits, 0xaa, 64 * 4 );
4797 info->bmiHeader.biHeight = 9;
4798 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4799 ok( ret == 9, "got %d\n", ret );
4800 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4801 memset( dib_bits, 0xaa, 64 * 4 );
4803 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4804 ok( ret == 9, "got %d\n", ret );
4805 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4806 memset( dib_bits, 0xaa, 64 * 4 );
4808 info->bmiHeader.biHeight = 8;
4809 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 9, rle8_data, info, DIB_RGB_COLORS );
4810 ok( ret == 8, "got %d\n", ret );
4811 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4812 memset( dib_bits, 0xaa, 64 * 4 );
4814 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4815 ok( ret == 8, "got %d\n", ret );
4816 for (i = 0; i < 40; i++) ok( dib_bits[i] == bottom_up[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4817 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4818 memset( dib_bits, 0xaa, 64 * 4 );
4820 ret = SetDIBitsToDevice( hdc, 0, 3, 4, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4821 ok( ret == 8, "got %d\n", ret );
4822 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4823 for (i = 8; i < 40; i++)
4824 if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4825 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4826 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4827 memset( dib_bits, 0xaa, 64 * 4 );
4829 ret = SetDIBitsToDevice( hdc, 3, 3, 8, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4830 ok( ret == 8, "got %d\n", ret );
4831 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4832 for (i = 8; i < 40; i++)
4833 if ((i & 7) < 3) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4834 else ok( dib_bits[i] == bottom_up[i - 11], "%d: got %08x\n", i, dib_bits[i] );
4835 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4836 memset( dib_bits, 0xaa, 64 * 4 );
4838 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 4, 2, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4839 ok( ret == 8, "got %d\n", ret );
4840 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4841 for (i = 8; i < 40; i++)
4842 if ((i & 7) < 2) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4843 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4844 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4845 memset( dib_bits, 0xaa, 64 * 4 );
4847 info->bmiHeader.biWidth = 37;
4848 info->bmiHeader.biHeight = 37;
4849 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
4850 ok( ret == 37, "got %d\n", ret );
4851 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4852 for (i = 24; i < 64; i++)
4853 if (i == 52) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
4854 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4855 else ok( dib_bits[i] == bottom_up[i - 20], "%d: got %08x\n", i, dib_bits[i] );
4856 memset( dib_bits, 0xaa, 64 * 4 );
4858 /* top-down compressed dibs are invalid */
4859 info->bmiHeader.biWidth = 8;
4860 info->bmiHeader.biHeight = -8;
4861 SetLastError( 0xdeadbeef );
4862 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4863 ok( ret == 0, "got %d\n", ret );
4864 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4868 info->bmiHeader.biHeight = -8;
4869 info->bmiHeader.biBitCount = 32;
4870 info->bmiHeader.biCompression = BI_RGB;
4871 info->bmiHeader.biSizeImage = 0;
4873 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4874 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4875 DeleteObject( SelectObject( hdc, dib ));
4877 info->bmiHeader.biHeight = 8;
4878 info->bmiHeader.biBitCount = 8;
4879 info->bmiHeader.biCompression = BI_RLE8;
4880 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4882 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4883 ok( ret == 8, "got %d\n", ret );
4884 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4885 memset( dib_bits, 0xaa, 64 * 4 );
4887 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4888 ok( ret == 8, "got %d\n", ret );
4889 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4890 memset( dib_bits, 0xaa, 64 * 4 );
4892 info->bmiHeader.biHeight = 4;
4893 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4894 ok( ret == 4, "got %d\n", ret );
4895 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4896 memset( dib_bits, 0xaa, 64 * 4 );
4898 info->bmiHeader.biHeight = 9;
4899 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4900 ok( ret == 9, "got %d\n", ret );
4901 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4902 memset( dib_bits, 0xaa, 64 * 4 );
4904 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4905 ok( ret == 9, "got %d\n", ret );
4906 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4907 memset( dib_bits, 0xaa, 64 * 4 );
4909 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 6, 2, 2, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4910 ok( ret == 9, "got %d\n", ret );
4911 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4912 for (i = 24; i < 64; i++) ok( dib_bits[i] == top_down[i - 24], "%d: got %08x\n", i, dib_bits[i] );
4913 memset( dib_bits, 0xaa, 64 * 4 );
4915 info->bmiHeader.biWidth = 37;
4916 info->bmiHeader.biHeight = 37;
4917 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
4918 ok( ret == 37, "got %d\n", ret );
4919 for (i = 0; i < 40; i++)
4920 if (i == 12) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
4921 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4922 else ok( dib_bits[i] == top_down[i + 28], "%d: got %08x\n", i, dib_bits[i] );
4923 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4924 memset( dib_bits, 0xaa, 64 * 4 );
4927 DeleteObject( dib );
4928 HeapFree( GetProcessHeap(), 0, info );
4935 hdll = GetModuleHandle("gdi32.dll");
4936 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
4937 pSetLayout = (void*)GetProcAddress(hdll, "SetLayout");
4939 test_createdibitmap();
4942 test_mono_dibsection();
4945 test_GetDIBits_selected_DIB(1);
4946 test_GetDIBits_selected_DIB(4);
4947 test_GetDIBits_selected_DIB(8);
4948 test_GetDIBits_selected_DDB(TRUE);
4949 test_GetDIBits_selected_DDB(FALSE);
4951 test_GetDIBits_BI_BITFIELDS();
4952 test_select_object();
4953 test_CreateBitmap();
4956 test_StretchDIBits();
4957 test_GdiAlphaBlend();
4958 test_32bit_bitmap_blt();
4959 test_bitmapinfoheadersize();
4962 test_GetDIBits_top_down(16);
4963 test_GetDIBits_top_down(24);
4964 test_GetDIBits_top_down(32);
4965 test_GetSetDIBits_rtl();
4966 test_GetDIBits_scanlines();
4968 test_SetDIBits_RLE4();
4969 test_SetDIBits_RLE8();
4970 test_SetDIBitsToDevice();
4971 test_SetDIBitsToDevice_RLE8();