2 * Unit test suite for bitmaps
4 * Copyright 2004 Huw Davies
5 * Copyright 2006 Dmitry Timoshkov
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
33 #include "wine/test.h"
35 static BOOL (WINAPI *pGdiAlphaBlend)(HDC,int,int,int,int,HDC,int,int,int,int,BLENDFUNCTION);
36 static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
38 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
40 static inline int get_bitmap_stride( int width, int bpp )
42 return ((width * bpp + 15) >> 3) & ~1;
45 static inline int get_dib_stride( int width, int bpp )
47 return ((width * bpp + 31) >> 3) & ~3;
50 static inline int get_dib_image_size( const BITMAPINFO *info )
52 return get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount )
53 * abs( info->bmiHeader.biHeight );
56 static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHEADER *bmih)
61 BYTE buf[512], buf_cmp[512];
63 ret = GetObject(hbm, sizeof(bm), &bm);
64 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
66 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
67 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
68 ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
69 width_bytes = get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel);
70 ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
71 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
72 ok(bm.bmBitsPixel == expected_depth, "wrong bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, expected_depth);
73 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
75 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
76 assert(sizeof(buf) == sizeof(buf_cmp));
78 SetLastError(0xdeadbeef);
79 ret = GetBitmapBits(hbm, 0, NULL);
80 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
82 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
83 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
85 memset(buf, 0xAA, sizeof(buf));
86 ret = GetBitmapBits(hbm, sizeof(buf), buf);
87 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
88 ok(!memcmp(buf, buf_cmp, sizeof(buf)),
89 "buffers do not match, depth %d\n", bmih->biBitCount);
91 /* test various buffer sizes for GetObject */
92 ret = GetObject(hbm, sizeof(*bma) * 2, bma);
93 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
95 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
96 ok(ret == 0, "%d != 0\n", ret);
98 ret = GetObject(hbm, 0, &bm);
99 ok(ret == 0, "%d != 0\n", ret);
101 ret = GetObject(hbm, 1, &bm);
102 ok(ret == 0, "%d != 0\n", ret);
104 ret = GetObject(hbm, 0, NULL);
105 ok(ret == sizeof(bm), "wrong size %d\n", ret);
108 static void test_createdibitmap(void)
111 BITMAPINFOHEADER bmih;
113 HBITMAP hbm, hbm_colour, hbm_old;
118 screen_depth = GetDeviceCaps(hdc, BITSPIXEL);
119 memset(&bmih, 0, sizeof(bmih));
120 bmih.biSize = sizeof(bmih);
124 bmih.biBitCount = 32;
125 bmih.biCompression = BI_RGB;
127 hbm = CreateDIBitmap(hdc, NULL, CBM_INIT, NULL, NULL, 0);
128 ok(hbm == NULL, "CreateDIBitmap should fail\n");
129 hbm = CreateDIBitmap(hdc, NULL, 0, NULL, NULL, 0);
130 ok(hbm == NULL, "CreateDIBitmap should fail\n");
132 /* First create an un-initialised bitmap. The depth of the bitmap
133 should match that of the hdc and not that supplied in bmih.
136 /* First try 32 bits */
137 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
138 ok(hbm != NULL, "CreateDIBitmap failed\n");
139 test_bitmap_info(hbm, screen_depth, &bmih);
143 bmih.biBitCount = 16;
144 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
145 ok(hbm != NULL, "CreateDIBitmap failed\n");
146 test_bitmap_info(hbm, screen_depth, &bmih);
151 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
152 ok(hbm != NULL, "CreateDIBitmap failed\n");
153 test_bitmap_info(hbm, screen_depth, &bmih);
156 /* Now with a monochrome dc we expect a monochrome bitmap */
157 hdcmem = CreateCompatibleDC(hdc);
159 /* First try 32 bits */
160 bmih.biBitCount = 32;
161 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
162 ok(hbm != NULL, "CreateDIBitmap failed\n");
163 test_bitmap_info(hbm, 1, &bmih);
167 bmih.biBitCount = 16;
168 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
169 ok(hbm != NULL, "CreateDIBitmap failed\n");
170 test_bitmap_info(hbm, 1, &bmih);
175 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
176 ok(hbm != NULL, "CreateDIBitmap failed\n");
177 test_bitmap_info(hbm, 1, &bmih);
180 /* Now select a polychrome bitmap into the dc and we expect
181 screen_depth bitmaps again */
182 hbm_colour = CreateCompatibleBitmap(hdc, bmih.biWidth, bmih.biHeight);
183 test_bitmap_info(hbm_colour, screen_depth, &bmih);
184 hbm_old = SelectObject(hdcmem, hbm_colour);
186 /* First try 32 bits */
187 bmih.biBitCount = 32;
188 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
189 ok(hbm != NULL, "CreateDIBitmap failed\n");
190 test_bitmap_info(hbm, screen_depth, &bmih);
194 bmih.biBitCount = 16;
195 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
196 ok(hbm != NULL, "CreateDIBitmap failed\n");
197 test_bitmap_info(hbm, screen_depth, &bmih);
202 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
203 ok(hbm != NULL, "CreateDIBitmap failed\n");
204 test_bitmap_info(hbm, screen_depth, &bmih);
207 SelectObject(hdcmem, hbm_old);
208 DeleteObject(hbm_colour);
211 bmih.biBitCount = 32;
212 hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0);
213 ok(hbm != NULL, "CreateDIBitmap failed\n");
214 test_bitmap_info(hbm, 1, &bmih);
217 /* Test how formats are converted */
223 memset(&bm, 0, sizeof(bm));
224 bm.bmiHeader.biSize = sizeof(bm.bmiHeader);
225 bm.bmiHeader.biWidth = 1;
226 bm.bmiHeader.biHeight = 1;
227 bm.bmiHeader.biPlanes = 1;
228 bm.bmiHeader.biBitCount= 24;
229 bm.bmiHeader.biCompression= BI_RGB;
230 bm.bmiHeader.biSizeImage = 0;
231 hbm = CreateDIBitmap(hdc, &bmih, CBM_INIT, &pixel, &bm, DIB_RGB_COLORS);
232 ok(hbm != NULL, "CreateDIBitmap failed\n");
235 bm.bmiHeader.biBitCount= 32;
236 GetDIBits(hdc, hbm, 0, 1, &pixel, &bm, DIB_RGB_COLORS);
237 ok(pixel == 0x00ffffff, "Reading a 32 bit pixel from a DDB returned %08x\n", pixel);
243 static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
249 INT ret, bm_width_bytes, dib_width_bytes;
252 ret = GetObject(hbm, sizeof(bm), &bm);
253 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
255 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
256 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
257 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
258 dib_width_bytes = get_dib_stride(bm.bmWidth, bm.bmBitsPixel);
259 bm_width_bytes = get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel);
260 if (bm.bmWidthBytes != dib_width_bytes) /* Win2k bug */
261 ok(bm.bmWidthBytes == bm_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, bm_width_bytes);
263 ok(bm.bmWidthBytes == dib_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, dib_width_bytes);
264 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
265 ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount);
266 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
268 buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);
270 /* GetBitmapBits returns not 32-bit aligned data */
271 SetLastError(0xdeadbeef);
272 ret = GetBitmapBits(hbm, 0, NULL);
273 ok(ret == bm_width_bytes * bm.bmHeight,
274 "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
276 memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
277 ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
278 ok(ret == bm_width_bytes * bm.bmHeight, "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
280 HeapFree(GetProcessHeap(), 0, buf);
282 /* test various buffer sizes for GetObject */
283 memset(&ds, 0xAA, sizeof(ds));
284 ret = GetObject(hbm, sizeof(*bma) * 2, bma);
285 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
286 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
287 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
288 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
290 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
291 ok(ret == 0, "%d != 0\n", ret);
293 ret = GetObject(hbm, 0, &bm);
294 ok(ret == 0, "%d != 0\n", ret);
296 ret = GetObject(hbm, 1, &bm);
297 ok(ret == 0, "%d != 0\n", ret);
299 /* test various buffer sizes for GetObject */
300 ret = GetObject(hbm, 0, NULL);
301 ok(ret == sizeof(bm), "wrong size %d\n", ret);
303 ret = GetObject(hbm, sizeof(*dsa) * 2, dsa);
304 ok(ret == sizeof(*dsa), "wrong size %d\n", ret);
306 memset(&ds, 0xAA, sizeof(ds));
307 ret = GetObject(hbm, sizeof(ds), &ds);
308 ok(ret == sizeof(ds), "wrong size %d\n", ret);
310 ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
311 if (ds.dsBm.bmWidthBytes != bm_width_bytes) /* Win2k bug */
312 ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%u != %u\n",
313 ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
314 ok(bmih->biSizeImage == 0, "%u != 0\n", bmih->biSizeImage);
315 ds.dsBmih.biSizeImage = 0;
317 ok(ds.dsBmih.biSize == bmih->biSize, "%u != %u\n", ds.dsBmih.biSize, bmih->biSize);
318 ok(ds.dsBmih.biWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
319 ok(ds.dsBmih.biHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
320 ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes);
321 ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount);
322 ok(ds.dsBmih.biCompression == bmih->biCompression ||
323 ((bmih->biBitCount == 32) && broken(ds.dsBmih.biCompression == BI_BITFIELDS)), /* nt4 sp1 and 2 */
324 "%u != %u\n", ds.dsBmih.biCompression, bmih->biCompression);
325 ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%u != %u\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
326 ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%d != %d\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
327 ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%d != %d\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);
329 memset(&ds, 0xAA, sizeof(ds));
330 ret = GetObject(hbm, sizeof(ds) - 4, &ds);
331 ok(ret == sizeof(ds.dsBm), "wrong size %d\n", ret);
332 ok(ds.dsBm.bmWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
333 ok(ds.dsBm.bmHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
334 ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);
336 ret = GetObject(hbm, 0, &ds);
337 ok(ret == 0, "%d != 0\n", ret);
339 ret = GetObject(hbm, 1, &ds);
340 ok(ret == 0, "%d != 0\n", ret);
343 #define test_color_todo(got, exp, txt, todo) \
344 if (!todo && got != exp && screen_depth < 24) { \
345 todo_wine ok(0, #txt " failed at %d-bit screen depth: got 0x%06x expected 0x%06x - skipping DIB tests\n", \
346 screen_depth, (UINT)got, (UINT)exp); \
348 } else if (todo) todo_wine { ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp); } \
349 else ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp) \
351 #define test_color(hdc, color, exp, todo_setp, todo_getp) \
354 c = SetPixel(hdc, 0, 0, color); \
355 test_color_todo(c, exp, SetPixel, todo_setp); \
356 c = GetPixel(hdc, 0, 0); \
357 test_color_todo(c, exp, GetPixel, todo_getp); \
360 static void test_dib_bits_access( HBITMAP hdib, void *bits )
362 MEMORY_BASIC_INFORMATION info;
363 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
365 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
367 char filename[MAX_PATH];
372 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
373 "VirtualQuery failed\n");
374 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
375 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
376 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
377 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
378 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
379 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
381 memset( pbmi, 0, sizeof(bmibuf) );
382 memset( data, 0xcc, sizeof(data) );
383 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
384 pbmi->bmiHeader.biHeight = 16;
385 pbmi->bmiHeader.biWidth = 16;
386 pbmi->bmiHeader.biBitCount = 32;
387 pbmi->bmiHeader.biPlanes = 1;
388 pbmi->bmiHeader.biCompression = BI_RGB;
392 ret = SetDIBits( hdc, hdib, 0, 16, data, pbmi, DIB_RGB_COLORS );
393 ok(ret == 16, "SetDIBits failed: expected 16 got %d\n", ret);
397 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
398 "VirtualQuery failed\n");
399 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
400 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
401 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
402 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
403 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
404 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
406 /* try writing protected bits to a file */
408 GetTempFileNameA( ".", "dib", 0, filename );
409 file = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
410 CREATE_ALWAYS, 0, 0 );
411 ok( file != INVALID_HANDLE_VALUE, "failed to open %s error %u\n", filename, GetLastError() );
412 ret = WriteFile( file, bits, 8192, &written, NULL );
413 ok( ret, "WriteFile failed error %u\n", GetLastError() );
414 if (ret) ok( written == 8192, "only wrote %u bytes\n", written );
416 DeleteFileA( filename );
419 static void test_dibsections(void)
421 HDC hdc, hdcmem, hdcmem2;
422 HBITMAP hdib, oldbm, hdib2, oldbm2;
423 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
424 char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
425 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
426 BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
432 char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
433 LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
436 HPALETTE hpal, oldpal;
441 MEMORY_BASIC_INFORMATION info;
444 screen_depth = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
446 memset(pbmi, 0, sizeof(bmibuf));
447 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
448 pbmi->bmiHeader.biHeight = 100;
449 pbmi->bmiHeader.biWidth = 512;
450 pbmi->bmiHeader.biBitCount = 24;
451 pbmi->bmiHeader.biPlanes = 1;
452 pbmi->bmiHeader.biCompression = BI_RGB;
454 SetLastError(0xdeadbeef);
456 /* invalid pointer for BITMAPINFO
457 (*bits should be NULL on error) */
458 bits = (BYTE*)0xdeadbeef;
459 hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
460 ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n");
462 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
463 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
464 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
465 ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
467 /* test the DIB memory */
468 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
469 "VirtualQuery failed\n");
470 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
471 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
472 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
473 ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
474 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
475 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
476 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
478 test_dib_bits_access( hdib, bits );
480 test_dib_info(hdib, bits, &pbmi->bmiHeader);
483 /* Test a top-down DIB. */
484 pbmi->bmiHeader.biHeight = -100;
485 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
486 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
487 test_dib_info(hdib, bits, &pbmi->bmiHeader);
490 pbmi->bmiHeader.biHeight = 100;
491 pbmi->bmiHeader.biBitCount = 8;
492 pbmi->bmiHeader.biCompression = BI_RLE8;
493 SetLastError(0xdeadbeef);
494 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
495 ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
496 ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
498 pbmi->bmiHeader.biBitCount = 16;
499 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
500 ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
501 ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
502 ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
503 SetLastError(0xdeadbeef);
504 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
505 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
507 /* test the DIB memory */
508 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
509 "VirtualQuery failed\n");
510 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
511 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
512 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
513 ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
514 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
515 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
516 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
518 test_dib_info(hdib, bits, &pbmi->bmiHeader);
521 memset(pbmi, 0, sizeof(bmibuf));
522 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
523 pbmi->bmiHeader.biHeight = 16;
524 pbmi->bmiHeader.biWidth = 16;
525 pbmi->bmiHeader.biBitCount = 1;
526 pbmi->bmiHeader.biPlanes = 1;
527 pbmi->bmiHeader.biCompression = BI_RGB;
528 pbmi->bmiColors[0].rgbRed = 0xff;
529 pbmi->bmiColors[0].rgbGreen = 0;
530 pbmi->bmiColors[0].rgbBlue = 0;
531 pbmi->bmiColors[1].rgbRed = 0;
532 pbmi->bmiColors[1].rgbGreen = 0;
533 pbmi->bmiColors[1].rgbBlue = 0xff;
535 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
536 ok(hdib != NULL, "CreateDIBSection failed\n");
537 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
538 ok(dibsec.dsBmih.biClrUsed == 2,
539 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
541 /* Test if the old BITMAPCOREINFO structure is supported */
543 pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
544 pbci->bmciHeader.bcBitCount = 0;
546 ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
547 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
548 ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
549 && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
550 "GetDIBits didn't fill in the BITMAPCOREHEADER structure properly\n");
552 ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
553 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
554 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
555 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
556 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
557 "The color table has not been translated to the old BITMAPCOREINFO format\n");
559 hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
560 ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
562 ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
563 ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
564 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
565 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
566 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
567 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
568 "The color table has not been translated to the old BITMAPCOREINFO format\n");
570 DeleteObject(hcoredib);
572 hdcmem = CreateCompatibleDC(hdc);
573 oldbm = SelectObject(hdcmem, hdib);
575 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
576 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
577 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
578 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
579 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
580 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
582 c0 = RGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen, pbmi->bmiColors[0].rgbBlue);
583 c1 = RGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen, pbmi->bmiColors[1].rgbBlue);
585 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
586 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
587 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
588 test_color(hdcmem, PALETTEINDEX(0), c0, 1, 1);
589 test_color(hdcmem, PALETTEINDEX(1), c0, 1, 1);
590 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
591 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen,
592 pbmi->bmiColors[0].rgbBlue), c0, 1, 1);
593 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen,
594 pbmi->bmiColors[1].rgbBlue), c1, 1, 1);
595 test_color(hdcmem, PALETTERGB(0, 0, 0), c0, 1, 1);
596 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
597 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1, 1, 1);
599 SelectObject(hdcmem, oldbm);
602 pbmi->bmiColors[0].rgbRed = 0xff;
603 pbmi->bmiColors[0].rgbGreen = 0xff;
604 pbmi->bmiColors[0].rgbBlue = 0xff;
605 pbmi->bmiColors[1].rgbRed = 0;
606 pbmi->bmiColors[1].rgbGreen = 0;
607 pbmi->bmiColors[1].rgbBlue = 0;
609 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
610 ok(hdib != NULL, "CreateDIBSection failed\n");
612 test_dib_info(hdib, bits, &pbmi->bmiHeader);
614 oldbm = SelectObject(hdcmem, hdib);
616 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
617 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
618 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
619 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
620 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
621 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
623 SelectObject(hdcmem, oldbm);
624 test_dib_info(hdib, bits, &pbmi->bmiHeader);
627 pbmi->bmiHeader.biBitCount = 4;
628 for (i = 0; i < 16; i++) {
629 pbmi->bmiColors[i].rgbRed = i;
630 pbmi->bmiColors[i].rgbGreen = 16-i;
631 pbmi->bmiColors[i].rgbBlue = 0;
633 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
634 ok(hdib != NULL, "CreateDIBSection failed\n");
635 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
636 ok(dibsec.dsBmih.biClrUsed == 16,
637 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
638 test_dib_info(hdib, bits, &pbmi->bmiHeader);
641 pbmi->bmiHeader.biBitCount = 8;
643 for (i = 0; i < 128; i++) {
644 pbmi->bmiColors[i].rgbRed = 255 - i * 2;
645 pbmi->bmiColors[i].rgbGreen = i * 2;
646 pbmi->bmiColors[i].rgbBlue = 0;
647 pbmi->bmiColors[255 - i].rgbRed = 0;
648 pbmi->bmiColors[255 - i].rgbGreen = i * 2;
649 pbmi->bmiColors[255 - i].rgbBlue = 255 - i * 2;
651 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
652 ok(hdib != NULL, "CreateDIBSection failed\n");
653 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
654 ok(dibsec.dsBmih.biClrUsed == 256,
655 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
657 oldbm = SelectObject(hdcmem, hdib);
659 for (i = 0; i < 256; i++) {
660 test_color(hdcmem, DIBINDEX(i),
661 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
662 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue),
663 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
666 SelectObject(hdcmem, oldbm);
667 test_dib_info(hdib, bits, &pbmi->bmiHeader);
670 pbmi->bmiHeader.biBitCount = 1;
672 /* Now create a palette and a palette indexed dib section */
673 memset(plogpal, 0, sizeof(logpalbuf));
674 plogpal->palVersion = 0x300;
675 plogpal->palNumEntries = 2;
676 plogpal->palPalEntry[0].peRed = 0xff;
677 plogpal->palPalEntry[0].peBlue = 0xff;
678 plogpal->palPalEntry[1].peGreen = 0xff;
680 index = (WORD*)pbmi->bmiColors;
683 hpal = CreatePalette(plogpal);
684 ok(hpal != NULL, "CreatePalette failed\n");
685 oldpal = SelectPalette(hdc, hpal, TRUE);
686 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
687 ok(hdib != NULL, "CreateDIBSection failed\n");
688 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
689 ok(dibsec.dsBmih.biClrUsed == 2, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
691 /* The colour table has already been grabbed from the dc, so we select back the
694 SelectPalette(hdc, oldpal, TRUE);
695 oldbm = SelectObject(hdcmem, hdib);
696 oldpal = SelectPalette(hdcmem, hpal, TRUE);
698 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
699 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
700 ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
701 rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
702 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
703 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
704 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
706 c0 = RGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen, plogpal->palPalEntry[0].peBlue);
707 c1 = RGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen, plogpal->palPalEntry[1].peBlue);
709 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
710 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
711 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
712 test_color(hdcmem, PALETTEINDEX(0), c0, 0, 1);
713 test_color(hdcmem, PALETTEINDEX(1), c1, 0, 1);
714 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
715 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen,
716 plogpal->palPalEntry[0].peBlue), c0, 1, 1);
717 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen,
718 plogpal->palPalEntry[1].peBlue), c1, 1, 1);
719 test_color(hdcmem, PALETTERGB(0, 0, 0), c1, 1, 1);
720 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
721 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0, 1, 1);
722 test_color(hdcmem, PALETTERGB(0, 1, 0), c1, 1, 1);
723 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1, 1, 1);
724 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0, 1, 1);
726 /* Bottom and 2nd row from top green, everything else magenta */
727 bits[0] = bits[1] = 0xff;
728 bits[13 * 4] = bits[13*4 + 1] = 0xff;
730 test_dib_info(hdib, bits, &pbmi->bmiHeader);
732 pbmi->bmiHeader.biBitCount = 32;
734 hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
735 ok(hdib2 != NULL, "CreateDIBSection failed\n");
736 hdcmem2 = CreateCompatibleDC(hdc);
737 oldbm2 = SelectObject(hdcmem2, hdib2);
739 BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
741 ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
742 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
744 SelectObject(hdcmem2, oldbm2);
745 test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
748 SelectObject(hdcmem, oldbm);
749 SelectPalette(hdcmem, oldpal, TRUE);
754 pbmi->bmiHeader.biBitCount = 8;
756 memset(plogpal, 0, sizeof(logpalbuf));
757 plogpal->palVersion = 0x300;
758 plogpal->palNumEntries = 256;
760 for (i = 0; i < 128; i++) {
761 plogpal->palPalEntry[i].peRed = 255 - i * 2;
762 plogpal->palPalEntry[i].peBlue = i * 2;
763 plogpal->palPalEntry[i].peGreen = 0;
764 plogpal->palPalEntry[255 - i].peRed = 0;
765 plogpal->palPalEntry[255 - i].peGreen = i * 2;
766 plogpal->palPalEntry[255 - i].peBlue = 255 - i * 2;
769 index = (WORD*)pbmi->bmiColors;
770 for (i = 0; i < 256; i++) {
774 hpal = CreatePalette(plogpal);
775 ok(hpal != NULL, "CreatePalette failed\n");
776 oldpal = SelectPalette(hdc, hpal, TRUE);
777 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
778 ok(hdib != NULL, "CreateDIBSection failed\n");
779 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
780 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
782 test_dib_info(hdib, bits, &pbmi->bmiHeader);
784 SelectPalette(hdc, oldpal, TRUE);
785 oldbm = SelectObject(hdcmem, hdib);
786 oldpal = SelectPalette(hdcmem, hpal, TRUE);
788 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
789 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
790 for (i = 0; i < 256; i++) {
791 ok(rgb[i].rgbRed == plogpal->palPalEntry[i].peRed &&
792 rgb[i].rgbBlue == plogpal->palPalEntry[i].peBlue &&
793 rgb[i].rgbGreen == plogpal->palPalEntry[i].peGreen,
794 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
795 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
798 for (i = 0; i < 256; i++) {
799 test_color(hdcmem, DIBINDEX(i),
800 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
801 test_color(hdcmem, PALETTEINDEX(i),
802 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
803 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue),
804 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
807 SelectPalette(hdcmem, oldpal, TRUE);
808 SelectObject(hdcmem, oldbm);
817 static void test_dib_formats(void)
822 int planes, bpp, compr;
826 BOOL expect_ok, todo;
828 bi = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
830 memdc = CreateCompatibleDC( 0 );
831 hbmp = CreateCompatibleBitmap( hdc, 10, 10 );
833 memset( data, 0xaa, sizeof(data) );
835 for (bpp = 0; bpp <= 64; bpp++)
837 for (planes = 0; planes <= 64; planes++)
839 for (compr = 0; compr < 8; compr++)
846 case 24: expect_ok = (compr == BI_RGB); break;
848 case 32: expect_ok = (compr == BI_RGB || compr == BI_BITFIELDS); break;
849 default: expect_ok = FALSE; break;
851 todo = (compr == BI_BITFIELDS); /* wine doesn't like strange bitfields */
853 memset( bi, 0, sizeof(bi->bmiHeader) );
854 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
855 bi->bmiHeader.biWidth = 2;
856 bi->bmiHeader.biHeight = 2;
857 bi->bmiHeader.biPlanes = planes;
858 bi->bmiHeader.biBitCount = bpp;
859 bi->bmiHeader.biCompression = compr;
860 bi->bmiHeader.biSizeImage = 0;
861 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
862 ret = GetDIBits(hdc, hbmp, 0, 0, data, bi, DIB_RGB_COLORS);
863 if (expect_ok || (!bpp && compr != BI_JPEG && compr != BI_PNG) ||
864 (bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8))
865 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
867 ok( !ret || broken(!bpp && (compr == BI_JPEG || compr == BI_PNG)), /* nt4 */
868 "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
870 /* all functions check planes except GetDIBits with 0 lines */
871 if (!planes) expect_ok = FALSE;
872 memset( bi, 0, sizeof(bi->bmiHeader) );
873 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
874 bi->bmiHeader.biWidth = 2;
875 bi->bmiHeader.biHeight = 2;
876 bi->bmiHeader.biPlanes = planes;
877 bi->bmiHeader.biBitCount = bpp;
878 bi->bmiHeader.biCompression = compr;
879 bi->bmiHeader.biSizeImage = 0;
880 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
882 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
883 if (expect_ok && (planes == 1 || planes * bpp <= 16))
884 ok( hdib != NULL, "CreateDIBSection failed for %u/%u/%u\n", bpp, planes, compr );
886 ok( hdib == NULL, "CreateDIBSection succeeded for %u/%u/%u\n", bpp, planes, compr );
887 if (hdib) DeleteObject( hdib );
889 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, data, bi, DIB_RGB_COLORS );
890 /* no sanity checks in CreateDIBitmap except compression */
891 if (compr == BI_JPEG || compr == BI_PNG)
892 ok( hdib == NULL || broken(hdib != NULL), /* nt4 */
893 "CreateDIBitmap succeeded for %u/%u/%u\n", bpp, planes, compr );
895 ok( hdib != NULL, "CreateDIBitmap failed for %u/%u/%u\n", bpp, planes, compr );
896 if (hdib) DeleteObject( hdib );
898 /* RLE needs a size */
899 bi->bmiHeader.biSizeImage = 0;
900 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
904 todo_wine ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
906 ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
910 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
911 "SetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
912 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
916 todo_wine ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
918 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
922 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
923 "SetDIBitsToDevice succeeded for %u/%u/%u\n", bpp, planes, compr );
924 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
928 todo_wine ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
930 ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
934 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
935 "StretchDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
937 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
939 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
941 ok( !ret, "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
942 ok( bi->bmiHeader.biBitCount == bpp, "GetDIBits modified bpp %u/%u\n",
943 bpp, bi->bmiHeader.biBitCount );
945 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
946 bi->bmiHeader.biWidth = 2;
947 bi->bmiHeader.biHeight = 2;
948 bi->bmiHeader.biPlanes = planes;
949 bi->bmiHeader.biBitCount = bpp;
950 bi->bmiHeader.biCompression = compr;
951 bi->bmiHeader.biSizeImage = 1;
952 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
953 /* RLE allowed with valid biSizeImage */
954 if ((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)) expect_ok = TRUE;
956 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
960 todo_wine ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
962 ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
965 ok( !ret, "SetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
966 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
970 todo_wine ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
972 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
975 ok( !ret, "SetDIBitsToDevice succeeded for %u/%u/%u\n", bpp, planes, compr );
976 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
980 todo_wine ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
982 ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
985 ok( !ret, "StretchDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
987 bi->bmiHeader.biSizeImage = 0;
988 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
989 if (expect_ok || !bpp)
990 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
992 ok( !ret, "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
997 memset( bi, 0, sizeof(bi->bmiHeader) );
998 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
999 bi->bmiHeader.biWidth = 2;
1000 bi->bmiHeader.biHeight = 2;
1001 bi->bmiHeader.biPlanes = 1;
1002 bi->bmiHeader.biBitCount = 16;
1003 bi->bmiHeader.biCompression = BI_BITFIELDS;
1004 bi->bmiHeader.biSizeImage = 0;
1005 *(DWORD *)&bi->bmiColors[0] = 0;
1006 *(DWORD *)&bi->bmiColors[1] = 0;
1007 *(DWORD *)&bi->bmiColors[2] = 0;
1009 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1010 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1011 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1012 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1013 /* other functions don't check */
1014 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1015 ok( hdib != NULL, "CreateDIBitmap failed with null bitfields\n" );
1016 DeleteObject( hdib );
1017 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1018 todo_wine ok( ret, "SetDIBitsToDevice failed with null bitfields\n" );
1019 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1020 todo_wine ok( ret, "StretchDIBits failed with null bitfields\n" );
1021 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1022 ok( ret, "GetDIBits failed with null bitfields\n" );
1023 bi->bmiHeader.biPlanes = 1;
1024 bi->bmiHeader.biBitCount = 16;
1025 bi->bmiHeader.biCompression = BI_BITFIELDS;
1026 bi->bmiHeader.biSizeImage = 0;
1027 *(DWORD *)&bi->bmiColors[0] = 0;
1028 *(DWORD *)&bi->bmiColors[1] = 0;
1029 *(DWORD *)&bi->bmiColors[2] = 0;
1030 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1031 ok( ret, "GetDIBits failed with null bitfields\n" );
1033 /* all fields must be non-zero */
1034 *(DWORD *)&bi->bmiColors[0] = 3;
1035 *(DWORD *)&bi->bmiColors[1] = 0;
1036 *(DWORD *)&bi->bmiColors[2] = 7;
1037 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1038 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1039 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1040 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1042 /* garbage is ok though */
1043 *(DWORD *)&bi->bmiColors[0] = 0x55;
1044 *(DWORD *)&bi->bmiColors[1] = 0x44;
1045 *(DWORD *)&bi->bmiColors[2] = 0x33;
1046 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1047 ok( hdib != NULL, "CreateDIBSection failed with bad bitfields\n" );
1048 if (hdib) DeleteObject( hdib );
1049 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1050 todo_wine ok( ret, "SetDIBits failed with bad bitfields\n" );
1052 bi->bmiHeader.biWidth = -2;
1053 bi->bmiHeader.biHeight = 2;
1054 bi->bmiHeader.biBitCount = 32;
1055 bi->bmiHeader.biCompression = BI_RGB;
1056 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1057 ok( hdib == NULL, "CreateDIBSection succeeded with negative width\n" );
1058 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1059 ok( hdib == NULL, "CreateDIBitmap succeeded with negative width\n" );
1060 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1061 ok( !ret, "SetDIBits succeeded with negative width\n" );
1062 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1063 ok( !ret, "SetDIBitsToDevice succeeded with negative width\n" );
1064 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1065 ok( !ret, "StretchDIBits succeeded with negative width\n" );
1066 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1067 ok( !ret, "GetDIBits succeeded with negative width\n" );
1068 bi->bmiHeader.biWidth = -2;
1069 bi->bmiHeader.biHeight = 2;
1070 bi->bmiHeader.biBitCount = 32;
1071 bi->bmiHeader.biCompression = BI_RGB;
1072 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1073 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with negative width\n" );
1075 bi->bmiHeader.biWidth = 0;
1076 bi->bmiHeader.biHeight = 2;
1077 bi->bmiHeader.biBitCount = 32;
1078 bi->bmiHeader.biCompression = BI_RGB;
1079 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1080 ok( hdib == NULL, "CreateDIBSection succeeded with zero width\n" );
1081 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1082 ok( hdib != NULL, "CreateDIBitmap failed with zero width\n" );
1083 DeleteObject( hdib );
1084 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1085 ok( !ret || broken(ret), /* nt4 */ "SetDIBits succeeded with zero width\n" );
1086 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1087 ok( !ret || broken(ret), /* nt4 */ "SetDIBitsToDevice succeeded with zero width\n" );
1088 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1089 ok( !ret || broken(ret), /* nt4 */ "StretchDIBits succeeded with zero width\n" );
1090 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1091 ok( !ret, "GetDIBits succeeded with zero width\n" );
1092 bi->bmiHeader.biWidth = 0;
1093 bi->bmiHeader.biHeight = 2;
1094 bi->bmiHeader.biBitCount = 32;
1095 bi->bmiHeader.biCompression = BI_RGB;
1096 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1097 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero width\n" );
1099 bi->bmiHeader.biWidth = 2;
1100 bi->bmiHeader.biHeight = 0;
1101 bi->bmiHeader.biBitCount = 32;
1102 bi->bmiHeader.biCompression = BI_RGB;
1103 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1104 ok( hdib == NULL, "CreateDIBSection succeeded with zero height\n" );
1105 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1106 ok( hdib != NULL, "CreateDIBitmap failed with zero height\n" );
1107 DeleteObject( hdib );
1108 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1109 ok( !ret, "SetDIBits succeeded with zero height\n" );
1110 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1111 ok( !ret, "SetDIBitsToDevice succeeded with zero height\n" );
1112 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1113 ok( !ret, "StretchDIBits succeeded with zero height\n" );
1114 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1115 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1116 bi->bmiHeader.biWidth = 2;
1117 bi->bmiHeader.biHeight = 0;
1118 bi->bmiHeader.biBitCount = 32;
1119 bi->bmiHeader.biCompression = BI_RGB;
1120 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1121 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1124 DeleteObject( hbmp );
1125 ReleaseDC( 0, hdc );
1126 HeapFree( GetProcessHeap(), 0, bi );
1129 static void test_mono_dibsection(void)
1132 HBITMAP old_bm, mono_ds;
1133 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
1134 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
1141 memdc = CreateCompatibleDC(hdc);
1143 memset(pbmi, 0, sizeof(bmibuf));
1144 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
1145 pbmi->bmiHeader.biHeight = 10;
1146 pbmi->bmiHeader.biWidth = 10;
1147 pbmi->bmiHeader.biBitCount = 1;
1148 pbmi->bmiHeader.biPlanes = 1;
1149 pbmi->bmiHeader.biCompression = BI_RGB;
1150 pbmi->bmiColors[0].rgbRed = 0xff;
1151 pbmi->bmiColors[0].rgbGreen = 0xff;
1152 pbmi->bmiColors[0].rgbBlue = 0xff;
1153 pbmi->bmiColors[1].rgbRed = 0x0;
1154 pbmi->bmiColors[1].rgbGreen = 0x0;
1155 pbmi->bmiColors[1].rgbBlue = 0x0;
1158 * First dib section is 'inverted' ie color[0] is white, color[1] is black
1161 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1162 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1163 old_bm = SelectObject(memdc, mono_ds);
1165 /* black border, white interior */
1166 Rectangle(memdc, 0, 0, 10, 10);
1167 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1168 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1170 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1172 memset(bits, 0, sizeof(bits));
1175 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1176 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1178 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1180 pbmi->bmiColors[0].rgbRed = 0x0;
1181 pbmi->bmiColors[0].rgbGreen = 0x0;
1182 pbmi->bmiColors[0].rgbBlue = 0x0;
1183 pbmi->bmiColors[1].rgbRed = 0xff;
1184 pbmi->bmiColors[1].rgbGreen = 0xff;
1185 pbmi->bmiColors[1].rgbBlue = 0xff;
1187 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1188 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1190 SelectObject(memdc, old_bm);
1191 DeleteObject(mono_ds);
1194 * Next dib section is 'normal' ie color[0] is black, color[1] is white
1197 pbmi->bmiColors[0].rgbRed = 0x0;
1198 pbmi->bmiColors[0].rgbGreen = 0x0;
1199 pbmi->bmiColors[0].rgbBlue = 0x0;
1200 pbmi->bmiColors[1].rgbRed = 0xff;
1201 pbmi->bmiColors[1].rgbGreen = 0xff;
1202 pbmi->bmiColors[1].rgbBlue = 0xff;
1204 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1205 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1206 old_bm = SelectObject(memdc, mono_ds);
1208 /* black border, white interior */
1209 Rectangle(memdc, 0, 0, 10, 10);
1210 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
1211 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
1213 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
1215 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1216 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1218 /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
1220 pbmi->bmiColors[0].rgbRed = 0xff;
1221 pbmi->bmiColors[0].rgbGreen = 0xff;
1222 pbmi->bmiColors[0].rgbBlue = 0xff;
1223 pbmi->bmiColors[1].rgbRed = 0x0;
1224 pbmi->bmiColors[1].rgbGreen = 0x0;
1225 pbmi->bmiColors[1].rgbBlue = 0x0;
1227 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1228 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1231 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
1234 pbmi->bmiColors[0].rgbRed = 0xff;
1235 pbmi->bmiColors[0].rgbGreen = 0xff;
1236 pbmi->bmiColors[0].rgbBlue = 0xff;
1237 pbmi->bmiColors[1].rgbRed = 0x0;
1238 pbmi->bmiColors[1].rgbGreen = 0x0;
1239 pbmi->bmiColors[1].rgbBlue = 0x0;
1240 num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors);
1241 ok(num == 2, "num = %d\n", num);
1243 /* black border, white interior */
1244 Rectangle(memdc, 0, 0, 10, 10);
1245 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1246 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1248 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1250 memset(bits, 0, sizeof(bits));
1253 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1254 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1256 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1258 pbmi->bmiColors[0].rgbRed = 0x0;
1259 pbmi->bmiColors[0].rgbGreen = 0x0;
1260 pbmi->bmiColors[0].rgbBlue = 0x0;
1261 pbmi->bmiColors[1].rgbRed = 0xff;
1262 pbmi->bmiColors[1].rgbGreen = 0xff;
1263 pbmi->bmiColors[1].rgbBlue = 0xff;
1265 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1266 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1268 SelectObject(memdc, old_bm);
1269 DeleteObject(mono_ds);
1272 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
1275 pbmi->bmiColors[0].rgbRed = 0xff;
1276 pbmi->bmiColors[0].rgbGreen = 0x0;
1277 pbmi->bmiColors[0].rgbBlue = 0x0;
1278 pbmi->bmiColors[1].rgbRed = 0xfe;
1279 pbmi->bmiColors[1].rgbGreen = 0x0;
1280 pbmi->bmiColors[1].rgbBlue = 0x0;
1282 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1283 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1284 old_bm = SelectObject(memdc, mono_ds);
1286 /* black border, white interior */
1287 Rectangle(memdc, 0, 0, 10, 10);
1288 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1289 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1291 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1293 pbmi->bmiColors[0].rgbRed = 0x0;
1294 pbmi->bmiColors[0].rgbGreen = 0x0;
1295 pbmi->bmiColors[0].rgbBlue = 0x0;
1296 pbmi->bmiColors[1].rgbRed = 0xff;
1297 pbmi->bmiColors[1].rgbGreen = 0xff;
1298 pbmi->bmiColors[1].rgbBlue = 0xff;
1300 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1301 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1303 /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
1305 pbmi->bmiColors[0].rgbRed = 0xff;
1306 pbmi->bmiColors[0].rgbGreen = 0xff;
1307 pbmi->bmiColors[0].rgbBlue = 0xff;
1308 pbmi->bmiColors[1].rgbRed = 0x0;
1309 pbmi->bmiColors[1].rgbGreen = 0x0;
1310 pbmi->bmiColors[1].rgbBlue = 0x0;
1312 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1313 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1315 SelectObject(memdc, old_bm);
1316 DeleteObject(mono_ds);
1322 static void test_bitmap(void)
1324 char buf[256], buf_cmp[256];
1325 HBITMAP hbmp, hbmp_old;
1331 hdc = CreateCompatibleDC(0);
1334 SetLastError(0xdeadbeef);
1335 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1338 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1339 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1340 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1345 SetLastError(0xdeadbeef);
1346 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1349 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1350 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1351 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1356 SetLastError(0xdeadbeef);
1357 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1358 ok(!hbmp, "CreateBitmap should fail\n");
1360 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1361 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1365 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1366 assert(hbmp != NULL);
1368 ret = GetObject(hbmp, sizeof(bm), &bm);
1369 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1371 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1372 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1373 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1374 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1375 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1376 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1377 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1379 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1380 assert(sizeof(buf) == sizeof(buf_cmp));
1382 ret = GetBitmapBits(hbmp, 0, NULL);
1383 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1385 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1386 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1388 memset(buf, 0xAA, sizeof(buf));
1389 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1390 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1391 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1393 hbmp_old = SelectObject(hdc, hbmp);
1395 ret = GetObject(hbmp, sizeof(bm), &bm);
1396 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1398 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1399 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1400 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1401 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1402 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1403 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1404 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1406 memset(buf, 0xAA, sizeof(buf));
1407 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1408 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1409 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1411 hbmp_old = SelectObject(hdc, hbmp_old);
1412 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1414 /* test various buffer sizes for GetObject */
1415 ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
1416 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1418 ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1419 ok(ret == 0, "%d != 0\n", ret);
1421 ret = GetObject(hbmp, 0, &bm);
1422 ok(ret == 0, "%d != 0\n", ret);
1424 ret = GetObject(hbmp, 1, &bm);
1425 ok(ret == 0, "%d != 0\n", ret);
1431 static void test_bmBits(void)
1437 memset(bits, 0, sizeof(bits));
1438 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1439 ok(hbmp != NULL, "CreateBitmap failed\n");
1441 memset(&bmp, 0xFF, sizeof(bmp));
1442 ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1443 "GetObject failed or returned a wrong structure size\n");
1444 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1449 static void test_GetDIBits_selected_DIB(UINT bpp)
1456 UINT dib_size, dib32_size;
1463 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1464 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1466 /* Create a DIB section with a color table */
1468 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1469 info->bmiHeader.biWidth = 32;
1470 info->bmiHeader.biHeight = 32;
1471 info->bmiHeader.biPlanes = 1;
1472 info->bmiHeader.biBitCount = bpp;
1473 info->bmiHeader.biCompression = BI_RGB;
1474 info->bmiHeader.biXPelsPerMeter = 0;
1475 info->bmiHeader.biYPelsPerMeter = 0;
1476 info->bmiHeader.biClrUsed = 0;
1477 info->bmiHeader.biClrImportant = 0;
1479 for (i=0; i < (1u << bpp); i++)
1481 BYTE c = i * (1 << (8 - bpp));
1482 info->bmiColors[i].rgbRed = c;
1483 info->bmiColors[i].rgbGreen = c;
1484 info->bmiColors[i].rgbBlue = c;
1485 info->bmiColors[i].rgbReserved = 0;
1488 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1489 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1490 dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1492 /* Set the bits of the DIB section */
1493 for (i=0; i < dib_size; i++)
1495 ((BYTE *)bits)[i] = i % 256;
1498 /* Select the DIB into a DC */
1499 dib_dc = CreateCompatibleDC(NULL);
1500 old_bmp = SelectObject(dib_dc, dib);
1501 dc = CreateCompatibleDC(NULL);
1502 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
1504 /* Copy the DIB attributes but not the color table */
1505 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1507 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1508 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1510 /* Compare the color table and the bits */
1511 for (i=0; i < (1u << bpp); i++)
1512 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1513 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1514 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1515 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1516 "color table entry %d differs (bpp %d)\n", i, bpp );
1518 ok( !memcmp( bits, bits2, dib_size ), "bit mismatch (bpp %d)\n", bpp );
1520 /* Test various combinations of lines = 0 and bits2 = NULL */
1521 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1522 res = GetDIBits( dc, dib, 0, 0, bits2, info2, DIB_RGB_COLORS );
1523 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1524 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1525 "color table mismatch (bpp %d)\n", bpp );
1527 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1528 res = GetDIBits( dc, dib, 0, 0, NULL, info2, DIB_RGB_COLORS );
1529 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1530 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1531 "color table mismatch (bpp %d)\n", bpp );
1533 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1534 res = GetDIBits( dc, dib, 0, info->bmiHeader.biHeight, NULL, info2, DIB_RGB_COLORS );
1535 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1536 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1537 "color table mismatch (bpp %d)\n", bpp );
1539 /* Map into a 32bit-DIB */
1540 info2->bmiHeader.biBitCount = 32;
1541 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1542 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1544 /* Check if last pixel was set */
1545 pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
1546 ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
1548 HeapFree(GetProcessHeap(), 0, bits2);
1551 SelectObject(dib_dc, old_bmp);
1554 HeapFree(GetProcessHeap(), 0, info2);
1555 HeapFree(GetProcessHeap(), 0, info);
1558 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1572 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1573 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1575 width = height = 16;
1577 /* Create a DDB (device-dependent bitmap) */
1581 ddb = CreateBitmap(width, height, 1, 1, NULL);
1585 HDC screen_dc = GetDC(NULL);
1586 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1587 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1588 ReleaseDC(NULL, screen_dc);
1591 /* Set the pixels */
1592 ddb_dc = CreateCompatibleDC(NULL);
1593 old_bmp = SelectObject(ddb_dc, ddb);
1594 for (i = 0; i < width; i++)
1596 for (j=0; j < height; j++)
1598 BYTE c = (i * width + j) % 256;
1599 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1602 SelectObject(ddb_dc, old_bmp);
1604 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1605 info->bmiHeader.biWidth = width;
1606 info->bmiHeader.biHeight = height;
1607 info->bmiHeader.biPlanes = 1;
1608 info->bmiHeader.biBitCount = bpp;
1609 info->bmiHeader.biCompression = BI_RGB;
1611 dc = CreateCompatibleDC(NULL);
1613 /* Fill in biSizeImage */
1614 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1615 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1617 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1618 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1621 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1622 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1624 /* Copy the DIB attributes but not the color table */
1625 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1627 /* Select the DDB into another DC */
1628 old_bmp = SelectObject(ddb_dc, ddb);
1631 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1632 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1634 /* Compare the color table and the bits */
1637 for (i=0; i < (1u << bpp); i++)
1638 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1639 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1640 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1641 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1642 "color table entry %d differs (bpp %d)\n", i, bpp );
1645 ok( !memcmp( bits, bits2, info->bmiHeader.biSizeImage ), "bit mismatch (bpp %d)\n", bpp );
1647 /* Test the palette */
1648 if (info2->bmiHeader.biBitCount <= 8)
1650 WORD *colors = (WORD*)info2->bmiColors;
1652 /* Get the palette indices */
1653 res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1654 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1656 for (i = 0; i < (1 << info->bmiHeader.biBitCount); i++)
1657 ok( colors[i] == i, "%d: got %d (bpp %d)\n", i, colors[i], bpp );
1660 HeapFree(GetProcessHeap(), 0, bits2);
1661 HeapFree(GetProcessHeap(), 0, bits);
1664 SelectObject(ddb_dc, old_bmp);
1667 HeapFree(GetProcessHeap(), 0, info2);
1668 HeapFree(GetProcessHeap(), 0, info);
1671 static void test_GetDIBits(void)
1673 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1674 static const BYTE bmp_bits_1[16 * 2] =
1676 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1677 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1678 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1679 0xff,0xff, 0,0, 0xff,0xff, 0,0
1681 /* 4-bytes aligned 1-bit DIB data: 16x16 */
1682 static const BYTE dib_bits_1[16 * 4] =
1684 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1685 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1686 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1687 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1689 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1690 static const BYTE bmp_bits_24[16 * 16*3] =
1692 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1693 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1694 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1705 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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1707 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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1709 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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1711 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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1713 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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1715 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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1717 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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1719 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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1721 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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1723 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 /* 4-bytes aligned 24-bit DIB data: 16x16 */
1726 static const BYTE dib_bits_24[16 * 16*3] =
1728 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1729 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1730 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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1732 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1733 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1734 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1735 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1736 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1737 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1738 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1739 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1740 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1741 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1742 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1743 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1744 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1745 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1746 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1747 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1748 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1749 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1750 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1751 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1752 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1753 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1754 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1755 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1756 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1757 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1758 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1759 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1764 int i, bytes, lines;
1766 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1767 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1768 PALETTEENTRY pal_ents[20];
1772 /* 1-bit source bitmap data */
1773 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1774 ok(hbmp != 0, "CreateBitmap failed\n");
1776 memset(&bm, 0xAA, sizeof(bm));
1777 bytes = GetObject(hbmp, sizeof(bm), &bm);
1778 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1779 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1780 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1781 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1782 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1783 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1784 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1785 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1787 bytes = GetBitmapBits(hbmp, 0, NULL);
1788 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1789 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1790 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1791 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1793 /* retrieve 1-bit DIB data */
1794 memset(bi, 0, sizeof(*bi));
1795 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1796 bi->bmiHeader.biWidth = bm.bmWidth;
1797 bi->bmiHeader.biHeight = bm.bmHeight;
1798 bi->bmiHeader.biPlanes = 1;
1799 bi->bmiHeader.biBitCount = 1;
1800 bi->bmiHeader.biCompression = BI_RGB;
1801 bi->bmiHeader.biSizeImage = 0;
1802 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1803 SetLastError(0xdeadbeef);
1804 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1805 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1806 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1807 broken(GetLastError() == 0xdeadbeef), /* winnt */
1808 "wrong error %u\n", GetLastError());
1809 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1811 memset(buf, 0xAA, sizeof(buf));
1812 SetLastError(0xdeadbeef);
1813 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1814 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1815 lines, bm.bmHeight, GetLastError());
1816 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1818 /* the color table consists of black and white */
1819 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1820 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1821 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1822 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1823 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1824 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1825 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1826 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1827 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1828 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1829 for (i = 2; i < 256; i++)
1831 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1832 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1833 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1834 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1835 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1838 /* returned bits are DWORD aligned and upside down */
1839 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1841 /* Test the palette indices */
1842 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1843 SetLastError(0xdeadbeef);
1844 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1845 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1846 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1847 for (i = 2; i < 256; i++)
1848 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[1]);
1850 /* retrieve 24-bit DIB data */
1851 memset(bi, 0, sizeof(*bi));
1852 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1853 bi->bmiHeader.biWidth = bm.bmWidth;
1854 bi->bmiHeader.biHeight = bm.bmHeight;
1855 bi->bmiHeader.biPlanes = 1;
1856 bi->bmiHeader.biBitCount = 24;
1857 bi->bmiHeader.biCompression = BI_RGB;
1858 bi->bmiHeader.biSizeImage = 0;
1859 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1860 memset(buf, 0xAA, sizeof(buf));
1861 SetLastError(0xdeadbeef);
1862 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1863 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1864 lines, bm.bmHeight, GetLastError());
1865 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1867 /* the color table doesn't exist for 24-bit images */
1868 for (i = 0; i < 256; i++)
1870 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1871 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1872 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1873 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1874 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1877 /* returned bits are DWORD aligned and upside down */
1878 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1881 /* 24-bit source bitmap data */
1882 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1883 ok(hbmp != 0, "CreateBitmap failed\n");
1884 SetLastError(0xdeadbeef);
1885 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1886 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1887 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1888 lines, bm.bmHeight, GetLastError());
1890 memset(&bm, 0xAA, sizeof(bm));
1891 bytes = GetObject(hbmp, sizeof(bm), &bm);
1892 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1893 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1894 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1895 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1896 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1897 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1898 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1899 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1901 bytes = GetBitmapBits(hbmp, 0, NULL);
1902 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
1903 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1904 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1905 bm.bmWidthBytes * bm.bmHeight, bytes);
1907 /* retrieve 1-bit DIB data */
1908 memset(bi, 0, sizeof(*bi));
1909 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1910 bi->bmiHeader.biWidth = bm.bmWidth;
1911 bi->bmiHeader.biHeight = bm.bmHeight;
1912 bi->bmiHeader.biPlanes = 1;
1913 bi->bmiHeader.biBitCount = 1;
1914 bi->bmiHeader.biCompression = BI_RGB;
1915 bi->bmiHeader.biSizeImage = 0;
1916 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1917 memset(buf, 0xAA, sizeof(buf));
1918 SetLastError(0xdeadbeef);
1919 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1920 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1921 lines, bm.bmHeight, GetLastError());
1922 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1924 /* the color table consists of black and white */
1925 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1926 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1927 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1928 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1929 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1930 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1931 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1932 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1933 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1934 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1935 for (i = 2; i < 256; i++)
1937 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1938 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1939 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1940 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1941 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1944 /* returned bits are DWORD aligned and upside down */
1945 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1947 /* Test the palette indices */
1948 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1949 SetLastError(0xdeadbeef);
1950 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1951 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1952 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1953 for (i = 2; i < 256; i++)
1954 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[i]);
1956 /* retrieve 4-bit DIB data */
1957 memset(bi, 0, sizeof(*bi));
1958 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1959 bi->bmiHeader.biWidth = bm.bmWidth;
1960 bi->bmiHeader.biHeight = bm.bmHeight;
1961 bi->bmiHeader.biPlanes = 1;
1962 bi->bmiHeader.biBitCount = 4;
1963 bi->bmiHeader.biCompression = BI_RGB;
1964 bi->bmiHeader.biSizeImage = 0;
1965 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1966 memset(buf, 0xAA, sizeof(buf));
1967 SetLastError(0xdeadbeef);
1968 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1969 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1970 lines, bm.bmHeight, GetLastError());
1972 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
1974 for (i = 0; i < 16; i++)
1977 int entry = i < 8 ? i : i + 4;
1979 if(entry == 7) entry = 12;
1980 else if(entry == 12) entry = 7;
1982 expect.rgbRed = pal_ents[entry].peRed;
1983 expect.rgbGreen = pal_ents[entry].peGreen;
1984 expect.rgbBlue = pal_ents[entry].peBlue;
1985 expect.rgbReserved = 0;
1987 ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
1988 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
1989 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
1990 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1991 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1994 /* retrieve 8-bit DIB data */
1995 memset(bi, 0, sizeof(*bi));
1996 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1997 bi->bmiHeader.biWidth = bm.bmWidth;
1998 bi->bmiHeader.biHeight = bm.bmHeight;
1999 bi->bmiHeader.biPlanes = 1;
2000 bi->bmiHeader.biBitCount = 8;
2001 bi->bmiHeader.biCompression = BI_RGB;
2002 bi->bmiHeader.biSizeImage = 0;
2003 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
2004 memset(buf, 0xAA, sizeof(buf));
2005 SetLastError(0xdeadbeef);
2006 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2007 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2008 lines, bm.bmHeight, GetLastError());
2010 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2012 for (i = 0; i < 256; i++)
2016 if (i < 10 || i >= 246)
2018 int entry = i < 10 ? i : i - 236;
2019 expect.rgbRed = pal_ents[entry].peRed;
2020 expect.rgbGreen = pal_ents[entry].peGreen;
2021 expect.rgbBlue = pal_ents[entry].peBlue;
2025 expect.rgbRed = (i & 0x07) << 5;
2026 expect.rgbGreen = (i & 0x38) << 2;
2027 expect.rgbBlue = i & 0xc0;
2029 expect.rgbReserved = 0;
2031 ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
2032 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2033 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2034 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
2035 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
2038 /* retrieve 24-bit DIB data */
2039 memset(bi, 0, sizeof(*bi));
2040 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2041 bi->bmiHeader.biWidth = bm.bmWidth;
2042 bi->bmiHeader.biHeight = bm.bmHeight;
2043 bi->bmiHeader.biPlanes = 1;
2044 bi->bmiHeader.biBitCount = 24;
2045 bi->bmiHeader.biCompression = BI_RGB;
2046 bi->bmiHeader.biSizeImage = 0;
2047 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
2048 memset(buf, 0xAA, sizeof(buf));
2049 SetLastError(0xdeadbeef);
2050 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2051 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2052 lines, bm.bmHeight, GetLastError());
2053 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2055 /* the color table doesn't exist for 24-bit images */
2056 for (i = 0; i < 256; i++)
2058 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
2059 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
2060 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2061 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
2062 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
2065 /* returned bits are DWORD aligned and upside down */
2066 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2072 static void test_GetDIBits_BI_BITFIELDS(void)
2074 /* Try a screen resolution detection technique
2075 * from the September 1999 issue of Windows Developer's Journal
2076 * which seems to be in widespread use.
2077 * http://www.lesher.ws/highcolor.html
2078 * http://www.lesher.ws/vidfmt.c
2079 * It hinges on being able to retrieve the bitmaps
2080 * for the three primary colors in non-paletted 16 bit mode.
2082 char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
2084 LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
2085 DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
2091 memset(dibinfo, 0, sizeof(dibinfo_buf));
2092 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2095 ok(hdc != NULL, "GetDC failed?\n");
2096 hbm = CreateCompatibleBitmap(hdc, 1, 1);
2097 ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
2099 /* Call GetDIBits to fill in bmiHeader. */
2100 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2101 ok(ret == 1, "GetDIBits failed\n");
2102 if (dibinfo->bmiHeader.biBitCount > 8)
2104 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2105 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2106 "compression is %u (%d bpp)\n", dibinfo->bmiHeader.biCompression, dibinfo->bmiHeader.biBitCount );
2108 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2110 ok( !bitmasks[0], "red mask is set\n" );
2111 ok( !bitmasks[1], "green mask is set\n" );
2112 ok( !bitmasks[2], "blue mask is set\n" );
2114 /* test with NULL bits pointer and correct bpp */
2115 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2116 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2117 ok(ret == 1, "GetDIBits failed\n");
2119 ok( bitmasks[0] != 0, "red mask is not set\n" );
2120 ok( bitmasks[1] != 0, "green mask is not set\n" );
2121 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2122 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2124 /* test with valid bits pointer */
2125 memset(dibinfo, 0, sizeof(dibinfo_buf));
2126 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2127 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2128 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2129 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2130 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2131 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2133 ok( bitmasks[0] != 0, "red mask is not set\n" );
2134 ok( bitmasks[1] != 0, "green mask is not set\n" );
2135 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2136 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2138 /* now with bits and 0 lines */
2139 memset(dibinfo, 0, sizeof(dibinfo_buf));
2140 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2141 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2142 SetLastError(0xdeadbeef);
2143 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2144 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2146 ok( !bitmasks[0], "red mask is set\n" );
2147 ok( !bitmasks[1], "green mask is set\n" );
2148 ok( !bitmasks[2], "blue mask is set\n" );
2149 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2151 memset(bitmasks, 0, 3*sizeof(DWORD));
2152 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2153 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2154 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2156 ok( bitmasks[0] != 0, "red mask is not set\n" );
2157 ok( bitmasks[1] != 0, "green mask is not set\n" );
2158 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2159 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2162 else skip("bitmap in colortable mode, skipping BI_BITFIELDS tests\n");
2166 /* same thing now with a 32-bpp DIB section */
2168 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2169 dibinfo->bmiHeader.biWidth = 1;
2170 dibinfo->bmiHeader.biHeight = 1;
2171 dibinfo->bmiHeader.biPlanes = 1;
2172 dibinfo->bmiHeader.biBitCount = 32;
2173 dibinfo->bmiHeader.biCompression = BI_RGB;
2174 dibinfo->bmiHeader.biSizeImage = 0;
2175 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2176 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2177 dibinfo->bmiHeader.biClrUsed = 0;
2178 dibinfo->bmiHeader.biClrImportant = 0;
2179 bitmasks[0] = 0x0000ff;
2180 bitmasks[1] = 0x00ff00;
2181 bitmasks[2] = 0xff0000;
2182 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2183 ok( hbm != 0, "failed to create bitmap\n" );
2185 memset(dibinfo, 0, sizeof(dibinfo_buf));
2186 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2187 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2188 ok(ret == 1, "GetDIBits failed\n");
2189 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2191 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2192 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2193 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2194 ok( !bitmasks[0], "red mask is set\n" );
2195 ok( !bitmasks[1], "green mask is set\n" );
2196 ok( !bitmasks[2], "blue mask is set\n" );
2198 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2199 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2200 ok(ret == 1, "GetDIBits failed\n");
2201 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2202 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2203 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2204 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2205 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2207 ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
2208 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2209 ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
2211 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2215 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2216 dibinfo->bmiHeader.biWidth = 1;
2217 dibinfo->bmiHeader.biHeight = 1;
2218 dibinfo->bmiHeader.biPlanes = 1;
2219 dibinfo->bmiHeader.biBitCount = 32;
2220 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2221 dibinfo->bmiHeader.biSizeImage = 0;
2222 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2223 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2224 dibinfo->bmiHeader.biClrUsed = 0;
2225 dibinfo->bmiHeader.biClrImportant = 0;
2226 bitmasks[0] = 0x0000ff;
2227 bitmasks[1] = 0x00ff00;
2228 bitmasks[2] = 0xff0000;
2229 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2230 ok( hbm != 0, "failed to create bitmap\n" );
2234 memset(dibinfo, 0, sizeof(dibinfo_buf));
2235 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2236 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2237 ok(ret == 1, "GetDIBits failed\n");
2239 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
2240 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2241 ok( !bitmasks[0], "red mask is set\n" );
2242 ok( !bitmasks[1], "green mask is set\n" );
2243 ok( !bitmasks[2], "blue mask is set\n" );
2245 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2246 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2247 ok(ret == 1, "GetDIBits failed\n");
2248 ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
2249 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2250 ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
2251 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2256 /* 24-bpp DIB sections don't have bitfields */
2258 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2259 dibinfo->bmiHeader.biWidth = 1;
2260 dibinfo->bmiHeader.biHeight = 1;
2261 dibinfo->bmiHeader.biPlanes = 1;
2262 dibinfo->bmiHeader.biBitCount = 24;
2263 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2264 dibinfo->bmiHeader.biSizeImage = 0;
2265 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2266 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2267 dibinfo->bmiHeader.biClrUsed = 0;
2268 dibinfo->bmiHeader.biClrImportant = 0;
2269 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2270 ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
2271 dibinfo->bmiHeader.biCompression = BI_RGB;
2272 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2273 ok( hbm != 0, "failed to create bitmap\n" );
2275 memset(dibinfo, 0, sizeof(dibinfo_buf));
2276 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2277 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2278 ok(ret == 1, "GetDIBits failed\n");
2279 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2281 ok( dibinfo->bmiHeader.biCompression == BI_RGB,
2282 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2283 ok( !bitmasks[0], "red mask is set\n" );
2284 ok( !bitmasks[1], "green mask is set\n" );
2285 ok( !bitmasks[2], "blue mask is set\n" );
2287 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2288 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2289 ok(ret == 1, "GetDIBits failed\n");
2290 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2291 ok( !bitmasks[0], "red mask is set\n" );
2292 ok( !bitmasks[1], "green mask is set\n" );
2293 ok( !bitmasks[2], "blue mask is set\n" );
2294 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2297 ReleaseDC(NULL, hdc);
2300 static void test_select_object(void)
2303 HBITMAP hbm, hbm_old;
2305 DWORD depths[] = {8, 15, 16, 24, 32};
2310 ok(hdc != 0, "GetDC(0) failed\n");
2311 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2312 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2314 hbm_old = SelectObject(hdc, hbm);
2315 ok(hbm_old == 0, "SelectObject should fail\n");
2320 hdc = CreateCompatibleDC(0);
2321 ok(hdc != 0, "GetDC(0) failed\n");
2322 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2323 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2325 hbm_old = SelectObject(hdc, hbm);
2326 ok(hbm_old != 0, "SelectObject failed\n");
2327 hbm_old = SelectObject(hdc, hbm_old);
2328 ok(hbm_old == hbm, "SelectObject failed\n");
2332 /* test an 1-bpp bitmap */
2333 planes = GetDeviceCaps(hdc, PLANES);
2336 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
2337 ok(hbm != 0, "CreateBitmap failed\n");
2339 hbm_old = SelectObject(hdc, hbm);
2340 ok(hbm_old != 0, "SelectObject failed\n");
2341 hbm_old = SelectObject(hdc, hbm_old);
2342 ok(hbm_old == hbm, "SelectObject failed\n");
2346 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
2347 /* test a color bitmap to dc bpp matching */
2348 planes = GetDeviceCaps(hdc, PLANES);
2349 bpp = GetDeviceCaps(hdc, BITSPIXEL);
2351 hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
2352 ok(hbm != 0, "CreateBitmap failed\n");
2354 hbm_old = SelectObject(hdc, hbm);
2355 if(depths[i] == bpp ||
2356 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
2358 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
2359 SelectObject(hdc, hbm_old);
2361 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
2364 memset(&bm, 0xAA, sizeof(bm));
2365 bytes = GetObject(hbm, sizeof(bm), &bm);
2366 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2367 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2368 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
2369 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
2370 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2371 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
2372 if(depths[i] == 15) {
2373 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
2375 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2377 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2385 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
2390 ret = GetObjectType(hbmp);
2391 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
2393 ret = GetObject(hbmp, 0, 0);
2394 ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
2396 memset(&bm, 0xDA, sizeof(bm));
2397 SetLastError(0xdeadbeef);
2398 ret = GetObject(hbmp, sizeof(bm), &bm);
2399 if (!ret) /* XP, only for curObj2 */ return;
2400 ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
2401 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2402 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2403 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2404 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2405 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2406 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2407 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2410 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2412 static void test_CreateBitmap(void)
2415 HDC screenDC = GetDC(0);
2416 HDC hdc = CreateCompatibleDC(screenDC);
2419 /* all of these are the stock monochrome bitmap */
2420 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2421 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2422 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2423 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2424 HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2425 HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2427 /* these 2 are not the stock monochrome bitmap */
2428 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2429 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2431 HBITMAP old1 = SelectObject(hdc, bm2);
2432 HBITMAP old2 = SelectObject(screenDC, bm3);
2433 SelectObject(hdc, old1);
2434 SelectObject(screenDC, old2);
2436 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2437 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2438 bm, bm1, bm4, bm5, curObj1, old1);
2439 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2441 ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
2442 ok(old2 == 0, "old2 %p\n", old2);
2444 test_mono_1x1_bmp(bm);
2445 test_mono_1x1_bmp(bm1);
2446 test_mono_1x1_bmp(bm2);
2447 test_mono_1x1_bmp(bm3);
2448 test_mono_1x1_bmp(bm4);
2449 test_mono_1x1_bmp(bm5);
2450 test_mono_1x1_bmp(old1);
2451 test_mono_1x1_bmp(curObj1);
2461 ReleaseDC(0, screenDC);
2463 /* show that Windows ignores the provided bm.bmWidthBytes */
2467 bmp.bmWidthBytes = 28;
2469 bmp.bmBitsPixel = 1;
2471 bm = CreateBitmapIndirect(&bmp);
2472 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2473 test_mono_1x1_bmp(bm);
2476 /* Test how the bmBitsPixel field is treated */
2477 for(i = 1; i <= 33; i++) {
2481 bmp.bmWidthBytes = 28;
2483 bmp.bmBitsPixel = i;
2485 SetLastError(0xdeadbeef);
2486 bm = CreateBitmapIndirect(&bmp);
2488 DWORD error = GetLastError();
2489 ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
2490 ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2494 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2495 GetObject(bm, sizeof(bmp), &bmp);
2502 } else if(i <= 16) {
2504 } else if(i <= 24) {
2506 } else if(i <= 32) {
2509 ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2510 i, bmp.bmBitsPixel, expect);
2515 static void test_bitmapinfoheadersize(void)
2522 memset(&bmi, 0, sizeof(BITMAPINFO));
2523 bmi.bmiHeader.biHeight = 100;
2524 bmi.bmiHeader.biWidth = 512;
2525 bmi.bmiHeader.biBitCount = 24;
2526 bmi.bmiHeader.biPlanes = 1;
2528 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2530 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2531 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2533 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2535 SetLastError(0xdeadbeef);
2536 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2537 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2540 bmi.bmiHeader.biSize++;
2542 SetLastError(0xdeadbeef);
2543 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2545 broken(!hdib), /* Win98, WinMe */
2546 "CreateDIBSection error %d\n", GetLastError());
2549 bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2551 SetLastError(0xdeadbeef);
2552 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2554 broken(!hdib), /* Win98, WinMe */
2555 "CreateDIBSection error %d\n", GetLastError());
2558 bmi.bmiHeader.biSize++;
2560 SetLastError(0xdeadbeef);
2561 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2563 broken(!hdib), /* Win98, WinMe */
2564 "CreateDIBSection error %d\n", GetLastError());
2567 bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2569 SetLastError(0xdeadbeef);
2570 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2571 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2574 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2576 SetLastError(0xdeadbeef);
2577 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2579 broken(!hdib), /* Win95 */
2580 "CreateDIBSection error %d\n", GetLastError());
2583 memset(&bci, 0, sizeof(BITMAPCOREINFO));
2584 bci.bmciHeader.bcHeight = 100;
2585 bci.bmciHeader.bcWidth = 512;
2586 bci.bmciHeader.bcBitCount = 24;
2587 bci.bmciHeader.bcPlanes = 1;
2589 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2591 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2592 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2594 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2596 SetLastError(0xdeadbeef);
2597 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2598 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2601 bci.bmciHeader.bcSize++;
2603 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2604 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2606 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2608 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2609 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2614 static void test_get16dibits(void)
2616 BYTE bits[4 * (16 / sizeof(BYTE))];
2618 HDC screen_dc = GetDC(NULL);
2621 int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2623 int overwritten_bytes = 0;
2625 memset(bits, 0, sizeof(bits));
2626 hbmp = CreateBitmap(2, 2, 1, 16, bits);
2627 ok(hbmp != NULL, "CreateBitmap failed\n");
2629 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2632 memset(info, '!', info_len);
2633 memset(info, 0, sizeof(info->bmiHeader));
2635 info->bmiHeader.biSize = sizeof(info->bmiHeader);
2636 info->bmiHeader.biWidth = 2;
2637 info->bmiHeader.biHeight = 2;
2638 info->bmiHeader.biPlanes = 1;
2639 info->bmiHeader.biCompression = BI_RGB;
2641 ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2642 ok(ret != 0, "GetDIBits failed got %d\n", ret);
2644 for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2646 overwritten_bytes++;
2647 ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2649 HeapFree(GetProcessHeap(), 0, info);
2651 ReleaseDC(NULL, screen_dc);
2654 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2655 DWORD dwRop, UINT32 expected, int line)
2657 *srcBuffer = 0xFEDCBA98;
2658 *dstBuffer = 0x89ABCDEF;
2659 Rectangle(hdcSrc, 0, 0, 1, 1); /* A null operation to ensure dibs are coerced to X11 */
2660 BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
2661 ok(expected == *dstBuffer,
2662 "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2663 dwRop, expected, *dstBuffer, line);
2666 static void test_BitBlt(void)
2668 HBITMAP bmpDst, bmpSrc;
2669 HBITMAP oldDst, oldSrc;
2670 HDC hdcScreen, hdcDst, hdcSrc;
2671 UINT32 *dstBuffer, *srcBuffer;
2672 HBRUSH hBrush, hOldBrush;
2673 BITMAPINFO bitmapInfo;
2675 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2676 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2677 bitmapInfo.bmiHeader.biWidth = 1;
2678 bitmapInfo.bmiHeader.biHeight = 1;
2679 bitmapInfo.bmiHeader.biPlanes = 1;
2680 bitmapInfo.bmiHeader.biBitCount = 32;
2681 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2682 bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2684 hdcScreen = CreateCompatibleDC(0);
2685 hdcDst = CreateCompatibleDC(hdcScreen);
2686 hdcSrc = CreateCompatibleDC(hdcDst);
2688 /* Setup the destination dib section */
2689 bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
2691 oldDst = SelectObject(hdcDst, bmpDst);
2693 hBrush = CreateSolidBrush(0x012345678);
2694 hOldBrush = SelectObject(hdcDst, hBrush);
2696 /* Setup the source dib section */
2697 bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
2699 oldSrc = SelectObject(hdcSrc, bmpSrc);
2701 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2702 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2703 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2704 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2705 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2706 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2707 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2708 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2709 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2710 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2711 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2712 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2713 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2714 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2715 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2718 SelectObject(hdcSrc, oldSrc);
2719 DeleteObject(bmpSrc);
2722 SelectObject(hdcDst, hOldBrush);
2723 DeleteObject(hBrush);
2724 SelectObject(hdcDst, oldDst);
2725 DeleteObject(bmpDst);
2729 DeleteDC(hdcScreen);
2732 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2733 DWORD dwRop, UINT32 expected, int line)
2735 *srcBuffer = 0xFEDCBA98;
2736 *dstBuffer = 0x89ABCDEF;
2737 StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
2738 ok(expected == *dstBuffer,
2739 "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2740 dwRop, expected, *dstBuffer, line);
2743 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, BITMAPINFO *dst_info, UINT32 *dstBuffer, UINT32 *srcBuffer,
2744 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2745 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2746 UINT32 *expected, int line)
2748 int dst_size = get_dib_image_size( dst_info );
2750 memset(dstBuffer, 0, dst_size);
2751 StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2752 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
2753 ok(memcmp(dstBuffer, expected, dst_size) == 0,
2754 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2755 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2756 expected[0], expected[1], expected[2], expected[3],
2757 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2758 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2759 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2762 static void test_StretchBlt(void)
2764 HBITMAP bmpDst, bmpSrc;
2765 HBITMAP oldDst, oldSrc;
2766 HDC hdcScreen, hdcDst, hdcSrc;
2767 UINT32 *dstBuffer, *srcBuffer;
2768 HBRUSH hBrush, hOldBrush;
2769 BITMAPINFO biDst, biSrc;
2770 UINT32 expected[256];
2773 memset(&biDst, 0, sizeof(BITMAPINFO));
2774 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2775 biDst.bmiHeader.biWidth = 16;
2776 biDst.bmiHeader.biHeight = -16;
2777 biDst.bmiHeader.biPlanes = 1;
2778 biDst.bmiHeader.biBitCount = 32;
2779 biDst.bmiHeader.biCompression = BI_RGB;
2780 memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
2782 hdcScreen = CreateCompatibleDC(0);
2783 hdcDst = CreateCompatibleDC(hdcScreen);
2784 hdcSrc = CreateCompatibleDC(hdcDst);
2787 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2789 oldDst = SelectObject(hdcDst, bmpDst);
2791 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2793 oldSrc = SelectObject(hdcSrc, bmpSrc);
2795 hBrush = CreateSolidBrush(0x012345678);
2796 hOldBrush = SelectObject(hdcDst, hBrush);
2798 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2799 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2800 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2801 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2802 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2803 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2804 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2805 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2806 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2807 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2808 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2809 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2810 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2811 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2812 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2814 SelectObject(hdcDst, hOldBrush);
2815 DeleteObject(hBrush);
2817 /* Top-down to top-down tests */
2818 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2819 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2821 memset( expected, 0, get_dib_image_size( &biDst ) );
2822 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2823 expected[16] = 0xFEDCBA98, expected[17] = 0x76543210;
2824 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2825 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2827 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2828 expected[16] = 0x00000000, expected[17] = 0x00000000;
2829 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2830 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
2832 expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
2833 expected[16] = 0xCAFED00D, expected[17] = 0xCAFED00D;
2834 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2835 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
2837 /* This is an example of the dst width (height) == 1 exception, explored below */
2838 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2839 expected[16] = 0x00000000, expected[17] = 0x00000000;
2840 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2841 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
2843 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2844 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
2845 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2846 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2848 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2849 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
2850 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2851 1, 1, -2, -2, 0, 0, 2, 2, expected, __LINE__);
2853 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2854 expected[16] = 0x00000000, expected[17] = 0x00000000;
2855 todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2856 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
2858 expected[0] = 0x00000000, expected[1] = 0x00000000;
2859 expected[16] = 0x00000000, expected[17] = 0xCAFED00D, expected[18] = 0xFEEDFACE;
2860 expected[32] = 0x00000000, expected[33] = 0xFEDCBA98, expected[34] = 0x76543210;
2862 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2863 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2865 /* when dst width is 1 merge src width - 1 pixels */
2866 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
2867 srcBuffer[0] = 0x0000ff00, srcBuffer[1] = 0x0000f0f0, srcBuffer[2] = 0x0000cccc, srcBuffer[3] = 0x0000aaaa;
2868 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2870 memset( expected, 0, get_dib_image_size( &biDst ) );
2871 expected[0] = srcBuffer[0];
2872 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2873 0, 0, 1, 1, 0, 0, 2, 1, expected, __LINE__);
2875 expected[0] = srcBuffer[0] & srcBuffer[1];
2876 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2877 0, 0, 1, 1, 0, 0, 3, 1, expected, __LINE__);
2879 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
2880 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2881 0, 0, 1, 1, 0, 0, 4, 1, expected, __LINE__);
2883 /* this doesn't happen if the src width is -ve */
2884 expected[0] = srcBuffer[1] & srcBuffer[2];
2885 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2886 0, 0, 1, 1, 2, 0, -2, 1, expected, __LINE__);
2888 /* when dst width > 1 behaviour reverts to what one would expect */
2889 expected[0] = srcBuffer[0] & srcBuffer[1], expected[1] = srcBuffer[2] & srcBuffer[3];
2890 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2891 0, 0, 2, 1, 0, 0, 4, 1, expected, __LINE__);
2893 /* similarly in the vertical direction */
2894 memset( expected, 0, get_dib_image_size( &biDst ) );
2895 expected[0] = srcBuffer[0];
2896 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2897 0, 0, 1, 1, 0, 0, 1, 2, expected, __LINE__);
2899 /* check that it's the dst size in device units that needs to be 1 */
2900 SetMapMode( hdcDst, MM_ISOTROPIC );
2901 SetWindowExtEx( hdcDst, 200, 200, NULL );
2902 SetViewportExtEx( hdcDst, 100, 100, NULL );
2904 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
2905 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2906 0, 0, 2, 2, 0, 0, 4, 1, expected, __LINE__);
2907 SetMapMode( hdcDst, MM_TEXT );
2909 SelectObject(hdcDst, oldDst);
2910 DeleteObject(bmpDst);
2912 /* Top-down to bottom-up tests */
2913 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
2914 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2915 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2917 biDst.bmiHeader.biHeight = 16;
2918 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2920 oldDst = SelectObject(hdcDst, bmpDst);
2922 memset( expected, 0, get_dib_image_size( &biDst ) );
2924 expected[224] = 0xFEDCBA98, expected[225] = 0x76543210;
2925 expected[240] = 0xCAFED00D, expected[241] = 0xFEEDFACE;
2926 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2927 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2929 expected[224] = 0xFEEDFACE, expected[225] = 0xCAFED00D;
2930 expected[240] = 0x76543210, expected[241] = 0xFEDCBA98;
2931 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2932 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2934 SelectObject(hdcSrc, oldSrc);
2935 DeleteObject(bmpSrc);
2937 /* Bottom-up to bottom-up tests */
2938 biSrc.bmiHeader.biHeight = 16;
2939 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2941 srcBuffer[224] = 0xCAFED00D, srcBuffer[225] = 0xFEEDFACE;
2942 srcBuffer[240] = 0xFEDCBA98, srcBuffer[241] = 0x76543210;
2943 oldSrc = SelectObject(hdcSrc, bmpSrc);
2945 memset( expected, 0, get_dib_image_size( &biDst ) );
2947 expected[224] = 0xCAFED00D, expected[225] = 0xFEEDFACE;
2948 expected[240] = 0xFEDCBA98, expected[241] = 0x76543210;
2949 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2950 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2952 expected[224] = 0x76543210, expected[225] = 0xFEDCBA98;
2953 expected[240] = 0xFEEDFACE, expected[241] = 0xCAFED00D;
2954 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2955 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2957 SelectObject(hdcDst, oldDst);
2958 DeleteObject(bmpDst);
2960 /* Bottom-up to top-down tests */
2961 biDst.bmiHeader.biHeight = -16;
2962 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2964 oldDst = SelectObject(hdcDst, bmpDst);
2966 memset( expected, 0, get_dib_image_size( &biDst ) );
2967 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2968 expected[16] = 0xCAFED00D, expected[17] = 0xFEEDFACE;
2969 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2970 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2972 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2973 expected[16] = 0x76543210, expected[17] = 0xFEDCBA98;
2974 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2975 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2977 SelectObject(hdcSrc, oldSrc);
2978 DeleteObject(bmpSrc);
2980 biSrc.bmiHeader.biHeight = -2;
2981 biSrc.bmiHeader.biBitCount = 24;
2982 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
2983 oldSrc = SelectObject(hdcSrc, bmpSrc);
2985 memset( expected, 0, get_dib_image_size( &biDst ) );
2986 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2987 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2988 memcpy(dstBuffer, expected, 4 * sizeof(*dstBuffer));
2989 StretchBlt(hdcSrc, 0, 0, 4, 1, hdcDst, 0, 0, 4, 1, SRCCOPY );
2990 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
2991 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
2992 expected[0] = 0x00EDFACE, expected[1] = 0x00FED00D;
2993 expected[2] = 0x00543210, expected[3] = 0x00DCBA98;
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 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3000 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
3001 memcpy(srcBuffer, expected, 4 * sizeof(*dstBuffer));
3002 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
3003 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3004 expected[0] = 0x00EDFACE, expected[1] = 0x00D00DFE;
3005 expected[2] = 0x0010CAFE, expected[3] = 0x00765432;
3006 ok(!memcmp(dstBuffer, expected, 16),
3007 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3008 expected[0], expected[1], expected[2], expected[3],
3009 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3011 SelectObject(hdcSrc, oldSrc);
3012 DeleteObject(bmpSrc);
3014 biSrc.bmiHeader.biBitCount = 1;
3015 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
3016 oldSrc = SelectObject(hdcSrc, bmpSrc);
3017 *((DWORD *)colors + 0) = 0x123456;
3018 *((DWORD *)colors + 1) = 0x335577;
3019 SetDIBColorTable( hdcSrc, 0, 2, colors );
3020 srcBuffer[0] = 0x55555555;
3021 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
3022 SetTextColor( hdcDst, 0 );
3023 SetBkColor( hdcDst, 0 );
3024 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3025 expected[0] = expected[2] = 0x00123456;
3026 expected[1] = expected[3] = 0x00335577;
3027 ok(!memcmp(dstBuffer, expected, 16),
3028 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3029 expected[0], expected[1], expected[2], expected[3],
3030 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3032 SelectObject(hdcSrc, oldSrc);
3033 DeleteObject(bmpSrc);
3035 bmpSrc = CreateBitmap( 16, 16, 1, 1, 0 );
3036 oldSrc = SelectObject(hdcSrc, bmpSrc);
3037 SetPixel( hdcSrc, 0, 0, 0 );
3038 SetPixel( hdcSrc, 1, 0, 0xffffff );
3039 SetPixel( hdcSrc, 2, 0, 0xffffff );
3040 SetPixel( hdcSrc, 3, 0, 0 );
3041 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
3042 SetTextColor( hdcDst, RGB(0x22,0x44,0x66) );
3043 SetBkColor( hdcDst, RGB(0x65,0x43,0x21) );
3044 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3045 expected[0] = expected[3] = 0x00224466;
3046 expected[1] = expected[2] = 0x00654321;
3047 ok(!memcmp(dstBuffer, expected, 16),
3048 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3049 expected[0], expected[1], expected[2], expected[3],
3050 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3052 SelectObject(hdcSrc, oldSrc);
3053 DeleteObject(bmpSrc);
3057 SelectObject(hdcDst, oldDst);
3058 DeleteObject(bmpDst);
3061 DeleteDC(hdcScreen);
3064 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3065 DWORD dwRop, UINT32 expected, int line)
3067 const UINT32 buffer[2] = { 0xFEDCBA98, 0 };
3068 BITMAPINFO bitmapInfo;
3070 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3071 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3072 bitmapInfo.bmiHeader.biWidth = 2;
3073 bitmapInfo.bmiHeader.biHeight = 1;
3074 bitmapInfo.bmiHeader.biPlanes = 1;
3075 bitmapInfo.bmiHeader.biBitCount = 32;
3076 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3077 bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer);
3079 *dstBuffer = 0x89ABCDEF;
3081 StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop);
3082 ok(expected == *dstBuffer,
3083 "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
3084 dwRop, expected, *dstBuffer, line);
3087 static void check_StretchDIBits_stretch(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3088 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
3089 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
3090 UINT32 expected[4], UINT32 legacy_expected[4], int line)
3092 BITMAPINFO bitmapInfo;
3094 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3095 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3096 bitmapInfo.bmiHeader.biWidth = 2;
3097 bitmapInfo.bmiHeader.biHeight = -2;
3098 bitmapInfo.bmiHeader.biPlanes = 1;
3099 bitmapInfo.bmiHeader.biBitCount = 32;
3100 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3102 memset(dstBuffer, 0, 16);
3103 StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
3104 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3105 srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
3106 ok(memcmp(dstBuffer, expected, 16) == 0,
3107 "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
3108 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
3109 expected[0], expected[1], expected[2], expected[3],
3110 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
3111 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3112 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
3115 static void test_StretchDIBits(void)
3119 HDC hdcScreen, hdcDst;
3120 UINT32 *dstBuffer, srcBuffer[4];
3121 HBRUSH hBrush, hOldBrush;
3123 UINT32 expected[4], legacy_expected[4];
3125 memset(&biDst, 0, sizeof(BITMAPINFO));
3126 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3127 biDst.bmiHeader.biWidth = 2;
3128 biDst.bmiHeader.biHeight = -2;
3129 biDst.bmiHeader.biPlanes = 1;
3130 biDst.bmiHeader.biBitCount = 32;
3131 biDst.bmiHeader.biCompression = BI_RGB;
3133 hdcScreen = CreateCompatibleDC(0);
3134 hdcDst = CreateCompatibleDC(hdcScreen);
3137 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3139 oldDst = SelectObject(hdcDst, bmpDst);
3141 hBrush = CreateSolidBrush(0x012345678);
3142 hOldBrush = SelectObject(hdcDst, hBrush);
3144 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3145 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3146 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3147 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3148 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3149 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3150 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3151 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3152 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3153 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3154 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3155 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3156 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3157 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3158 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3160 SelectObject(hdcDst, hOldBrush);
3161 DeleteObject(hBrush);
3163 /* Top-down destination tests */
3164 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3165 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
3167 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
3168 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
3169 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3170 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
3172 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3173 expected[2] = 0x00000000, expected[3] = 0x00000000;
3174 legacy_expected[0] = 0xFEDCBA98, legacy_expected[1] = 0x00000000;
3175 legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
3176 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3177 0, 0, 1, 1, 0, 0, 1, 1, expected, legacy_expected, __LINE__);
3179 expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
3180 expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
3181 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3182 0, 0, 2, 2, 0, 0, 1, 1, expected, expected, __LINE__);
3184 expected[0] = 0x42441000, expected[1] = 0x00000000;
3185 expected[2] = 0x00000000, expected[3] = 0x00000000;
3186 legacy_expected[0] = 0x00543210, legacy_expected[1] = 0x00000000;
3187 legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
3188 todo_wine check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3189 0, 0, 1, 1, 0, 0, 2, 2, expected, legacy_expected, __LINE__);
3191 expected[0] = 0x00000000, expected[1] = 0x00000000;
3192 expected[2] = 0x00000000, expected[3] = 0x00000000;
3193 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3194 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
3196 expected[0] = 0x00000000, expected[1] = 0x00000000;
3197 expected[2] = 0x00000000, expected[3] = 0x00000000;
3198 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3199 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
3201 expected[0] = 0x00000000, expected[1] = 0x00000000;
3202 expected[2] = 0x00000000, expected[3] = 0x00000000;
3203 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3204 1, 1, -2, -2, 1, 1, -2, -2, expected, expected, __LINE__);
3206 expected[0] = 0x00000000, expected[1] = 0x00000000;
3207 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
3208 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3209 1, 1, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
3211 SelectObject(hdcDst, oldDst);
3212 DeleteObject(bmpDst);
3214 /* Bottom up destination tests */
3215 biDst.bmiHeader.biHeight = 2;
3216 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3218 oldDst = SelectObject(hdcDst, bmpDst);
3220 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3221 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
3222 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3223 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
3226 SelectObject(hdcDst, oldDst);
3227 DeleteObject(bmpDst);
3230 DeleteDC(hdcScreen);
3233 static void test_GdiAlphaBlend(void)
3235 /* test out-of-bound parameters for GdiAlphaBlend */
3248 BLENDFUNCTION blend;
3250 if (!pGdiAlphaBlend)
3252 win_skip("GdiAlphaBlend() is not implemented\n");
3256 hdcNull = GetDC(NULL);
3257 hdcDst = CreateCompatibleDC(hdcNull);
3258 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
3259 hdcSrc = CreateCompatibleDC(hdcNull);
3261 memset(&bmi, 0, sizeof(bmi)); /* as of Wine 0.9.44 we require the src to be a DIB section */
3262 bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
3263 bmi.bmiHeader.biHeight = 20;
3264 bmi.bmiHeader.biWidth = 20;
3265 bmi.bmiHeader.biBitCount = 32;
3266 bmi.bmiHeader.biPlanes = 1;
3267 bmi.bmiHeader.biCompression = BI_RGB;
3268 bmpSrc = CreateDIBSection(hdcDst, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3269 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3271 oldDst = SelectObject(hdcDst, bmpDst);
3272 oldSrc = SelectObject(hdcSrc, bmpSrc);
3274 blend.BlendOp = AC_SRC_OVER;
3275 blend.BlendFlags = 0;
3276 blend.SourceConstantAlpha = 128;
3277 blend.AlphaFormat = 0;
3279 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend), TRUE, BOOL, "%d");
3280 SetLastError(0xdeadbeef);
3281 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), FALSE, BOOL, "%d");
3282 expect_eq(GetLastError(), ERROR_INVALID_PARAMETER, int, "%d");
3283 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), FALSE, BOOL, "%d");
3284 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend), FALSE, BOOL, "%d");
3285 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
3286 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
3288 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
3289 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), TRUE, BOOL, "%d");
3290 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), TRUE, BOOL, "%d");
3291 SetMapMode(hdcSrc, MM_ANISOTROPIC);
3292 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
3293 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend), TRUE, BOOL, "%d");
3294 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend), TRUE, BOOL, "%d");
3296 SetLastError(0xdeadbeef);
3297 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend), FALSE, BOOL, "%d");
3298 expect_eq(GetLastError(), 0xdeadbeef, int, "%d");
3300 SelectObject(hdcDst, oldDst);
3301 SelectObject(hdcSrc, oldSrc);
3302 DeleteObject(bmpSrc);
3303 DeleteObject(bmpDst);
3307 ReleaseDC(NULL, hdcNull);
3311 static void test_clipping(void)
3319 HDC hdcDst = CreateCompatibleDC( NULL );
3320 HDC hdcSrc = CreateCompatibleDC( NULL );
3322 BITMAPINFO bmpinfo={{0}};
3323 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3324 bmpinfo.bmiHeader.biWidth = 100;
3325 bmpinfo.bmiHeader.biHeight = 100;
3326 bmpinfo.bmiHeader.biPlanes = 1;
3327 bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3328 bmpinfo.bmiHeader.biCompression = BI_RGB;
3330 bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3331 ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3332 SelectObject( hdcDst, bmpDst );
3334 bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3335 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3336 SelectObject( hdcSrc, bmpSrc );
3338 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3339 ok(result, "BitBlt failed\n");
3341 hRgn = CreateRectRgn( 0,0,0,0 );
3342 SelectClipRgn( hdcDst, hRgn );
3344 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3345 ok(result, "BitBlt failed\n");
3347 DeleteObject( bmpDst );
3348 DeleteObject( bmpSrc );
3349 DeleteObject( hRgn );
3354 static void test_32bit_bitmap_blt(void)
3357 HBITMAP bmpSrc, bmpDst;
3358 HBITMAP oldSrc, oldDst;
3359 HDC hdcSrc, hdcDst, hdcScreen;
3361 DWORD colorSrc = 0x11223344;
3363 memset(&biDst, 0, sizeof(BITMAPINFO));
3364 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3365 biDst.bmiHeader.biWidth = 2;
3366 biDst.bmiHeader.biHeight = -2;
3367 biDst.bmiHeader.biPlanes = 1;
3368 biDst.bmiHeader.biBitCount = 32;
3369 biDst.bmiHeader.biCompression = BI_RGB;
3371 hdcScreen = CreateCompatibleDC(0);
3372 if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3374 DeleteDC(hdcScreen);
3375 trace("Skipping 32-bit DDB test\n");
3379 hdcSrc = CreateCompatibleDC(hdcScreen);
3380 bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3381 oldSrc = SelectObject(hdcSrc, bmpSrc);
3383 hdcDst = CreateCompatibleDC(hdcScreen);
3384 bmpDst = CreateDIBSection(hdcDst, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3385 oldDst = SelectObject(hdcDst, bmpDst);
3387 StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3388 ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3391 SelectObject(hdcDst, oldDst);
3392 DeleteObject(bmpDst);
3395 SelectObject(hdcSrc, oldSrc);
3396 DeleteObject(bmpSrc);
3399 DeleteDC(hdcScreen);
3403 * Used by test_GetDIBits_top_down to create the bitmap to test against.
3405 static void setup_picture(char *picture, int bpp)
3413 /*Set the first byte in each pixel to the index of that pixel.*/
3414 for (i = 0; i < 4; i++)
3415 picture[i * (bpp / 8)] = i;
3420 /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
3427 static void test_GetDIBits_top_down(int bpp)
3430 HBITMAP bmptb, bmpbt;
3436 memset( &bi, 0, sizeof(bi) );
3437 bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
3438 bi.bmiHeader.biWidth=2;
3439 bi.bmiHeader.biHeight=2;
3440 bi.bmiHeader.biPlanes=1;
3441 bi.bmiHeader.biBitCount=bpp;
3442 bi.bmiHeader.biCompression=BI_RGB;
3444 /*Get the device context for the screen.*/
3446 ok(hdc != NULL, "Could not get a handle to a device context.\n");
3448 /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
3449 bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3450 ok(bmpbt != NULL, "Could not create a DIB section.\n");
3451 /*Now that we have a pointer to the pixels, we write to them.*/
3452 setup_picture((char*)picture, bpp);
3453 /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
3454 bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
3455 bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3456 ok(bmptb != NULL, "Could not create a DIB section.\n");
3457 /*Write to this top to bottom bitmap.*/
3458 setup_picture((char*)picture, bpp);
3460 bi.bmiHeader.biWidth = 1;
3462 bi.bmiHeader.biHeight = 2;
3463 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3464 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3465 /*Check the first byte of the pixel.*/
3466 ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3467 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3468 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3469 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3470 /*Check second scanline.*/
3471 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3472 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3473 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3474 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3475 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3476 ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3477 /*Check both scanlines.*/
3478 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3479 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3480 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3481 ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3482 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3483 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3484 ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3485 ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3487 /*Make destination bitmap top-down.*/
3488 bi.bmiHeader.biHeight = -2;
3489 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3490 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3491 ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3492 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3493 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3494 ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3495 /*Check second scanline.*/
3496 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3497 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3498 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3499 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3500 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3501 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3502 /*Check both scanlines.*/
3503 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3504 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3505 ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3506 ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3507 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3508 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3509 ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3510 ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3512 DeleteObject(bmpbt);
3513 DeleteObject(bmptb);
3516 static void test_GetSetDIBits_rtl(void)
3519 HBITMAP bitmap, orig_bitmap;
3522 DWORD bits_1[8 * 8], bits_2[8 * 8];
3526 win_skip("Don't have SetLayout\n");
3530 hdc = GetDC( NULL );
3531 hdc_mem = CreateCompatibleDC( hdc );
3532 pSetLayout( hdc_mem, LAYOUT_LTR );
3534 bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
3535 orig_bitmap = SelectObject( hdc_mem, bitmap );
3536 SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
3537 SelectObject( hdc_mem, orig_bitmap );
3539 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3540 info.bmiHeader.biWidth = 8;
3541 info.bmiHeader.biHeight = 8;
3542 info.bmiHeader.biPlanes = 1;
3543 info.bmiHeader.biBitCount = 32;
3544 info.bmiHeader.biCompression = BI_RGB;
3546 /* First show that GetDIBits ignores the layout mode. */
3548 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3549 ok(ret == 8, "got %d\n", ret);
3550 ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
3552 pSetLayout( hdc_mem, LAYOUT_RTL );
3554 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3555 ok(ret == 8, "got %d\n", ret);
3557 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3559 /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
3560 followed by a GetDIBits and show that the bits remain unchanged. */
3562 pSetLayout( hdc_mem, LAYOUT_LTR );
3564 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3565 ok(ret == 8, "got %d\n", ret);
3566 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3567 ok(ret == 8, "got %d\n", ret);
3568 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3570 pSetLayout( hdc_mem, LAYOUT_RTL );
3572 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3573 ok(ret == 8, "got %d\n", ret);
3574 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3575 ok(ret == 8, "got %d\n", ret);
3576 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3578 DeleteObject( bitmap );
3579 DeleteDC( hdc_mem );
3580 ReleaseDC( NULL, hdc );
3583 static void test_GetDIBits_scanlines(void)
3587 HDC hdc = GetDC( NULL );
3589 DWORD data[128], inverted_bits[64];
3592 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
3594 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3595 info->bmiHeader.biWidth = 8;
3596 info->bmiHeader.biHeight = 8;
3597 info->bmiHeader.biPlanes = 1;
3598 info->bmiHeader.biBitCount = 32;
3599 info->bmiHeader.biCompression = BI_RGB;
3601 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3603 for (i = 0; i < 64; i++)
3606 inverted_bits[56 - (i & ~7) + (i & 7)] = i;
3611 memset( data, 0xaa, sizeof(data) );
3613 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3614 ok( ret == 8, "got %d\n", ret );
3615 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3616 memset( data, 0xaa, sizeof(data) );
3618 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3619 ok( ret == 5, "got %d\n", ret );
3620 ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
3621 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3622 memset( data, 0xaa, sizeof(data) );
3624 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3625 ok( ret == 7, "got %d\n", ret );
3626 ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
3627 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3628 memset( data, 0xaa, sizeof(data) );
3630 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3631 ok( ret == 1, "got %d\n", ret );
3632 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3633 memset( data, 0xaa, sizeof(data) );
3635 info->bmiHeader.biHeight = 16;
3636 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3637 ok( ret == 5, "got %d\n", ret );
3638 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3639 ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
3640 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3641 memset( data, 0xaa, sizeof(data) );
3643 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3644 ok( ret == 6, "got %d\n", ret );
3645 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3646 ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
3647 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3648 memset( data, 0xaa, sizeof(data) );
3650 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3651 ok( ret == 0, "got %d\n", ret );
3652 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3653 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3654 memset( data, 0xaa, sizeof(data) );
3656 info->bmiHeader.biHeight = 5;
3657 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3658 ok( ret == 2, "got %d\n", ret );
3659 ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
3660 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3661 memset( data, 0xaa, sizeof(data) );
3665 info->bmiHeader.biHeight = -8;
3666 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3667 ok( ret == 8, "got %d\n", ret );
3668 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3669 memset( data, 0xaa, sizeof(data) );
3671 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3672 ok( ret == 5, "got %d\n", ret );
3673 ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
3674 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3675 memset( data, 0xaa, sizeof(data) );
3677 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3678 ok( ret == 7, "got %d\n", ret );
3679 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3680 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3681 memset( data, 0xaa, sizeof(data) );
3683 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3684 ok( ret == 4, "got %d\n", ret );
3685 ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
3686 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3687 memset( data, 0xaa, sizeof(data) );
3689 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3690 ok( ret == 5, "got %d\n", ret );
3691 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3692 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3693 memset( data, 0xaa, sizeof(data) );
3695 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3696 ok( ret == 5, "got %d\n", ret );
3697 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3698 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3699 memset( data, 0xaa, sizeof(data) );
3701 info->bmiHeader.biHeight = -16;
3702 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3703 ok( ret == 8, "got %d\n", ret );
3704 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3705 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3706 memset( data, 0xaa, sizeof(data) );
3708 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3709 ok( ret == 5, "got %d\n", ret );
3710 ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
3711 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3712 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3713 memset( data, 0xaa, sizeof(data) );
3715 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3716 ok( ret == 8, "got %d\n", ret );
3717 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3718 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3719 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3720 memset( data, 0xaa, sizeof(data) );
3722 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3723 ok( ret == 8, "got %d\n", ret );
3724 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3725 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3726 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3727 memset( data, 0xaa, sizeof(data) );
3729 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3730 ok( ret == 7, "got %d\n", ret );
3731 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3732 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3733 memset( data, 0xaa, sizeof(data) );
3735 ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
3736 ok( ret == 1, "got %d\n", ret );
3737 for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3738 memset( data, 0xaa, sizeof(data) );
3740 info->bmiHeader.biHeight = -5;
3741 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3742 ok( ret == 2, "got %d\n", ret );
3743 ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
3744 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3745 memset( data, 0xaa, sizeof(data) );
3747 DeleteObject( dib );
3749 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3750 info->bmiHeader.biWidth = 8;
3751 info->bmiHeader.biHeight = -8;
3752 info->bmiHeader.biPlanes = 1;
3753 info->bmiHeader.biBitCount = 32;
3754 info->bmiHeader.biCompression = BI_RGB;
3756 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3758 for (i = 0; i < 64; i++) dib_bits[i] = i;
3762 info->bmiHeader.biHeight = -8;
3763 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3764 ok( ret == 8, "got %d\n", ret );
3765 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3766 memset( data, 0xaa, sizeof(data) );
3768 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3769 ok( ret == 5, "got %d\n", ret );
3770 ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
3771 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3772 memset( data, 0xaa, sizeof(data) );
3774 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3775 ok( ret == 7, "got %d\n", ret );
3776 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3777 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3778 memset( data, 0xaa, sizeof(data) );
3780 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3781 ok( ret == 4, "got %d\n", ret );
3782 ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
3783 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3784 memset( data, 0xaa, sizeof(data) );
3786 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3787 ok( ret == 5, "got %d\n", ret );
3788 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3789 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3790 memset( data, 0xaa, sizeof(data) );
3792 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3793 ok( ret == 5, "got %d\n", ret );
3794 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3795 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3796 memset( data, 0xaa, sizeof(data) );
3798 info->bmiHeader.biHeight = -16;
3799 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3800 ok( ret == 8, "got %d\n", ret );
3801 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3802 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3803 memset( data, 0xaa, sizeof(data) );
3805 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3806 ok( ret == 5, "got %d\n", ret );
3807 ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
3808 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3809 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3810 memset( data, 0xaa, sizeof(data) );
3812 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3813 ok( ret == 8, "got %d\n", ret );
3814 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3815 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3816 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3817 memset( data, 0xaa, sizeof(data) );
3819 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3820 ok( ret == 8, "got %d\n", ret );
3821 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3822 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3823 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3824 memset( data, 0xaa, sizeof(data) );
3826 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3827 ok( ret == 7, "got %d\n", ret );
3828 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3829 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3830 memset( data, 0xaa, sizeof(data) );
3832 info->bmiHeader.biHeight = -5;
3833 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3834 ok( ret == 2, "got %d\n", ret );
3835 ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
3836 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3837 memset( data, 0xaa, sizeof(data) );
3842 info->bmiHeader.biHeight = 8;
3844 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3845 ok( ret == 8, "got %d\n", ret );
3846 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3847 memset( data, 0xaa, sizeof(data) );
3849 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3850 ok( ret == 5, "got %d\n", ret );
3851 ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
3852 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3853 memset( data, 0xaa, sizeof(data) );
3855 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3856 ok( ret == 7, "got %d\n", ret );
3857 ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
3858 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3859 memset( data, 0xaa, sizeof(data) );
3861 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3862 ok( ret == 1, "got %d\n", ret );
3863 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3864 memset( data, 0xaa, sizeof(data) );
3866 info->bmiHeader.biHeight = 16;
3867 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3868 ok( ret == 5, "got %d\n", ret );
3869 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3870 ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
3871 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3872 memset( data, 0xaa, sizeof(data) );
3874 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3875 ok( ret == 6, "got %d\n", ret );
3876 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3877 ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
3878 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3879 memset( data, 0xaa, sizeof(data) );
3881 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3882 ok( ret == 0, "got %d\n", ret );
3883 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3884 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3885 memset( data, 0xaa, sizeof(data) );
3887 info->bmiHeader.biHeight = 5;
3888 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3889 ok( ret == 2, "got %d\n", ret );
3890 ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
3891 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3892 memset( data, 0xaa, sizeof(data) );
3894 DeleteObject( dib );
3896 ReleaseDC( NULL, hdc );
3897 HeapFree( GetProcessHeap(), 0, info );
3901 static void test_SetDIBits(void)
3905 HDC hdc = GetDC( NULL );
3906 DWORD data[128], inverted_data[128];
3910 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
3912 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3913 info->bmiHeader.biWidth = 8;
3914 info->bmiHeader.biHeight = 8;
3915 info->bmiHeader.biPlanes = 1;
3916 info->bmiHeader.biBitCount = 32;
3917 info->bmiHeader.biCompression = BI_RGB;
3919 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3920 memset( dib_bits, 0xaa, 64 * 4 );
3922 for (i = 0; i < 128; i++)
3925 inverted_data[120 - (i & ~7) + (i & 7)] = i;
3930 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3931 ok( ret == 8, "got %d\n", ret );
3932 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
3933 memset( dib_bits, 0xaa, 64 * 4 );
3935 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3936 ok( ret == 5, "got %d\n", ret );
3937 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3938 ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
3939 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3940 memset( dib_bits, 0xaa, 64 * 4 );
3942 /* top of dst is aligned with startscans down for the top of the src.
3943 Then starting from the bottom of src, lines rows are copied across. */
3945 info->bmiHeader.biHeight = 16;
3946 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3947 ok( ret == 12, "got %d\n", ret );
3948 ok( !memcmp( dib_bits, data + 56, 40 * 4 ), "bits differ\n");
3949 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3950 memset( dib_bits, 0xaa, 64 * 4 );
3952 info->bmiHeader.biHeight = 5;
3953 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3954 ok( ret == 2, "got %d\n", ret );
3955 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3956 ok( !memcmp( dib_bits + 32, data, 16 * 4 ), "bits differ\n");
3957 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3958 memset( dib_bits, 0xaa, 64 * 4 );
3961 info->bmiHeader.biHeight = -8;
3962 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3963 ok( ret == 8, "got %d\n", ret );
3964 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3965 memset( dib_bits, 0xaa, 64 * 4 );
3967 /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
3968 we copy lines rows from the top of the src */
3970 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3971 ok( ret == 5, "got %d\n", ret );
3972 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3973 ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
3974 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3975 memset( dib_bits, 0xaa, 64 * 4 );
3977 info->bmiHeader.biHeight = -16;
3978 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3979 ok( ret == 12, "got %d\n", ret );
3980 ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
3981 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3982 memset( dib_bits, 0xaa, 64 * 4 );
3984 ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3985 ok( ret == 12, "got %d\n", ret );
3986 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3987 memset( dib_bits, 0xaa, 64 * 4 );
3989 ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3990 ok( ret == 12, "got %d\n", ret );
3991 ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
3992 memset( dib_bits, 0xaa, 64 * 4 );
3994 info->bmiHeader.biHeight = -5;
3995 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3996 ok( ret == 2, "got %d\n", ret );
3997 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3998 ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
3999 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4000 memset( dib_bits, 0xaa, 64 * 4 );
4002 DeleteObject( dib );
4004 info->bmiHeader.biHeight = -8;
4006 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4007 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4011 /* like the t-d -> b-u case. */
4013 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4014 ok( ret == 8, "got %d\n", ret );
4015 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4016 memset( dib_bits, 0xaa, 64 * 4 );
4018 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4019 ok( ret == 5, "got %d\n", ret );
4020 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4021 ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
4022 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4023 memset( dib_bits, 0xaa, 64 * 4 );
4025 info->bmiHeader.biHeight = -16;
4026 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4027 ok( ret == 12, "got %d\n", ret );
4028 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4029 ok( !memcmp( dib_bits + 24, data, 40 * 4 ), "bits differ\n");
4030 memset( dib_bits, 0xaa, 64 * 4 );
4032 info->bmiHeader.biHeight = -5;
4033 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4034 ok( ret == 2, "got %d\n", ret );
4035 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4036 ok( !memcmp( dib_bits + 16, data, 16 * 4 ), "bits differ\n");
4037 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4038 memset( dib_bits, 0xaa, 64 * 4 );
4041 /* like the b-u -> b-u case */
4043 info->bmiHeader.biHeight = 8;
4044 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4045 ok( ret == 8, "got %d\n", ret );
4046 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4047 memset( dib_bits, 0xaa, 64 * 4 );
4049 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4050 ok( ret == 5, "got %d\n", ret );
4051 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4052 ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
4053 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4054 memset( dib_bits, 0xaa, 64 * 4 );
4056 info->bmiHeader.biHeight = 16;
4057 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4058 ok( ret == 12, "got %d\n", ret );
4059 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4060 ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
4061 memset( dib_bits, 0xaa, 64 * 4 );
4063 info->bmiHeader.biHeight = 5;
4064 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4065 ok( ret == 2, "got %d\n", ret );
4066 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4067 ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
4068 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4069 memset( dib_bits, 0xaa, 64 * 4 );
4071 DeleteObject( dib );
4072 ReleaseDC( NULL, hdc );
4073 HeapFree( GetProcessHeap(), 0, info );
4076 static void test_SetDIBits_RLE4(void)
4080 HDC hdc = GetDC( NULL );
4081 BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00, /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
4082 0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
4083 0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00, /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
4084 0x00, 0x02, 0x01, 0x02, 0x05, 0x87, /* dx=1, dy=2, 8, 7, 8, 7, 8 */
4085 0x00, 0x01 }; /* <eod> */
4088 DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
4089 0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
4090 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4091 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4092 0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
4093 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4094 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4095 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4097 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4099 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4100 info->bmiHeader.biWidth = 8;
4101 info->bmiHeader.biHeight = 8;
4102 info->bmiHeader.biPlanes = 1;
4103 info->bmiHeader.biBitCount = 32;
4104 info->bmiHeader.biCompression = BI_RGB;
4106 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4107 memset( dib_bits, 0xaa, 64 * 4 );
4109 info->bmiHeader.biBitCount = 4;
4110 info->bmiHeader.biCompression = BI_RLE4;
4111 info->bmiHeader.biSizeImage = sizeof(rle4_data);
4113 for (i = 0; i < 16; i++)
4115 info->bmiColors[i].rgbRed = i;
4116 info->bmiColors[i].rgbGreen = i;
4117 info->bmiColors[i].rgbBlue = i;
4118 info->bmiColors[i].rgbReserved = 0;
4121 ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
4122 ok( ret == 8, "got %d\n", ret );
4123 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
4124 memset( dib_bits, 0xaa, 64 * 4 );
4126 DeleteObject( dib );
4127 ReleaseDC( NULL, hdc );
4128 HeapFree( GetProcessHeap(), 0, info );
4131 static void test_SetDIBits_RLE8(void)
4135 HDC hdc = GetDC( NULL );
4136 BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00, /* 2, 2, 2, f0, f0, f0, f0, <eol> */
4137 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4138 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4139 0x00, 0x01 }; /* <eod> */
4142 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4143 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4144 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4145 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4146 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4147 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4148 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4149 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4150 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4151 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4152 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4153 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4154 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4155 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4156 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4157 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4159 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4161 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4162 info->bmiHeader.biWidth = 8;
4163 info->bmiHeader.biHeight = 8;
4164 info->bmiHeader.biPlanes = 1;
4165 info->bmiHeader.biBitCount = 32;
4166 info->bmiHeader.biCompression = BI_RGB;
4168 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4169 memset( dib_bits, 0xaa, 64 * 4 );
4171 info->bmiHeader.biBitCount = 8;
4172 info->bmiHeader.biCompression = BI_RLE8;
4173 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4175 for (i = 0; i < 256; i++)
4177 info->bmiColors[i].rgbRed = i;
4178 info->bmiColors[i].rgbGreen = i;
4179 info->bmiColors[i].rgbBlue = i;
4180 info->bmiColors[i].rgbReserved = 0;
4183 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4184 ok( ret == 8, "got %d\n", ret );
4185 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4186 memset( dib_bits, 0xaa, 64 * 4 );
4188 /* startscan and lines are ignored, unless lines == 0 */
4189 ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4190 ok( ret == 8, "got %d\n", ret );
4191 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4192 memset( dib_bits, 0xaa, 64 * 4 );
4194 ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4195 ok( ret == 8, "got %d\n", ret );
4196 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4197 memset( dib_bits, 0xaa, 64 * 4 );
4199 ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4200 ok( ret == 0, "got %d\n", ret );
4201 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4202 memset( dib_bits, 0xaa, 64 * 4 );
4204 /* reduce width to 4, left-hand side of dst is touched. */
4205 info->bmiHeader.biWidth = 4;
4206 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4207 ok( ret == 8, "got %d\n", ret );
4208 for (i = 0; i < 64; i++)
4210 DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4211 ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4213 memset( dib_bits, 0xaa, 64 * 4 );
4215 /* Show that the top lines are aligned by adjusting the height of the src */
4217 /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4218 info->bmiHeader.biWidth = 8;
4219 info->bmiHeader.biHeight = 4;
4220 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4221 ok( ret == 4, "got %d\n", ret );
4222 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4223 ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4224 memset( dib_bits, 0xaa, 64 * 4 );
4226 /* increase the height to 9 -> everything moves down one row. */
4227 info->bmiHeader.biHeight = 9;
4228 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4229 ok( ret == 9, "got %d\n", ret );
4230 ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4231 for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4232 memset( dib_bits, 0xaa, 64 * 4 );
4234 /* top-down compressed dibs are invalid */
4235 info->bmiHeader.biHeight = -8;
4236 SetLastError( 0xdeadbeef );
4237 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4238 ok( ret == 0, "got %d\n", ret );
4239 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4240 DeleteObject( dib );
4244 info->bmiHeader.biHeight = -8;
4245 info->bmiHeader.biBitCount = 32;
4246 info->bmiHeader.biCompression = BI_RGB;
4247 info->bmiHeader.biSizeImage = 0;
4249 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4250 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4252 info->bmiHeader.biHeight = 8;
4253 info->bmiHeader.biBitCount = 8;
4254 info->bmiHeader.biCompression = BI_RLE8;
4255 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4257 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4258 ok( ret == 8, "got %d\n", ret );
4259 ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4260 memset( dib_bits, 0xaa, 64 * 4 );
4262 info->bmiHeader.biHeight = 4;
4263 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4264 ok( ret == 4, "got %d\n", ret );
4265 ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4266 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4267 memset( dib_bits, 0xaa, 64 * 4 );
4269 info->bmiHeader.biHeight = 9;
4270 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4271 ok( ret == 9, "got %d\n", ret );
4272 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4273 ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4274 memset( dib_bits, 0xaa, 64 * 4 );
4276 DeleteObject( dib );
4277 ReleaseDC( NULL, hdc );
4278 HeapFree( GetProcessHeap(), 0, info );
4281 static void test_SetDIBitsToDevice(void)
4285 HDC hdc = CreateCompatibleDC( 0 );
4286 DWORD data[128], inverted_data[128];
4290 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4292 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4293 info->bmiHeader.biWidth = 8;
4294 info->bmiHeader.biHeight = 8;
4295 info->bmiHeader.biPlanes = 1;
4296 info->bmiHeader.biBitCount = 32;
4297 info->bmiHeader.biCompression = BI_RGB;
4299 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4300 memset( dib_bits, 0xaa, 64 * 4 );
4301 SelectObject( hdc, dib );
4303 for (i = 0; i < 128; i++)
4306 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4311 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4312 ok( ret == 8, "got %d\n", ret );
4313 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4314 memset( dib_bits, 0xaa, 64 * 4 );
4316 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4317 ok( ret == 5, "got %d\n", ret );
4318 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4319 for (i = 8; i < 48; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4320 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4321 memset( dib_bits, 0xaa, 64 * 4 );
4323 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 3, 1, 5, data, info, DIB_RGB_COLORS );
4324 ok( ret == 5, "got %d\n", ret );
4325 for (i = 0; i < 24; i++) ok( dib_bits[i] == data[i + 16], "%d: got %08x\n", i, dib_bits[i] );
4326 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4327 memset( dib_bits, 0xaa, 64 * 4 );
4329 info->bmiHeader.biHeight = 16;
4330 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4331 ok( ret == 7, "got %d\n", ret );
4332 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4333 for (i = 8; i < 64; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4334 memset( dib_bits, 0xaa, 64 * 4 );
4336 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 8, 0, 6, 1, 12, data, info, DIB_RGB_COLORS );
4337 ok( ret == 12, "got %d\n", ret );
4338 for (i = 0; i < 40; i++) ok( dib_bits[i] == data[i + 56], "%d: got %08x\n", i, dib_bits[i] );
4339 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4340 memset( dib_bits, 0xaa, 64 * 4 );
4342 ret = SetDIBitsToDevice( hdc, 0, -4, 8, 8, 0, 3, 1, 12, data, info, DIB_RGB_COLORS );
4343 ok( ret == 10, "got %d\n", ret );
4344 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4345 for (i = 32; i < 64; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4346 memset( dib_bits, 0xaa, 64 * 4 );
4348 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, -3, 1, 12, data, info, DIB_RGB_COLORS );
4349 ok( ret == 4, "got %d\n", ret );
4350 for (i = 0; i < 32; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4351 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4352 memset( dib_bits, 0xaa, 64 * 4 );
4354 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 5, 0, -2, 1, 12, data, info, DIB_RGB_COLORS );
4355 ok( ret == 2, "got %d\n", ret );
4356 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4357 for (i = 32; i < 48; i++) ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4358 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4359 memset( dib_bits, 0xaa, 64 * 4 );
4361 info->bmiHeader.biHeight = 5;
4362 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 2, 2, data, info, DIB_RGB_COLORS );
4363 ok( ret == 2, "got %d\n", ret );
4364 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4365 for (i = 16; i < 32; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4366 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4367 memset( dib_bits, 0xaa, 64 * 4 );
4369 ret = SetDIBitsToDevice( hdc, 3, 3, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4370 ok( ret == 3, "got %d\n", ret );
4371 for (i = 0; i < 64; i++)
4372 if (i == 27 || i == 28 || i == 35 || i == 36)
4373 ok( dib_bits[i] == data[i - 18], "%d: got %08x\n", i, dib_bits[i] );
4375 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4376 memset( dib_bits, 0xaa, 64 * 4 );
4378 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4379 ok( ret == 5, "got %d\n", ret );
4380 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4381 memset( dib_bits, 0xaa, 64 * 4 );
4383 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4384 ok( ret == 0, "got %d\n", ret );
4385 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4386 memset( dib_bits, 0xaa, 64 * 4 );
4388 SetMapMode( hdc, MM_ANISOTROPIC );
4389 SetWindowExtEx( hdc, 3, 3, NULL );
4390 ret = SetDIBitsToDevice( hdc, 2, 2, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4391 ok( ret == 3, "got %d\n", ret );
4392 for (i = 0; i < 64; i++)
4393 if (i == 41 || i == 42 || i == 49 || i == 50)
4394 ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4396 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4397 memset( dib_bits, 0xaa, 64 * 4 );
4399 SetWindowExtEx( hdc, -1, -1, NULL );
4400 ret = SetDIBitsToDevice( hdc, 2, 2, 4, 4, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4401 ok( ret == 4, "got %d\n", ret );
4402 for (i = 0; i < 64; i++)
4403 if (i == 48 || i == 49 || i == 56 || i == 57)
4404 ok( dib_bits[i] == data[i - 37], "%d: got %08x\n", i, dib_bits[i] );
4406 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4407 memset( dib_bits, 0xaa, 64 * 4 );
4408 SetMapMode( hdc, MM_TEXT );
4412 pSetLayout( hdc, LAYOUT_RTL );
4413 ret = SetDIBitsToDevice( hdc, 1, 2, 3, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4414 ok( ret == 3, "got %d\n", ret );
4415 for (i = 0; i < 64; i++)
4416 if (i == 36 || i == 37 || i == 38 || i == 44 || i == 45 || i == 46)
4417 ok( dib_bits[i] == data[i - 27], "%d: got %08x\n", i, dib_bits[i] );
4419 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4420 memset( dib_bits, 0xaa, 64 * 4 );
4421 pSetLayout( hdc, LAYOUT_LTR );
4425 info->bmiHeader.biHeight = -8;
4426 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4427 ok( ret == 8, "got %d\n", ret );
4428 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4429 memset( dib_bits, 0xaa, 64 * 4 );
4431 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4432 ok( ret == 5, "got %d\n", ret );
4433 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4434 for (i = 8; i < 48; i++) ok( dib_bits[i] == inverted_data[i + 80], "%d: got %08x\n", i, dib_bits[i] );
4435 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4436 memset( dib_bits, 0xaa, 64 * 4 );
4438 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 4, 1, 5, data, info, DIB_RGB_COLORS );
4439 ok( ret == 5, "got %d\n", ret );
4440 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4441 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4442 memset( dib_bits, 0xaa, 64 * 4 );
4444 info->bmiHeader.biHeight = -16;
4445 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4446 ok( ret == 12, "got %d\n", ret );
4447 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4448 for (i = 8; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4449 memset( dib_bits, 0xaa, 64 * 4 );
4451 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, 7, 1, 12, data, info, DIB_RGB_COLORS );
4452 ok( ret == 12, "got %d\n", ret );
4453 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4454 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4455 memset( dib_bits, 0xaa, 64 * 4 );
4457 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 4, 12, data, info, DIB_RGB_COLORS );
4458 ok( ret == 12, "got %d\n", ret );
4459 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4460 for (i = 32; i < 64; i++) ok( dib_bits[i] == inverted_data[i], "%d: got %08x\n", i, dib_bits[i] );
4461 memset( dib_bits, 0xaa, 64 * 4 );
4463 ret = SetDIBitsToDevice( hdc, 0, -3, 8, 8, 0, 2, 4, 12, data, info, DIB_RGB_COLORS );
4464 ok( ret == 12, "got %d\n", ret );
4465 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4466 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4467 memset( dib_bits, 0xaa, 64 * 4 );
4469 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, -2, 4, 12, data, info, DIB_RGB_COLORS );
4470 ok( ret == 12, "got %d\n", ret );
4471 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4472 for (i = 24; i < 40; i++) ok( dib_bits[i] == inverted_data[i + 8], "%d: got %08x\n", i, dib_bits[i] );
4473 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4474 memset( dib_bits, 0xaa, 64 * 4 );
4476 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 5, 12, data, info, DIB_RGB_COLORS );
4477 ok( ret == 12, "got %d\n", ret );
4478 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4479 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4480 memset( dib_bits, 0xaa, 64 * 4 );
4482 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4483 ok( ret == 12, "got %d\n", ret );
4484 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4485 memset( dib_bits, 0xaa, 64 * 4 );
4487 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -2, -4, 0, 12, data, info, DIB_RGB_COLORS );
4488 ok( ret == 12, "got %d\n", ret );
4489 for (i = 0; i < 64; i++)
4490 if (i == 31 || i == 39 || i == 47 || i == 55 || i == 63)
4491 ok( dib_bits[i] == inverted_data[i + 1], "%d: got %08x\n", i, dib_bits[i] );
4493 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4494 memset( dib_bits, 0xaa, 64 * 4 );
4496 info->bmiHeader.biHeight = -5;
4497 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4498 ok( ret == 2, "got %d\n", ret );
4499 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4500 for (i = 8; i < 24; i++) ok( dib_bits[i] == inverted_data[i + 104], "%d: got %08x\n", i, dib_bits[i] );
4501 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4502 memset( dib_bits, 0xaa, 64 * 4 );
4504 ret = SetDIBitsToDevice( hdc, 5, 4, 2, 2, 6, 3, 1, 5, data, info, DIB_RGB_COLORS );
4505 ok( ret == 5, "got %d\n", ret );
4506 for (i = 0; i < 64; i++)
4507 if (i == 21 || i == 22 || i == 29 || i == 30)
4508 ok( dib_bits[i] == inverted_data[i + 89], "%d: got %08x\n", i, dib_bits[i] );
4510 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4511 memset( dib_bits, 0xaa, 64 * 4 );
4513 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4514 ok( ret == 5, "got %d\n", ret );
4515 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4516 memset( dib_bits, 0xaa, 64 * 4 );
4518 info->bmiHeader.biHeight = -8;
4520 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4521 DeleteObject( SelectObject( hdc, dib ));
4522 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4526 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4527 ok( ret == 8, "got %d\n", ret );
4528 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4529 memset( dib_bits, 0xaa, 64 * 4 );
4531 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4532 ok( ret == 5, "got %d\n", ret );
4533 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4534 for (i = 16; i < 56; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4535 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4536 memset( dib_bits, 0xaa, 64 * 4 );
4538 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 3, 0, 2, 1, 5, data, info, DIB_RGB_COLORS );
4539 ok( ret == 5, "got %d\n", ret );
4540 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4541 for (i = 24; i < 48; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4542 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4543 memset( dib_bits, 0xaa, 64 * 4 );
4545 info->bmiHeader.biHeight = -16;
4546 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4547 ok( ret == 12, "got %d\n", ret );
4548 for (i = 0; i < 56; i++) ok( dib_bits[i] == data[i + 40], "%d: got %08x\n", i, dib_bits[i] );
4549 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4550 memset( dib_bits, 0xaa, 64 * 4 );
4552 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -1, -8, 0, 12, data, info, DIB_RGB_COLORS );
4553 ok( ret == 12, "got %d\n", ret );
4554 for (i = 0; i < 64; i++)
4555 if (i == 6 || i == 7)
4556 ok( dib_bits[i] == data[i + 82], "%d: got %08x\n", i, dib_bits[i] );
4558 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4559 memset( dib_bits, 0xaa, 64 * 4 );
4561 info->bmiHeader.biHeight = -5;
4562 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4563 ok( ret == 2, "got %d\n", ret );
4564 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4565 for (i = 40; i < 56; i++) ok( dib_bits[i] == data[i - 40], "%d: got %08x\n", i, dib_bits[i] );
4566 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4567 memset( dib_bits, 0xaa, 64 * 4 );
4569 ret = SetDIBitsToDevice( hdc, 7, 2, 8, 8, 1, 0, 0, 5, data, info, DIB_RGB_COLORS );
4570 ok( ret == 5, "got %d\n", ret );
4571 for (i = 0; i < 64; i++)
4572 if (i == 47 || i == 55 || i == 63)
4573 ok( dib_bits[i] == data[i - 46], "%d: got %08x\n", i, dib_bits[i] );
4575 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4576 memset( dib_bits, 0xaa, 64 * 4 );
4578 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4579 ok( ret == 5, "got %d\n", ret );
4580 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4581 memset( dib_bits, 0xaa, 64 * 4 );
4585 info->bmiHeader.biHeight = 8;
4586 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4587 ok( ret == 8, "got %d\n", ret );
4588 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4589 memset( dib_bits, 0xaa, 64 * 4 );
4591 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4592 ok( ret == 5, "got %d\n", ret );
4593 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4594 for (i = 16; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4595 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4596 memset( dib_bits, 0xaa, 64 * 4 );
4598 info->bmiHeader.biHeight = 16;
4599 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4600 ok( ret == 7, "got %d\n", ret );
4601 for (i = 0; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4602 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4603 memset( dib_bits, 0xaa, 64 * 4 );
4605 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, 0, -4, 1, 12, data, info, DIB_RGB_COLORS );
4606 ok( ret == 3, "got %d\n", ret );
4607 for (i = 0; i < 64; i++)
4608 if ((i >= 36 && i <= 39) || (i >= 44 && i <= 47) || (i >= 52 && i <= 55))
4609 ok( dib_bits[i] == inverted_data[i + 68], "%d: got %08x\n", i, dib_bits[i] );
4611 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4612 memset( dib_bits, 0xaa, 64 * 4 );
4614 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, -30, -30, 1, 12, data, info, DIB_RGB_COLORS );
4615 ok( ret == 0, "got %d\n", ret );
4616 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4617 memset( dib_bits, 0xaa, 64 * 4 );
4619 ret = SetDIBitsToDevice( hdc, 5, -5, 8, 16, -2, -4, 4, 12, data, info, DIB_RGB_COLORS );
4620 ok( ret == 8, "got %d\n", ret );
4621 for (i = 0; i < 64; i++)
4622 if (i == 7 || i == 15 || i == 23)
4623 ok( dib_bits[i] == inverted_data[i + 97], "%d: got %08x\n", i, dib_bits[i] );
4625 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4626 memset( dib_bits, 0xaa, 64 * 4 );
4628 info->bmiHeader.biHeight = 5;
4629 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4630 ok( ret == 2, "got %d\n", ret );
4631 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4632 for (i = 40; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4633 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4634 memset( dib_bits, 0xaa, 64 * 4 );
4636 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4637 ok( ret == 5, "got %d\n", ret );
4638 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4639 memset( dib_bits, 0xaa, 64 * 4 );
4642 DeleteObject( dib );
4643 HeapFree( GetProcessHeap(), 0, info );
4646 static void test_SetDIBitsToDevice_RLE8(void)
4650 HDC hdc = CreateCompatibleDC( 0 );
4651 BYTE rle8_data[20] = { 0x04, 0x02, 0x03, 0xf0, 0x00, 0x00, /* 2, 2, 2, 2, f0, f0, f0, <eol> */
4652 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4653 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4654 0x00, 0x01 }; /* <eod> */
4657 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4658 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4659 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4660 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4661 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4662 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4663 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4664 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4665 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4666 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4667 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4668 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4669 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4670 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4671 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4672 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4674 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4676 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4677 info->bmiHeader.biWidth = 8;
4678 info->bmiHeader.biHeight = 8;
4679 info->bmiHeader.biPlanes = 1;
4680 info->bmiHeader.biBitCount = 32;
4681 info->bmiHeader.biCompression = BI_RGB;
4683 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4684 memset( dib_bits, 0xaa, 64 * 4 );
4685 SelectObject( hdc, dib );
4687 info->bmiHeader.biBitCount = 8;
4688 info->bmiHeader.biCompression = BI_RLE8;
4689 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4691 for (i = 0; i < 256; i++)
4693 info->bmiColors[i].rgbRed = i;
4694 info->bmiColors[i].rgbGreen = i;
4695 info->bmiColors[i].rgbBlue = i;
4696 info->bmiColors[i].rgbReserved = 0;
4699 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4700 ok( ret == 8, "got %d\n", ret );
4701 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4702 memset( dib_bits, 0xaa, 64 * 4 );
4704 /* startscan and lines are ignored, unless lines == 0 */
4705 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4706 ok( ret == 8, "got %d\n", ret );
4707 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4708 memset( dib_bits, 0xaa, 64 * 4 );
4710 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4711 ok( ret == 8, "got %d\n", ret );
4712 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4713 memset( dib_bits, 0xaa, 64 * 4 );
4715 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4716 ok( ret == 0, "got %d\n", ret );
4717 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4718 memset( dib_bits, 0xaa, 64 * 4 );
4720 info->bmiHeader.biWidth = 2;
4721 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4722 ok( ret == 8, "got %d\n", ret );
4723 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4724 memset( dib_bits, 0xaa, 64 * 4 );
4726 info->bmiHeader.biWidth = 8;
4727 info->bmiHeader.biHeight = 2;
4728 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4729 ok( ret == 2, "got %d\n", ret );
4730 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4731 memset( dib_bits, 0xaa, 64 * 4 );
4733 info->bmiHeader.biHeight = 9;
4734 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4735 ok( ret == 9, "got %d\n", ret );
4736 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4737 memset( dib_bits, 0xaa, 64 * 4 );
4739 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4740 ok( ret == 9, "got %d\n", ret );
4741 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4742 memset( dib_bits, 0xaa, 64 * 4 );
4744 info->bmiHeader.biHeight = 8;
4745 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 9, rle8_data, info, DIB_RGB_COLORS );
4746 ok( ret == 8, "got %d\n", ret );
4747 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4748 memset( dib_bits, 0xaa, 64 * 4 );
4750 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4751 ok( ret == 8, "got %d\n", ret );
4752 for (i = 0; i < 40; i++) ok( dib_bits[i] == bottom_up[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4753 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4754 memset( dib_bits, 0xaa, 64 * 4 );
4756 ret = SetDIBitsToDevice( hdc, 0, 3, 4, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4757 ok( ret == 8, "got %d\n", ret );
4758 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4759 for (i = 8; i < 40; i++)
4760 if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4761 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4762 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4763 memset( dib_bits, 0xaa, 64 * 4 );
4765 ret = SetDIBitsToDevice( hdc, 3, 3, 8, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4766 ok( ret == 8, "got %d\n", ret );
4767 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4768 for (i = 8; i < 40; i++)
4769 if ((i & 7) < 3) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4770 else ok( dib_bits[i] == bottom_up[i - 11], "%d: got %08x\n", i, dib_bits[i] );
4771 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4772 memset( dib_bits, 0xaa, 64 * 4 );
4774 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 4, 2, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4775 ok( ret == 8, "got %d\n", ret );
4776 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4777 for (i = 8; i < 40; i++)
4778 if ((i & 7) < 2) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4779 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4780 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4781 memset( dib_bits, 0xaa, 64 * 4 );
4783 info->bmiHeader.biWidth = 37;
4784 info->bmiHeader.biHeight = 37;
4785 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
4786 ok( ret == 37, "got %d\n", ret );
4787 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4788 for (i = 24; i < 64; i++)
4789 if (i == 52) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
4790 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4791 else ok( dib_bits[i] == bottom_up[i - 20], "%d: got %08x\n", i, dib_bits[i] );
4792 memset( dib_bits, 0xaa, 64 * 4 );
4794 /* top-down compressed dibs are invalid */
4795 info->bmiHeader.biWidth = 8;
4796 info->bmiHeader.biHeight = -8;
4797 SetLastError( 0xdeadbeef );
4798 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4799 ok( ret == 0, "got %d\n", ret );
4800 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4804 info->bmiHeader.biHeight = -8;
4805 info->bmiHeader.biBitCount = 32;
4806 info->bmiHeader.biCompression = BI_RGB;
4807 info->bmiHeader.biSizeImage = 0;
4809 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4810 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4811 DeleteObject( SelectObject( hdc, dib ));
4813 info->bmiHeader.biHeight = 8;
4814 info->bmiHeader.biBitCount = 8;
4815 info->bmiHeader.biCompression = BI_RLE8;
4816 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4818 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4819 ok( ret == 8, "got %d\n", ret );
4820 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4821 memset( dib_bits, 0xaa, 64 * 4 );
4823 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4824 ok( ret == 8, "got %d\n", ret );
4825 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4826 memset( dib_bits, 0xaa, 64 * 4 );
4828 info->bmiHeader.biHeight = 4;
4829 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4830 ok( ret == 4, "got %d\n", ret );
4831 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4832 memset( dib_bits, 0xaa, 64 * 4 );
4834 info->bmiHeader.biHeight = 9;
4835 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4836 ok( ret == 9, "got %d\n", ret );
4837 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4838 memset( dib_bits, 0xaa, 64 * 4 );
4840 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4841 ok( ret == 9, "got %d\n", ret );
4842 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4843 memset( dib_bits, 0xaa, 64 * 4 );
4845 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 6, 2, 2, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4846 ok( ret == 9, "got %d\n", ret );
4847 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4848 for (i = 24; i < 64; i++) ok( dib_bits[i] == top_down[i - 24], "%d: got %08x\n", i, dib_bits[i] );
4849 memset( dib_bits, 0xaa, 64 * 4 );
4851 info->bmiHeader.biWidth = 37;
4852 info->bmiHeader.biHeight = 37;
4853 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
4854 ok( ret == 37, "got %d\n", ret );
4855 for (i = 0; i < 40; i++)
4856 if (i == 12) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
4857 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4858 else ok( dib_bits[i] == top_down[i + 28], "%d: got %08x\n", i, dib_bits[i] );
4859 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4860 memset( dib_bits, 0xaa, 64 * 4 );
4863 DeleteObject( dib );
4864 HeapFree( GetProcessHeap(), 0, info );
4871 hdll = GetModuleHandle("gdi32.dll");
4872 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
4873 pSetLayout = (void*)GetProcAddress(hdll, "SetLayout");
4875 test_createdibitmap();
4878 test_mono_dibsection();
4881 test_GetDIBits_selected_DIB(1);
4882 test_GetDIBits_selected_DIB(4);
4883 test_GetDIBits_selected_DIB(8);
4884 test_GetDIBits_selected_DDB(TRUE);
4885 test_GetDIBits_selected_DDB(FALSE);
4887 test_GetDIBits_BI_BITFIELDS();
4888 test_select_object();
4889 test_CreateBitmap();
4892 test_StretchDIBits();
4893 test_GdiAlphaBlend();
4894 test_32bit_bitmap_blt();
4895 test_bitmapinfoheadersize();
4898 test_GetDIBits_top_down(16);
4899 test_GetDIBits_top_down(24);
4900 test_GetDIBits_top_down(32);
4901 test_GetSetDIBits_rtl();
4902 test_GetDIBits_scanlines();
4904 test_SetDIBits_RLE4();
4905 test_SetDIBits_RLE8();
4906 test_SetDIBitsToDevice();
4907 test_SetDIBitsToDevice_RLE8();