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)
819 char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256])];
820 BITMAPINFO *bi = (BITMAPINFO *)buffer;
823 int planes, bpp, compr;
827 BOOL expect_ok, todo;
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 );
1128 static void test_mono_dibsection(void)
1131 HBITMAP old_bm, mono_ds;
1132 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
1133 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
1140 memdc = CreateCompatibleDC(hdc);
1142 memset(pbmi, 0, sizeof(bmibuf));
1143 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
1144 pbmi->bmiHeader.biHeight = 10;
1145 pbmi->bmiHeader.biWidth = 10;
1146 pbmi->bmiHeader.biBitCount = 1;
1147 pbmi->bmiHeader.biPlanes = 1;
1148 pbmi->bmiHeader.biCompression = BI_RGB;
1149 pbmi->bmiColors[0].rgbRed = 0xff;
1150 pbmi->bmiColors[0].rgbGreen = 0xff;
1151 pbmi->bmiColors[0].rgbBlue = 0xff;
1152 pbmi->bmiColors[1].rgbRed = 0x0;
1153 pbmi->bmiColors[1].rgbGreen = 0x0;
1154 pbmi->bmiColors[1].rgbBlue = 0x0;
1157 * First dib section is 'inverted' ie color[0] is white, color[1] is black
1160 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1161 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1162 old_bm = SelectObject(memdc, mono_ds);
1164 /* black border, white interior */
1165 Rectangle(memdc, 0, 0, 10, 10);
1166 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1167 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1169 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1171 memset(bits, 0, sizeof(bits));
1174 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1175 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1177 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1179 pbmi->bmiColors[0].rgbRed = 0x0;
1180 pbmi->bmiColors[0].rgbGreen = 0x0;
1181 pbmi->bmiColors[0].rgbBlue = 0x0;
1182 pbmi->bmiColors[1].rgbRed = 0xff;
1183 pbmi->bmiColors[1].rgbGreen = 0xff;
1184 pbmi->bmiColors[1].rgbBlue = 0xff;
1186 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1187 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1189 SelectObject(memdc, old_bm);
1190 DeleteObject(mono_ds);
1193 * Next dib section is 'normal' ie color[0] is black, color[1] is white
1196 pbmi->bmiColors[0].rgbRed = 0x0;
1197 pbmi->bmiColors[0].rgbGreen = 0x0;
1198 pbmi->bmiColors[0].rgbBlue = 0x0;
1199 pbmi->bmiColors[1].rgbRed = 0xff;
1200 pbmi->bmiColors[1].rgbGreen = 0xff;
1201 pbmi->bmiColors[1].rgbBlue = 0xff;
1203 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1204 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1205 old_bm = SelectObject(memdc, mono_ds);
1207 /* black border, white interior */
1208 Rectangle(memdc, 0, 0, 10, 10);
1209 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
1210 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
1212 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
1214 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1215 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1217 /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
1219 pbmi->bmiColors[0].rgbRed = 0xff;
1220 pbmi->bmiColors[0].rgbGreen = 0xff;
1221 pbmi->bmiColors[0].rgbBlue = 0xff;
1222 pbmi->bmiColors[1].rgbRed = 0x0;
1223 pbmi->bmiColors[1].rgbGreen = 0x0;
1224 pbmi->bmiColors[1].rgbBlue = 0x0;
1226 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1227 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1230 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
1233 pbmi->bmiColors[0].rgbRed = 0xff;
1234 pbmi->bmiColors[0].rgbGreen = 0xff;
1235 pbmi->bmiColors[0].rgbBlue = 0xff;
1236 pbmi->bmiColors[1].rgbRed = 0x0;
1237 pbmi->bmiColors[1].rgbGreen = 0x0;
1238 pbmi->bmiColors[1].rgbBlue = 0x0;
1239 num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors);
1240 ok(num == 2, "num = %d\n", num);
1242 /* black border, white interior */
1243 Rectangle(memdc, 0, 0, 10, 10);
1244 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1245 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1247 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1249 memset(bits, 0, sizeof(bits));
1252 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1253 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1255 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1257 pbmi->bmiColors[0].rgbRed = 0x0;
1258 pbmi->bmiColors[0].rgbGreen = 0x0;
1259 pbmi->bmiColors[0].rgbBlue = 0x0;
1260 pbmi->bmiColors[1].rgbRed = 0xff;
1261 pbmi->bmiColors[1].rgbGreen = 0xff;
1262 pbmi->bmiColors[1].rgbBlue = 0xff;
1264 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1265 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1267 SelectObject(memdc, old_bm);
1268 DeleteObject(mono_ds);
1271 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
1274 pbmi->bmiColors[0].rgbRed = 0xff;
1275 pbmi->bmiColors[0].rgbGreen = 0x0;
1276 pbmi->bmiColors[0].rgbBlue = 0x0;
1277 pbmi->bmiColors[1].rgbRed = 0xfe;
1278 pbmi->bmiColors[1].rgbGreen = 0x0;
1279 pbmi->bmiColors[1].rgbBlue = 0x0;
1281 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1282 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1283 old_bm = SelectObject(memdc, mono_ds);
1285 /* black border, white interior */
1286 Rectangle(memdc, 0, 0, 10, 10);
1287 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1288 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1290 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1292 pbmi->bmiColors[0].rgbRed = 0x0;
1293 pbmi->bmiColors[0].rgbGreen = 0x0;
1294 pbmi->bmiColors[0].rgbBlue = 0x0;
1295 pbmi->bmiColors[1].rgbRed = 0xff;
1296 pbmi->bmiColors[1].rgbGreen = 0xff;
1297 pbmi->bmiColors[1].rgbBlue = 0xff;
1299 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1300 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1302 /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
1304 pbmi->bmiColors[0].rgbRed = 0xff;
1305 pbmi->bmiColors[0].rgbGreen = 0xff;
1306 pbmi->bmiColors[0].rgbBlue = 0xff;
1307 pbmi->bmiColors[1].rgbRed = 0x0;
1308 pbmi->bmiColors[1].rgbGreen = 0x0;
1309 pbmi->bmiColors[1].rgbBlue = 0x0;
1311 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1312 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1314 SelectObject(memdc, old_bm);
1315 DeleteObject(mono_ds);
1321 static void test_bitmap(void)
1323 char buf[256], buf_cmp[256];
1324 HBITMAP hbmp, hbmp_old;
1330 hdc = CreateCompatibleDC(0);
1333 SetLastError(0xdeadbeef);
1334 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1337 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1338 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1339 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1344 SetLastError(0xdeadbeef);
1345 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1348 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1349 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1350 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1355 SetLastError(0xdeadbeef);
1356 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1357 ok(!hbmp, "CreateBitmap should fail\n");
1359 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1360 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1364 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1365 assert(hbmp != NULL);
1367 ret = GetObject(hbmp, sizeof(bm), &bm);
1368 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1370 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1371 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1372 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1373 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1374 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1375 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1376 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1378 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1379 assert(sizeof(buf) == sizeof(buf_cmp));
1381 ret = GetBitmapBits(hbmp, 0, NULL);
1382 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1384 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1385 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1387 memset(buf, 0xAA, sizeof(buf));
1388 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1389 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1390 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1392 hbmp_old = SelectObject(hdc, hbmp);
1394 ret = GetObject(hbmp, sizeof(bm), &bm);
1395 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1397 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1398 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1399 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1400 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1401 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1402 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1403 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1405 memset(buf, 0xAA, sizeof(buf));
1406 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1407 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1408 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1410 hbmp_old = SelectObject(hdc, hbmp_old);
1411 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1413 /* test various buffer sizes for GetObject */
1414 ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
1415 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1417 ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1418 ok(ret == 0, "%d != 0\n", ret);
1420 ret = GetObject(hbmp, 0, &bm);
1421 ok(ret == 0, "%d != 0\n", ret);
1423 ret = GetObject(hbmp, 1, &bm);
1424 ok(ret == 0, "%d != 0\n", ret);
1430 static void test_bmBits(void)
1436 memset(bits, 0, sizeof(bits));
1437 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1438 ok(hbmp != NULL, "CreateBitmap failed\n");
1440 memset(&bmp, 0xFF, sizeof(bmp));
1441 ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1442 "GetObject failed or returned a wrong structure size\n");
1443 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1448 static void test_GetDIBits_selected_DIB(UINT bpp)
1451 char bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1452 char bmibuf2[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1453 BITMAPINFO *info = (BITMAPINFO *)bmibuf;
1454 BITMAPINFO *info2 = (BITMAPINFO *)bmibuf2;
1457 UINT dib_size, dib32_size;
1464 /* Create a DIB section with a color table */
1466 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1467 info->bmiHeader.biWidth = 32;
1468 info->bmiHeader.biHeight = 32;
1469 info->bmiHeader.biPlanes = 1;
1470 info->bmiHeader.biBitCount = bpp;
1471 info->bmiHeader.biCompression = BI_RGB;
1472 info->bmiHeader.biXPelsPerMeter = 0;
1473 info->bmiHeader.biYPelsPerMeter = 0;
1474 info->bmiHeader.biClrUsed = 0;
1475 info->bmiHeader.biClrImportant = 0;
1477 for (i=0; i < (1u << bpp); i++)
1479 BYTE c = i * (1 << (8 - bpp));
1480 info->bmiColors[i].rgbRed = c;
1481 info->bmiColors[i].rgbGreen = c;
1482 info->bmiColors[i].rgbBlue = c;
1483 info->bmiColors[i].rgbReserved = 0;
1486 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1487 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1488 dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1490 /* Set the bits of the DIB section */
1491 for (i=0; i < dib_size; i++)
1493 ((BYTE *)bits)[i] = i % 256;
1496 /* Select the DIB into a DC */
1497 dib_dc = CreateCompatibleDC(NULL);
1498 old_bmp = SelectObject(dib_dc, dib);
1499 dc = CreateCompatibleDC(NULL);
1500 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
1502 /* Copy the DIB attributes but not the color table */
1503 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1505 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1506 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1508 /* Compare the color table and the bits */
1509 for (i=0; i < (1u << bpp); i++)
1510 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1511 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1512 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1513 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1514 "color table entry %d differs (bpp %d)\n", i, bpp );
1516 ok( !memcmp( bits, bits2, dib_size ), "bit mismatch (bpp %d)\n", bpp );
1518 /* Test various combinations of lines = 0 and bits2 = NULL */
1519 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1520 res = GetDIBits( dc, dib, 0, 0, bits2, info2, DIB_RGB_COLORS );
1521 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1522 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1523 "color table mismatch (bpp %d)\n", bpp );
1525 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1526 res = GetDIBits( dc, dib, 0, 0, NULL, info2, DIB_RGB_COLORS );
1527 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1528 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1529 "color table mismatch (bpp %d)\n", bpp );
1531 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1532 res = GetDIBits( dc, dib, 0, info->bmiHeader.biHeight, NULL, info2, DIB_RGB_COLORS );
1533 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1534 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1535 "color table mismatch (bpp %d)\n", bpp );
1537 /* Map into a 32bit-DIB */
1538 info2->bmiHeader.biBitCount = 32;
1539 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1540 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1542 /* Check if last pixel was set */
1543 pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
1544 ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
1546 HeapFree(GetProcessHeap(), 0, bits2);
1549 SelectObject(dib_dc, old_bmp);
1554 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1557 char bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1558 char bmibuf2[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1559 BITMAPINFO *info = (BITMAPINFO *)bmibuf;
1560 BITMAPINFO *info2 = (BITMAPINFO *)bmibuf2;
1570 width = height = 16;
1572 /* Create a DDB (device-dependent bitmap) */
1576 ddb = CreateBitmap(width, height, 1, 1, NULL);
1580 HDC screen_dc = GetDC(NULL);
1581 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1582 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1583 ReleaseDC(NULL, screen_dc);
1586 /* Set the pixels */
1587 ddb_dc = CreateCompatibleDC(NULL);
1588 old_bmp = SelectObject(ddb_dc, ddb);
1589 for (i = 0; i < width; i++)
1591 for (j=0; j < height; j++)
1593 BYTE c = (i * width + j) % 256;
1594 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1597 SelectObject(ddb_dc, old_bmp);
1599 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1600 info->bmiHeader.biWidth = width;
1601 info->bmiHeader.biHeight = height;
1602 info->bmiHeader.biPlanes = 1;
1603 info->bmiHeader.biBitCount = bpp;
1604 info->bmiHeader.biCompression = BI_RGB;
1606 dc = CreateCompatibleDC(NULL);
1608 /* Fill in biSizeImage */
1609 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1610 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1612 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1613 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1616 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1617 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1619 /* Copy the DIB attributes but not the color table */
1620 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1622 /* Select the DDB into another DC */
1623 old_bmp = SelectObject(ddb_dc, ddb);
1626 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1627 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1629 /* Compare the color table and the bits */
1632 for (i=0; i < (1u << bpp); i++)
1633 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1634 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1635 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1636 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1637 "color table entry %d differs (bpp %d)\n", i, bpp );
1640 ok( !memcmp( bits, bits2, info->bmiHeader.biSizeImage ), "bit mismatch (bpp %d)\n", bpp );
1642 /* Test the palette */
1643 if (info2->bmiHeader.biBitCount <= 8)
1645 WORD *colors = (WORD*)info2->bmiColors;
1647 /* Get the palette indices */
1648 res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1649 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1651 for (i = 0; i < (1 << info->bmiHeader.biBitCount); i++)
1652 ok( colors[i] == i, "%d: got %d (bpp %d)\n", i, colors[i], bpp );
1655 HeapFree(GetProcessHeap(), 0, bits2);
1656 HeapFree(GetProcessHeap(), 0, bits);
1659 SelectObject(ddb_dc, old_bmp);
1664 static void test_GetDIBits(void)
1666 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1667 static const BYTE bmp_bits_1[16 * 2] =
1669 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1670 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1671 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1672 0xff,0xff, 0,0, 0xff,0xff, 0,0
1674 /* 4-bytes aligned 1-bit DIB data: 16x16 */
1675 static const BYTE dib_bits_1[16 * 4] =
1677 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1678 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1679 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1680 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1682 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1683 static const BYTE bmp_bits_24[16 * 16*3] =
1685 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1686 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1687 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1688 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1689 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1690 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1691 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1692 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1693 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1694 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1695 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1696 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1697 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1698 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1699 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1700 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1701 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1702 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1703 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1704 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1705 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1706 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1707 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1708 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1709 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1710 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1711 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1712 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1713 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1714 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1715 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1716 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1718 /* 4-bytes aligned 24-bit DIB data: 16x16 */
1719 static const BYTE dib_bits_24[16 * 16*3] =
1721 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1724 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1725 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1726 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1727 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1728 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1729 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1730 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1731 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1732 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1733 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1734 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1735 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1736 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1737 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1738 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1739 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1740 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1741 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1742 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1743 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1744 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1745 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1746 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1747 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1748 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1749 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1750 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1751 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1752 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1757 int i, bytes, lines;
1759 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1760 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1761 PALETTEENTRY pal_ents[20];
1765 /* 1-bit source bitmap data */
1766 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1767 ok(hbmp != 0, "CreateBitmap failed\n");
1769 memset(&bm, 0xAA, sizeof(bm));
1770 bytes = GetObject(hbmp, sizeof(bm), &bm);
1771 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1772 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1773 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1774 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1775 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1776 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1777 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1778 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1780 bytes = GetBitmapBits(hbmp, 0, NULL);
1781 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1782 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1783 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1784 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1786 /* retrieve 1-bit DIB data */
1787 memset(bi, 0, sizeof(*bi));
1788 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1789 bi->bmiHeader.biWidth = bm.bmWidth;
1790 bi->bmiHeader.biHeight = bm.bmHeight;
1791 bi->bmiHeader.biPlanes = 1;
1792 bi->bmiHeader.biBitCount = 1;
1793 bi->bmiHeader.biCompression = BI_RGB;
1794 bi->bmiHeader.biSizeImage = 0;
1795 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1796 SetLastError(0xdeadbeef);
1797 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1798 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1799 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1800 broken(GetLastError() == 0xdeadbeef), /* winnt */
1801 "wrong error %u\n", GetLastError());
1802 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1804 memset(buf, 0xAA, sizeof(buf));
1805 SetLastError(0xdeadbeef);
1806 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1807 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1808 lines, bm.bmHeight, GetLastError());
1809 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1811 /* the color table consists of black and white */
1812 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1813 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1814 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1815 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1816 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1817 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1818 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1819 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1820 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1821 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1822 for (i = 2; i < 256; i++)
1824 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1825 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1826 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1827 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1828 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1831 /* returned bits are DWORD aligned and upside down */
1832 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1834 /* Test the palette indices */
1835 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1836 SetLastError(0xdeadbeef);
1837 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1838 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1839 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1840 for (i = 2; i < 256; i++)
1841 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[1]);
1843 /* retrieve 24-bit DIB data */
1844 memset(bi, 0, sizeof(*bi));
1845 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1846 bi->bmiHeader.biWidth = bm.bmWidth;
1847 bi->bmiHeader.biHeight = bm.bmHeight;
1848 bi->bmiHeader.biPlanes = 1;
1849 bi->bmiHeader.biBitCount = 24;
1850 bi->bmiHeader.biCompression = BI_RGB;
1851 bi->bmiHeader.biSizeImage = 0;
1852 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1853 memset(buf, 0xAA, sizeof(buf));
1854 SetLastError(0xdeadbeef);
1855 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1856 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1857 lines, bm.bmHeight, GetLastError());
1858 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1860 /* the color table doesn't exist for 24-bit images */
1861 for (i = 0; i < 256; i++)
1863 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1864 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1865 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1866 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1867 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1870 /* returned bits are DWORD aligned and upside down */
1871 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1874 /* 24-bit source bitmap data */
1875 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1876 ok(hbmp != 0, "CreateBitmap failed\n");
1877 SetLastError(0xdeadbeef);
1878 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1879 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1880 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1881 lines, bm.bmHeight, GetLastError());
1883 memset(&bm, 0xAA, sizeof(bm));
1884 bytes = GetObject(hbmp, sizeof(bm), &bm);
1885 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1886 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1887 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1888 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1889 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1890 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1891 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1892 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1894 bytes = GetBitmapBits(hbmp, 0, NULL);
1895 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
1896 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1897 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1898 bm.bmWidthBytes * bm.bmHeight, bytes);
1900 /* retrieve 1-bit DIB data */
1901 memset(bi, 0, sizeof(*bi));
1902 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1903 bi->bmiHeader.biWidth = bm.bmWidth;
1904 bi->bmiHeader.biHeight = bm.bmHeight;
1905 bi->bmiHeader.biPlanes = 1;
1906 bi->bmiHeader.biBitCount = 1;
1907 bi->bmiHeader.biCompression = BI_RGB;
1908 bi->bmiHeader.biSizeImage = 0;
1909 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1910 memset(buf, 0xAA, sizeof(buf));
1911 SetLastError(0xdeadbeef);
1912 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1913 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1914 lines, bm.bmHeight, GetLastError());
1915 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1917 /* the color table consists of black and white */
1918 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1919 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1920 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1921 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1922 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1923 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1924 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1925 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1926 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1927 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1928 for (i = 2; i < 256; i++)
1930 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1931 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1932 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1933 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1934 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1937 /* returned bits are DWORD aligned and upside down */
1938 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1940 /* Test the palette indices */
1941 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1942 SetLastError(0xdeadbeef);
1943 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1944 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1945 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1946 for (i = 2; i < 256; i++)
1947 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[i]);
1949 /* retrieve 4-bit DIB data */
1950 memset(bi, 0, sizeof(*bi));
1951 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1952 bi->bmiHeader.biWidth = bm.bmWidth;
1953 bi->bmiHeader.biHeight = bm.bmHeight;
1954 bi->bmiHeader.biPlanes = 1;
1955 bi->bmiHeader.biBitCount = 4;
1956 bi->bmiHeader.biCompression = BI_RGB;
1957 bi->bmiHeader.biSizeImage = 0;
1958 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1959 memset(buf, 0xAA, sizeof(buf));
1960 SetLastError(0xdeadbeef);
1961 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1962 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1963 lines, bm.bmHeight, GetLastError());
1965 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
1967 for (i = 0; i < 16; i++)
1970 int entry = i < 8 ? i : i + 4;
1972 if(entry == 7) entry = 12;
1973 else if(entry == 12) entry = 7;
1975 expect.rgbRed = pal_ents[entry].peRed;
1976 expect.rgbGreen = pal_ents[entry].peGreen;
1977 expect.rgbBlue = pal_ents[entry].peBlue;
1978 expect.rgbReserved = 0;
1980 ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
1981 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
1982 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
1983 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1984 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1987 /* retrieve 8-bit DIB data */
1988 memset(bi, 0, sizeof(*bi));
1989 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1990 bi->bmiHeader.biWidth = bm.bmWidth;
1991 bi->bmiHeader.biHeight = bm.bmHeight;
1992 bi->bmiHeader.biPlanes = 1;
1993 bi->bmiHeader.biBitCount = 8;
1994 bi->bmiHeader.biCompression = BI_RGB;
1995 bi->bmiHeader.biSizeImage = 0;
1996 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1997 memset(buf, 0xAA, sizeof(buf));
1998 SetLastError(0xdeadbeef);
1999 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2000 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2001 lines, bm.bmHeight, GetLastError());
2003 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2005 for (i = 0; i < 256; i++)
2009 if (i < 10 || i >= 246)
2011 int entry = i < 10 ? i : i - 236;
2012 expect.rgbRed = pal_ents[entry].peRed;
2013 expect.rgbGreen = pal_ents[entry].peGreen;
2014 expect.rgbBlue = pal_ents[entry].peBlue;
2018 expect.rgbRed = (i & 0x07) << 5;
2019 expect.rgbGreen = (i & 0x38) << 2;
2020 expect.rgbBlue = i & 0xc0;
2022 expect.rgbReserved = 0;
2024 ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
2025 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2026 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2027 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
2028 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
2031 /* retrieve 24-bit DIB data */
2032 memset(bi, 0, sizeof(*bi));
2033 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2034 bi->bmiHeader.biWidth = bm.bmWidth;
2035 bi->bmiHeader.biHeight = bm.bmHeight;
2036 bi->bmiHeader.biPlanes = 1;
2037 bi->bmiHeader.biBitCount = 24;
2038 bi->bmiHeader.biCompression = BI_RGB;
2039 bi->bmiHeader.biSizeImage = 0;
2040 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
2041 memset(buf, 0xAA, sizeof(buf));
2042 SetLastError(0xdeadbeef);
2043 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2044 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2045 lines, bm.bmHeight, GetLastError());
2046 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2048 /* the color table doesn't exist for 24-bit images */
2049 for (i = 0; i < 256; i++)
2051 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
2052 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
2053 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2054 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
2055 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
2058 /* returned bits are DWORD aligned and upside down */
2059 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2065 static void test_GetDIBits_BI_BITFIELDS(void)
2067 /* Try a screen resolution detection technique
2068 * from the September 1999 issue of Windows Developer's Journal
2069 * which seems to be in widespread use.
2070 * http://www.lesher.ws/highcolor.html
2071 * http://www.lesher.ws/vidfmt.c
2072 * It hinges on being able to retrieve the bitmaps
2073 * for the three primary colors in non-paletted 16 bit mode.
2075 char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
2077 LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
2078 DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
2084 memset(dibinfo, 0, sizeof(dibinfo_buf));
2085 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2088 ok(hdc != NULL, "GetDC failed?\n");
2089 hbm = CreateCompatibleBitmap(hdc, 1, 1);
2090 ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
2092 /* Call GetDIBits to fill in bmiHeader. */
2093 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2094 ok(ret == 1, "GetDIBits failed\n");
2095 if (dibinfo->bmiHeader.biBitCount > 8)
2097 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2098 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2099 "compression is %u (%d bpp)\n", dibinfo->bmiHeader.biCompression, dibinfo->bmiHeader.biBitCount );
2101 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2103 ok( !bitmasks[0], "red mask is set\n" );
2104 ok( !bitmasks[1], "green mask is set\n" );
2105 ok( !bitmasks[2], "blue mask is set\n" );
2107 /* test with NULL bits pointer and correct bpp */
2108 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2109 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2110 ok(ret == 1, "GetDIBits failed\n");
2112 ok( bitmasks[0] != 0, "red mask is not set\n" );
2113 ok( bitmasks[1] != 0, "green mask is not set\n" );
2114 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2115 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2117 /* test with valid bits pointer */
2118 memset(dibinfo, 0, sizeof(dibinfo_buf));
2119 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2120 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2121 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2122 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2123 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2124 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2126 ok( bitmasks[0] != 0, "red mask is not set\n" );
2127 ok( bitmasks[1] != 0, "green mask is not set\n" );
2128 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2129 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2131 /* now with bits and 0 lines */
2132 memset(dibinfo, 0, sizeof(dibinfo_buf));
2133 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2134 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2135 SetLastError(0xdeadbeef);
2136 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2137 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2139 ok( !bitmasks[0], "red mask is set\n" );
2140 ok( !bitmasks[1], "green mask is set\n" );
2141 ok( !bitmasks[2], "blue mask is set\n" );
2142 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2144 memset(bitmasks, 0, 3*sizeof(DWORD));
2145 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2146 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2147 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2149 ok( bitmasks[0] != 0, "red mask is not set\n" );
2150 ok( bitmasks[1] != 0, "green mask is not set\n" );
2151 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2152 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2155 else skip("bitmap in colortable mode, skipping BI_BITFIELDS tests\n");
2159 /* same thing now with a 32-bpp DIB section */
2161 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2162 dibinfo->bmiHeader.biWidth = 1;
2163 dibinfo->bmiHeader.biHeight = 1;
2164 dibinfo->bmiHeader.biPlanes = 1;
2165 dibinfo->bmiHeader.biBitCount = 32;
2166 dibinfo->bmiHeader.biCompression = BI_RGB;
2167 dibinfo->bmiHeader.biSizeImage = 0;
2168 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2169 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2170 dibinfo->bmiHeader.biClrUsed = 0;
2171 dibinfo->bmiHeader.biClrImportant = 0;
2172 bitmasks[0] = 0x0000ff;
2173 bitmasks[1] = 0x00ff00;
2174 bitmasks[2] = 0xff0000;
2175 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2176 ok( hbm != 0, "failed to create bitmap\n" );
2178 memset(dibinfo, 0, sizeof(dibinfo_buf));
2179 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2180 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2181 ok(ret == 1, "GetDIBits failed\n");
2182 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2184 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2185 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2186 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2187 ok( !bitmasks[0], "red mask is set\n" );
2188 ok( !bitmasks[1], "green mask is set\n" );
2189 ok( !bitmasks[2], "blue mask is set\n" );
2191 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2192 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2193 ok(ret == 1, "GetDIBits failed\n");
2194 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2195 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2196 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2197 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2198 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2200 ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
2201 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2202 ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
2204 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2208 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2209 dibinfo->bmiHeader.biWidth = 1;
2210 dibinfo->bmiHeader.biHeight = 1;
2211 dibinfo->bmiHeader.biPlanes = 1;
2212 dibinfo->bmiHeader.biBitCount = 32;
2213 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2214 dibinfo->bmiHeader.biSizeImage = 0;
2215 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2216 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2217 dibinfo->bmiHeader.biClrUsed = 0;
2218 dibinfo->bmiHeader.biClrImportant = 0;
2219 bitmasks[0] = 0x0000ff;
2220 bitmasks[1] = 0x00ff00;
2221 bitmasks[2] = 0xff0000;
2222 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2223 ok( hbm != 0, "failed to create bitmap\n" );
2227 memset(dibinfo, 0, sizeof(dibinfo_buf));
2228 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2229 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2230 ok(ret == 1, "GetDIBits failed\n");
2232 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
2233 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2234 ok( !bitmasks[0], "red mask is set\n" );
2235 ok( !bitmasks[1], "green mask is set\n" );
2236 ok( !bitmasks[2], "blue mask is set\n" );
2238 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2239 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2240 ok(ret == 1, "GetDIBits failed\n");
2241 ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
2242 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2243 ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
2244 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2249 /* 24-bpp DIB sections don't have bitfields */
2251 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2252 dibinfo->bmiHeader.biWidth = 1;
2253 dibinfo->bmiHeader.biHeight = 1;
2254 dibinfo->bmiHeader.biPlanes = 1;
2255 dibinfo->bmiHeader.biBitCount = 24;
2256 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2257 dibinfo->bmiHeader.biSizeImage = 0;
2258 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2259 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2260 dibinfo->bmiHeader.biClrUsed = 0;
2261 dibinfo->bmiHeader.biClrImportant = 0;
2262 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2263 ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
2264 dibinfo->bmiHeader.biCompression = BI_RGB;
2265 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2266 ok( hbm != 0, "failed to create bitmap\n" );
2268 memset(dibinfo, 0, sizeof(dibinfo_buf));
2269 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2270 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2271 ok(ret == 1, "GetDIBits failed\n");
2272 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2274 ok( dibinfo->bmiHeader.biCompression == BI_RGB,
2275 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2276 ok( !bitmasks[0], "red mask is set\n" );
2277 ok( !bitmasks[1], "green mask is set\n" );
2278 ok( !bitmasks[2], "blue mask is set\n" );
2280 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2281 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2282 ok(ret == 1, "GetDIBits failed\n");
2283 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2284 ok( !bitmasks[0], "red mask is set\n" );
2285 ok( !bitmasks[1], "green mask is set\n" );
2286 ok( !bitmasks[2], "blue mask is set\n" );
2287 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2290 ReleaseDC(NULL, hdc);
2293 static void test_select_object(void)
2296 HBITMAP hbm, hbm_old;
2298 DWORD depths[] = {8, 15, 16, 24, 32};
2303 ok(hdc != 0, "GetDC(0) failed\n");
2304 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2305 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2307 hbm_old = SelectObject(hdc, hbm);
2308 ok(hbm_old == 0, "SelectObject should fail\n");
2313 hdc = CreateCompatibleDC(0);
2314 ok(hdc != 0, "GetDC(0) failed\n");
2315 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2316 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2318 hbm_old = SelectObject(hdc, hbm);
2319 ok(hbm_old != 0, "SelectObject failed\n");
2320 hbm_old = SelectObject(hdc, hbm_old);
2321 ok(hbm_old == hbm, "SelectObject failed\n");
2325 /* test an 1-bpp bitmap */
2326 planes = GetDeviceCaps(hdc, PLANES);
2329 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
2330 ok(hbm != 0, "CreateBitmap failed\n");
2332 hbm_old = SelectObject(hdc, hbm);
2333 ok(hbm_old != 0, "SelectObject failed\n");
2334 hbm_old = SelectObject(hdc, hbm_old);
2335 ok(hbm_old == hbm, "SelectObject failed\n");
2339 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
2340 /* test a color bitmap to dc bpp matching */
2341 planes = GetDeviceCaps(hdc, PLANES);
2342 bpp = GetDeviceCaps(hdc, BITSPIXEL);
2344 hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
2345 ok(hbm != 0, "CreateBitmap failed\n");
2347 hbm_old = SelectObject(hdc, hbm);
2348 if(depths[i] == bpp ||
2349 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
2351 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
2352 SelectObject(hdc, hbm_old);
2354 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
2357 memset(&bm, 0xAA, sizeof(bm));
2358 bytes = GetObject(hbm, sizeof(bm), &bm);
2359 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2360 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2361 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
2362 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
2363 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2364 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
2365 if(depths[i] == 15) {
2366 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
2368 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2370 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2378 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
2383 ret = GetObjectType(hbmp);
2384 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
2386 ret = GetObject(hbmp, 0, 0);
2387 ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
2389 memset(&bm, 0xDA, sizeof(bm));
2390 SetLastError(0xdeadbeef);
2391 ret = GetObject(hbmp, sizeof(bm), &bm);
2392 if (!ret) /* XP, only for curObj2 */ return;
2393 ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
2394 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2395 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2396 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2397 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2398 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2399 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2400 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2403 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2405 static void test_CreateBitmap(void)
2408 HDC screenDC = GetDC(0);
2409 HDC hdc = CreateCompatibleDC(screenDC);
2412 /* all of these are the stock monochrome bitmap */
2413 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2414 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2415 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2416 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2417 HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2418 HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2420 /* these 2 are not the stock monochrome bitmap */
2421 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2422 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2424 HBITMAP old1 = SelectObject(hdc, bm2);
2425 HBITMAP old2 = SelectObject(screenDC, bm3);
2426 SelectObject(hdc, old1);
2427 SelectObject(screenDC, old2);
2429 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2430 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2431 bm, bm1, bm4, bm5, curObj1, old1);
2432 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2434 ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
2435 ok(old2 == 0, "old2 %p\n", old2);
2437 test_mono_1x1_bmp(bm);
2438 test_mono_1x1_bmp(bm1);
2439 test_mono_1x1_bmp(bm2);
2440 test_mono_1x1_bmp(bm3);
2441 test_mono_1x1_bmp(bm4);
2442 test_mono_1x1_bmp(bm5);
2443 test_mono_1x1_bmp(old1);
2444 test_mono_1x1_bmp(curObj1);
2454 ReleaseDC(0, screenDC);
2456 /* show that Windows ignores the provided bm.bmWidthBytes */
2460 bmp.bmWidthBytes = 28;
2462 bmp.bmBitsPixel = 1;
2464 bm = CreateBitmapIndirect(&bmp);
2465 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2466 test_mono_1x1_bmp(bm);
2469 /* Test how the bmBitsPixel field is treated */
2470 for(i = 1; i <= 33; i++) {
2474 bmp.bmWidthBytes = 28;
2476 bmp.bmBitsPixel = i;
2478 SetLastError(0xdeadbeef);
2479 bm = CreateBitmapIndirect(&bmp);
2481 DWORD error = GetLastError();
2482 ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
2483 ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2487 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2488 GetObject(bm, sizeof(bmp), &bmp);
2495 } else if(i <= 16) {
2497 } else if(i <= 24) {
2499 } else if(i <= 32) {
2502 ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2503 i, bmp.bmBitsPixel, expect);
2508 static void test_bitmapinfoheadersize(void)
2515 memset(&bmi, 0, sizeof(BITMAPINFO));
2516 bmi.bmiHeader.biHeight = 100;
2517 bmi.bmiHeader.biWidth = 512;
2518 bmi.bmiHeader.biBitCount = 24;
2519 bmi.bmiHeader.biPlanes = 1;
2521 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2523 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2524 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2526 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2528 SetLastError(0xdeadbeef);
2529 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2530 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2533 bmi.bmiHeader.biSize++;
2535 SetLastError(0xdeadbeef);
2536 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2538 broken(!hdib), /* Win98, WinMe */
2539 "CreateDIBSection error %d\n", GetLastError());
2542 bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2544 SetLastError(0xdeadbeef);
2545 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2547 broken(!hdib), /* Win98, WinMe */
2548 "CreateDIBSection error %d\n", GetLastError());
2551 bmi.bmiHeader.biSize++;
2553 SetLastError(0xdeadbeef);
2554 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2556 broken(!hdib), /* Win98, WinMe */
2557 "CreateDIBSection error %d\n", GetLastError());
2560 bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2562 SetLastError(0xdeadbeef);
2563 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2564 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2567 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2569 SetLastError(0xdeadbeef);
2570 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2572 broken(!hdib), /* Win95 */
2573 "CreateDIBSection error %d\n", GetLastError());
2576 memset(&bci, 0, sizeof(BITMAPCOREINFO));
2577 bci.bmciHeader.bcHeight = 100;
2578 bci.bmciHeader.bcWidth = 512;
2579 bci.bmciHeader.bcBitCount = 24;
2580 bci.bmciHeader.bcPlanes = 1;
2582 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2584 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2585 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2587 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2589 SetLastError(0xdeadbeef);
2590 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2591 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2594 bci.bmciHeader.bcSize++;
2596 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2597 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2599 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2601 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2602 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2607 static void test_get16dibits(void)
2609 BYTE bits[4 * (16 / sizeof(BYTE))];
2611 HDC screen_dc = GetDC(NULL);
2614 int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2616 int overwritten_bytes = 0;
2618 memset(bits, 0, sizeof(bits));
2619 hbmp = CreateBitmap(2, 2, 1, 16, bits);
2620 ok(hbmp != NULL, "CreateBitmap failed\n");
2622 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2625 memset(info, '!', info_len);
2626 memset(info, 0, sizeof(info->bmiHeader));
2628 info->bmiHeader.biSize = sizeof(info->bmiHeader);
2629 info->bmiHeader.biWidth = 2;
2630 info->bmiHeader.biHeight = 2;
2631 info->bmiHeader.biPlanes = 1;
2632 info->bmiHeader.biCompression = BI_RGB;
2634 ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2635 ok(ret != 0, "GetDIBits failed got %d\n", ret);
2637 for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2639 overwritten_bytes++;
2640 ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2642 HeapFree(GetProcessHeap(), 0, info);
2644 ReleaseDC(NULL, screen_dc);
2647 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2648 DWORD dwRop, UINT32 expected, int line)
2650 *srcBuffer = 0xFEDCBA98;
2651 *dstBuffer = 0x89ABCDEF;
2652 Rectangle(hdcSrc, 0, 0, 1, 1); /* A null operation to ensure dibs are coerced to X11 */
2653 BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
2654 ok(expected == *dstBuffer,
2655 "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2656 dwRop, expected, *dstBuffer, line);
2659 static void test_BitBlt(void)
2661 HBITMAP bmpDst, bmpSrc;
2662 HBITMAP oldDst, oldSrc;
2663 HDC hdcScreen, hdcDst, hdcSrc;
2664 UINT32 *dstBuffer, *srcBuffer;
2665 HBRUSH hBrush, hOldBrush;
2666 BITMAPINFO bitmapInfo;
2668 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2669 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2670 bitmapInfo.bmiHeader.biWidth = 1;
2671 bitmapInfo.bmiHeader.biHeight = 1;
2672 bitmapInfo.bmiHeader.biPlanes = 1;
2673 bitmapInfo.bmiHeader.biBitCount = 32;
2674 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2675 bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2677 hdcScreen = CreateCompatibleDC(0);
2678 hdcDst = CreateCompatibleDC(hdcScreen);
2679 hdcSrc = CreateCompatibleDC(hdcDst);
2681 /* Setup the destination dib section */
2682 bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
2684 oldDst = SelectObject(hdcDst, bmpDst);
2686 hBrush = CreateSolidBrush(0x012345678);
2687 hOldBrush = SelectObject(hdcDst, hBrush);
2689 /* Setup the source dib section */
2690 bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
2692 oldSrc = SelectObject(hdcSrc, bmpSrc);
2694 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2695 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2696 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2697 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2698 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2699 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2700 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2701 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2702 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2703 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2704 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2705 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2706 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2707 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2708 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2711 SelectObject(hdcSrc, oldSrc);
2712 DeleteObject(bmpSrc);
2715 SelectObject(hdcDst, hOldBrush);
2716 DeleteObject(hBrush);
2717 SelectObject(hdcDst, oldDst);
2718 DeleteObject(bmpDst);
2722 DeleteDC(hdcScreen);
2725 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2726 DWORD dwRop, UINT32 expected, int line)
2728 *srcBuffer = 0xFEDCBA98;
2729 *dstBuffer = 0x89ABCDEF;
2730 StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
2731 ok(expected == *dstBuffer,
2732 "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2733 dwRop, expected, *dstBuffer, line);
2736 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, BITMAPINFO *dst_info, UINT32 *dstBuffer, UINT32 *srcBuffer,
2737 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2738 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2739 UINT32 *expected, int line)
2741 int dst_size = get_dib_image_size( dst_info );
2743 memset(dstBuffer, 0, dst_size);
2744 StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2745 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
2746 ok(memcmp(dstBuffer, expected, dst_size) == 0,
2747 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2748 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2749 expected[0], expected[1], expected[2], expected[3],
2750 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2751 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2752 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2755 static void test_StretchBlt(void)
2757 HBITMAP bmpDst, bmpSrc;
2758 HBITMAP oldDst, oldSrc;
2759 HDC hdcScreen, hdcDst, hdcSrc;
2760 UINT32 *dstBuffer, *srcBuffer;
2761 HBRUSH hBrush, hOldBrush;
2762 BITMAPINFO biDst, biSrc;
2763 UINT32 expected[256];
2766 memset(&biDst, 0, sizeof(BITMAPINFO));
2767 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2768 biDst.bmiHeader.biWidth = 16;
2769 biDst.bmiHeader.biHeight = -16;
2770 biDst.bmiHeader.biPlanes = 1;
2771 biDst.bmiHeader.biBitCount = 32;
2772 biDst.bmiHeader.biCompression = BI_RGB;
2773 memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
2775 hdcScreen = CreateCompatibleDC(0);
2776 hdcDst = CreateCompatibleDC(hdcScreen);
2777 hdcSrc = CreateCompatibleDC(hdcDst);
2780 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2782 oldDst = SelectObject(hdcDst, bmpDst);
2784 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2786 oldSrc = SelectObject(hdcSrc, bmpSrc);
2788 hBrush = CreateSolidBrush(0x012345678);
2789 hOldBrush = SelectObject(hdcDst, hBrush);
2791 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2792 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2793 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2794 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2795 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2796 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2797 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2798 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2799 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2800 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2801 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2802 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2803 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2804 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2805 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2807 SelectObject(hdcDst, hOldBrush);
2808 DeleteObject(hBrush);
2810 /* Top-down to top-down tests */
2811 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2812 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2814 memset( expected, 0, get_dib_image_size( &biDst ) );
2815 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2816 expected[16] = 0xFEDCBA98, expected[17] = 0x76543210;
2817 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2818 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2820 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2821 expected[16] = 0x00000000, expected[17] = 0x00000000;
2822 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2823 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
2825 expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
2826 expected[16] = 0xCAFED00D, expected[17] = 0xCAFED00D;
2827 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2828 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
2830 /* This is an example of the dst width (height) == 1 exception, explored below */
2831 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2832 expected[16] = 0x00000000, expected[17] = 0x00000000;
2833 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2834 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
2836 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2837 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
2838 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2839 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2841 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2842 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
2843 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2844 1, 1, -2, -2, 0, 0, 2, 2, expected, __LINE__);
2846 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2847 expected[16] = 0x00000000, expected[17] = 0x00000000;
2848 todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2849 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
2851 expected[0] = 0x00000000, expected[1] = 0x00000000;
2852 expected[16] = 0x00000000, expected[17] = 0xCAFED00D, expected[18] = 0xFEEDFACE;
2853 expected[32] = 0x00000000, expected[33] = 0xFEDCBA98, expected[34] = 0x76543210;
2855 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2856 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2858 /* when dst width is 1 merge src width - 1 pixels */
2859 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
2860 srcBuffer[0] = 0x0000ff00, srcBuffer[1] = 0x0000f0f0, srcBuffer[2] = 0x0000cccc, srcBuffer[3] = 0x0000aaaa;
2861 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2863 memset( expected, 0, get_dib_image_size( &biDst ) );
2864 expected[0] = srcBuffer[0];
2865 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2866 0, 0, 1, 1, 0, 0, 2, 1, expected, __LINE__);
2868 expected[0] = srcBuffer[0] & srcBuffer[1];
2870 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2871 0, 0, 1, 1, 0, 0, 3, 1, expected, __LINE__);
2873 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
2875 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2876 0, 0, 1, 1, 0, 0, 4, 1, expected, __LINE__);
2878 /* this doesn't happen if the src width is -ve */
2879 expected[0] = srcBuffer[1] & srcBuffer[2];
2881 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2882 0, 0, 1, 1, 2, 0, -2, 1, expected, __LINE__);
2884 /* when dst width > 1 behaviour reverts to what one would expect */
2885 expected[0] = srcBuffer[0] & srcBuffer[1], expected[1] = srcBuffer[2] & srcBuffer[3];
2887 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2888 0, 0, 2, 1, 0, 0, 4, 1, expected, __LINE__);
2890 /* similarly in the vertical direction */
2891 memset( expected, 0, get_dib_image_size( &biDst ) );
2892 expected[0] = srcBuffer[0];
2893 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2894 0, 0, 1, 1, 0, 0, 1, 2, expected, __LINE__);
2896 /* check that it's the dst size in device units that needs to be 1 */
2897 SetMapMode( hdcDst, MM_ISOTROPIC );
2898 SetWindowExtEx( hdcDst, 200, 200, NULL );
2899 SetViewportExtEx( hdcDst, 100, 100, NULL );
2901 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
2903 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2904 0, 0, 2, 2, 0, 0, 4, 1, expected, __LINE__);
2905 SetMapMode( hdcDst, MM_TEXT );
2907 SelectObject(hdcDst, oldDst);
2908 DeleteObject(bmpDst);
2910 /* Top-down to bottom-up tests */
2911 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
2912 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2913 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2915 biDst.bmiHeader.biHeight = 16;
2916 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2918 oldDst = SelectObject(hdcDst, bmpDst);
2920 memset( expected, 0, get_dib_image_size( &biDst ) );
2922 expected[224] = 0xFEDCBA98, expected[225] = 0x76543210;
2923 expected[240] = 0xCAFED00D, expected[241] = 0xFEEDFACE;
2924 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2925 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2927 expected[224] = 0xFEEDFACE, expected[225] = 0xCAFED00D;
2928 expected[240] = 0x76543210, expected[241] = 0xFEDCBA98;
2929 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2930 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2932 SelectObject(hdcSrc, oldSrc);
2933 DeleteObject(bmpSrc);
2935 /* Bottom-up to bottom-up tests */
2936 biSrc.bmiHeader.biHeight = 16;
2937 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2939 srcBuffer[224] = 0xCAFED00D, srcBuffer[225] = 0xFEEDFACE;
2940 srcBuffer[240] = 0xFEDCBA98, srcBuffer[241] = 0x76543210;
2941 oldSrc = SelectObject(hdcSrc, bmpSrc);
2943 memset( expected, 0, get_dib_image_size( &biDst ) );
2945 expected[224] = 0xCAFED00D, expected[225] = 0xFEEDFACE;
2946 expected[240] = 0xFEDCBA98, expected[241] = 0x76543210;
2947 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2948 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2950 expected[224] = 0x76543210, expected[225] = 0xFEDCBA98;
2951 expected[240] = 0xFEEDFACE, expected[241] = 0xCAFED00D;
2952 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2953 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2955 SelectObject(hdcDst, oldDst);
2956 DeleteObject(bmpDst);
2958 /* Bottom-up to top-down tests */
2959 biDst.bmiHeader.biHeight = -16;
2960 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2962 oldDst = SelectObject(hdcDst, bmpDst);
2964 memset( expected, 0, get_dib_image_size( &biDst ) );
2965 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2966 expected[16] = 0xCAFED00D, expected[17] = 0xFEEDFACE;
2967 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2968 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2970 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2971 expected[16] = 0x76543210, expected[17] = 0xFEDCBA98;
2972 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2973 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2975 SelectObject(hdcSrc, oldSrc);
2976 DeleteObject(bmpSrc);
2978 biSrc.bmiHeader.biHeight = -2;
2979 biSrc.bmiHeader.biBitCount = 24;
2980 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
2981 oldSrc = SelectObject(hdcSrc, bmpSrc);
2983 memset( expected, 0, get_dib_image_size( &biDst ) );
2984 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2985 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2986 memcpy(dstBuffer, expected, 4 * sizeof(*dstBuffer));
2987 StretchBlt(hdcSrc, 0, 0, 4, 1, hdcDst, 0, 0, 4, 1, SRCCOPY );
2988 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
2989 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
2990 expected[0] = 0x00EDFACE, expected[1] = 0x00FED00D;
2991 expected[2] = 0x00543210, expected[3] = 0x00DCBA98;
2992 ok(!memcmp(dstBuffer, expected, 16),
2993 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
2994 expected[0], expected[1], expected[2], expected[3],
2995 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
2997 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2998 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2999 memcpy(srcBuffer, expected, 4 * sizeof(*dstBuffer));
3000 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
3001 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3002 expected[0] = 0x00EDFACE, expected[1] = 0x00D00DFE;
3003 expected[2] = 0x0010CAFE, expected[3] = 0x00765432;
3004 ok(!memcmp(dstBuffer, expected, 16),
3005 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3006 expected[0], expected[1], expected[2], expected[3],
3007 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3009 SelectObject(hdcSrc, oldSrc);
3010 DeleteObject(bmpSrc);
3012 biSrc.bmiHeader.biBitCount = 1;
3013 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
3014 oldSrc = SelectObject(hdcSrc, bmpSrc);
3015 *((DWORD *)colors + 0) = 0x123456;
3016 *((DWORD *)colors + 1) = 0x335577;
3017 SetDIBColorTable( hdcSrc, 0, 2, colors );
3018 srcBuffer[0] = 0x55555555;
3019 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
3020 SetTextColor( hdcDst, 0 );
3021 SetBkColor( hdcDst, 0 );
3022 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3023 expected[0] = expected[2] = 0x00123456;
3024 expected[1] = expected[3] = 0x00335577;
3025 ok(!memcmp(dstBuffer, expected, 16),
3026 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3027 expected[0], expected[1], expected[2], expected[3],
3028 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3030 SelectObject(hdcSrc, oldSrc);
3031 DeleteObject(bmpSrc);
3033 bmpSrc = CreateBitmap( 16, 16, 1, 1, 0 );
3034 oldSrc = SelectObject(hdcSrc, bmpSrc);
3035 SetPixel( hdcSrc, 0, 0, 0 );
3036 SetPixel( hdcSrc, 1, 0, 0xffffff );
3037 SetPixel( hdcSrc, 2, 0, 0xffffff );
3038 SetPixel( hdcSrc, 3, 0, 0 );
3039 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
3040 SetTextColor( hdcDst, RGB(0x22,0x44,0x66) );
3041 SetBkColor( hdcDst, RGB(0x65,0x43,0x21) );
3042 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3043 expected[0] = expected[3] = 0x00224466;
3044 expected[1] = expected[2] = 0x00654321;
3045 ok(!memcmp(dstBuffer, expected, 16),
3046 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3047 expected[0], expected[1], expected[2], expected[3],
3048 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3050 SelectObject(hdcSrc, oldSrc);
3051 DeleteObject(bmpSrc);
3055 SelectObject(hdcDst, oldDst);
3056 DeleteObject(bmpDst);
3059 DeleteDC(hdcScreen);
3062 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3063 DWORD dwRop, UINT32 expected, int line)
3065 const UINT32 buffer[2] = { 0xFEDCBA98, 0 };
3066 BITMAPINFO bitmapInfo;
3068 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3069 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3070 bitmapInfo.bmiHeader.biWidth = 2;
3071 bitmapInfo.bmiHeader.biHeight = 1;
3072 bitmapInfo.bmiHeader.biPlanes = 1;
3073 bitmapInfo.bmiHeader.biBitCount = 32;
3074 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3075 bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer);
3077 *dstBuffer = 0x89ABCDEF;
3079 StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop);
3080 ok(expected == *dstBuffer,
3081 "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
3082 dwRop, expected, *dstBuffer, line);
3085 static void check_StretchDIBits_stretch(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3086 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
3087 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
3088 UINT32 expected[4], UINT32 legacy_expected[4], int line)
3090 BITMAPINFO bitmapInfo;
3092 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3093 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3094 bitmapInfo.bmiHeader.biWidth = 2;
3095 bitmapInfo.bmiHeader.biHeight = -2;
3096 bitmapInfo.bmiHeader.biPlanes = 1;
3097 bitmapInfo.bmiHeader.biBitCount = 32;
3098 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3100 memset(dstBuffer, 0, 16);
3101 StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
3102 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3103 srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
3104 ok(memcmp(dstBuffer, expected, 16) == 0,
3105 "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
3106 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
3107 expected[0], expected[1], expected[2], expected[3],
3108 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
3109 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3110 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
3113 static void test_StretchDIBits(void)
3117 HDC hdcScreen, hdcDst;
3118 UINT32 *dstBuffer, srcBuffer[4];
3119 HBRUSH hBrush, hOldBrush;
3121 UINT32 expected[4], legacy_expected[4];
3123 memset(&biDst, 0, sizeof(BITMAPINFO));
3124 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3125 biDst.bmiHeader.biWidth = 2;
3126 biDst.bmiHeader.biHeight = -2;
3127 biDst.bmiHeader.biPlanes = 1;
3128 biDst.bmiHeader.biBitCount = 32;
3129 biDst.bmiHeader.biCompression = BI_RGB;
3131 hdcScreen = CreateCompatibleDC(0);
3132 hdcDst = CreateCompatibleDC(hdcScreen);
3135 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3137 oldDst = SelectObject(hdcDst, bmpDst);
3139 hBrush = CreateSolidBrush(0x012345678);
3140 hOldBrush = SelectObject(hdcDst, hBrush);
3142 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3143 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3144 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3145 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3146 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3147 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3148 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3149 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3150 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3151 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3152 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3153 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3154 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3155 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3156 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3158 SelectObject(hdcDst, hOldBrush);
3159 DeleteObject(hBrush);
3161 /* Top-down destination tests */
3162 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3163 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
3165 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
3166 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
3167 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3168 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
3170 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3171 expected[2] = 0x00000000, expected[3] = 0x00000000;
3172 legacy_expected[0] = 0xFEDCBA98, legacy_expected[1] = 0x00000000;
3173 legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
3174 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3175 0, 0, 1, 1, 0, 0, 1, 1, expected, legacy_expected, __LINE__);
3177 expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
3178 expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
3179 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3180 0, 0, 2, 2, 0, 0, 1, 1, expected, expected, __LINE__);
3182 expected[0] = 0x42441000, expected[1] = 0x00000000;
3183 expected[2] = 0x00000000, expected[3] = 0x00000000;
3184 legacy_expected[0] = 0x00543210, legacy_expected[1] = 0x00000000;
3185 legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
3186 todo_wine check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3187 0, 0, 1, 1, 0, 0, 2, 2, expected, legacy_expected, __LINE__);
3189 expected[0] = 0x00000000, expected[1] = 0x00000000;
3190 expected[2] = 0x00000000, expected[3] = 0x00000000;
3191 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3192 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
3194 expected[0] = 0x00000000, expected[1] = 0x00000000;
3195 expected[2] = 0x00000000, expected[3] = 0x00000000;
3196 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3197 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
3199 expected[0] = 0x00000000, expected[1] = 0x00000000;
3200 expected[2] = 0x00000000, expected[3] = 0x00000000;
3201 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3202 1, 1, -2, -2, 1, 1, -2, -2, expected, expected, __LINE__);
3204 expected[0] = 0x00000000, expected[1] = 0x00000000;
3205 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
3206 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3207 1, 1, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
3209 SelectObject(hdcDst, oldDst);
3210 DeleteObject(bmpDst);
3212 /* Bottom up destination tests */
3213 biDst.bmiHeader.biHeight = 2;
3214 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3216 oldDst = SelectObject(hdcDst, bmpDst);
3218 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3219 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
3220 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3221 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
3224 SelectObject(hdcDst, oldDst);
3225 DeleteObject(bmpDst);
3228 DeleteDC(hdcScreen);
3231 static void test_GdiAlphaBlend(void)
3233 /* test out-of-bound parameters for GdiAlphaBlend */
3246 BLENDFUNCTION blend;
3248 if (!pGdiAlphaBlend)
3250 win_skip("GdiAlphaBlend() is not implemented\n");
3254 hdcNull = GetDC(NULL);
3255 hdcDst = CreateCompatibleDC(hdcNull);
3256 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
3257 hdcSrc = CreateCompatibleDC(hdcNull);
3259 memset(&bmi, 0, sizeof(bmi)); /* as of Wine 0.9.44 we require the src to be a DIB section */
3260 bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
3261 bmi.bmiHeader.biHeight = 20;
3262 bmi.bmiHeader.biWidth = 20;
3263 bmi.bmiHeader.biBitCount = 32;
3264 bmi.bmiHeader.biPlanes = 1;
3265 bmi.bmiHeader.biCompression = BI_RGB;
3266 bmpSrc = CreateDIBSection(hdcDst, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3267 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3269 oldDst = SelectObject(hdcDst, bmpDst);
3270 oldSrc = SelectObject(hdcSrc, bmpSrc);
3272 blend.BlendOp = AC_SRC_OVER;
3273 blend.BlendFlags = 0;
3274 blend.SourceConstantAlpha = 128;
3275 blend.AlphaFormat = 0;
3277 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend), TRUE, BOOL, "%d");
3278 SetLastError(0xdeadbeef);
3279 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), FALSE, BOOL, "%d");
3280 expect_eq(GetLastError(), ERROR_INVALID_PARAMETER, int, "%d");
3281 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), FALSE, BOOL, "%d");
3282 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend), FALSE, BOOL, "%d");
3283 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
3284 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
3286 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
3287 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), TRUE, BOOL, "%d");
3288 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), TRUE, BOOL, "%d");
3289 SetMapMode(hdcSrc, MM_ANISOTROPIC);
3290 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
3291 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend), TRUE, BOOL, "%d");
3292 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend), TRUE, BOOL, "%d");
3294 SetLastError(0xdeadbeef);
3295 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend), FALSE, BOOL, "%d");
3296 expect_eq(GetLastError(), 0xdeadbeef, int, "%d");
3298 SelectObject(hdcDst, oldDst);
3299 SelectObject(hdcSrc, oldSrc);
3300 DeleteObject(bmpSrc);
3301 DeleteObject(bmpDst);
3305 ReleaseDC(NULL, hdcNull);
3309 static void test_clipping(void)
3317 HDC hdcDst = CreateCompatibleDC( NULL );
3318 HDC hdcSrc = CreateCompatibleDC( NULL );
3320 BITMAPINFO bmpinfo={{0}};
3321 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3322 bmpinfo.bmiHeader.biWidth = 100;
3323 bmpinfo.bmiHeader.biHeight = 100;
3324 bmpinfo.bmiHeader.biPlanes = 1;
3325 bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3326 bmpinfo.bmiHeader.biCompression = BI_RGB;
3328 bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3329 ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3330 SelectObject( hdcDst, bmpDst );
3332 bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3333 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3334 SelectObject( hdcSrc, bmpSrc );
3336 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3337 ok(result, "BitBlt failed\n");
3339 hRgn = CreateRectRgn( 0,0,0,0 );
3340 SelectClipRgn( hdcDst, hRgn );
3342 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3343 ok(result, "BitBlt failed\n");
3345 DeleteObject( bmpDst );
3346 DeleteObject( bmpSrc );
3347 DeleteObject( hRgn );
3352 static void test_32bit_bitmap_blt(void)
3355 HBITMAP bmpSrc, bmpDst;
3356 HBITMAP oldSrc, oldDst;
3357 HDC hdcSrc, hdcDst, hdcScreen;
3359 DWORD colorSrc = 0x11223344;
3361 memset(&biDst, 0, sizeof(BITMAPINFO));
3362 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3363 biDst.bmiHeader.biWidth = 2;
3364 biDst.bmiHeader.biHeight = -2;
3365 biDst.bmiHeader.biPlanes = 1;
3366 biDst.bmiHeader.biBitCount = 32;
3367 biDst.bmiHeader.biCompression = BI_RGB;
3369 hdcScreen = CreateCompatibleDC(0);
3370 if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3372 DeleteDC(hdcScreen);
3373 trace("Skipping 32-bit DDB test\n");
3377 hdcSrc = CreateCompatibleDC(hdcScreen);
3378 bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3379 oldSrc = SelectObject(hdcSrc, bmpSrc);
3381 hdcDst = CreateCompatibleDC(hdcScreen);
3382 bmpDst = CreateDIBSection(hdcDst, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3383 oldDst = SelectObject(hdcDst, bmpDst);
3385 StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3386 ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3389 SelectObject(hdcDst, oldDst);
3390 DeleteObject(bmpDst);
3393 SelectObject(hdcSrc, oldSrc);
3394 DeleteObject(bmpSrc);
3397 DeleteDC(hdcScreen);
3401 * Used by test_GetDIBits_top_down to create the bitmap to test against.
3403 static void setup_picture(char *picture, int bpp)
3411 /*Set the first byte in each pixel to the index of that pixel.*/
3412 for (i = 0; i < 4; i++)
3413 picture[i * (bpp / 8)] = i;
3418 /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
3425 static void test_GetDIBits_top_down(int bpp)
3428 HBITMAP bmptb, bmpbt;
3434 memset( &bi, 0, sizeof(bi) );
3435 bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
3436 bi.bmiHeader.biWidth=2;
3437 bi.bmiHeader.biHeight=2;
3438 bi.bmiHeader.biPlanes=1;
3439 bi.bmiHeader.biBitCount=bpp;
3440 bi.bmiHeader.biCompression=BI_RGB;
3442 /*Get the device context for the screen.*/
3444 ok(hdc != NULL, "Could not get a handle to a device context.\n");
3446 /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
3447 bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3448 ok(bmpbt != NULL, "Could not create a DIB section.\n");
3449 /*Now that we have a pointer to the pixels, we write to them.*/
3450 setup_picture((char*)picture, bpp);
3451 /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
3452 bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
3453 bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3454 ok(bmptb != NULL, "Could not create a DIB section.\n");
3455 /*Write to this top to bottom bitmap.*/
3456 setup_picture((char*)picture, bpp);
3458 bi.bmiHeader.biWidth = 1;
3460 bi.bmiHeader.biHeight = 2;
3461 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3462 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3463 /*Check the first byte of the pixel.*/
3464 ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3465 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3466 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3467 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3468 /*Check second scanline.*/
3469 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3470 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3471 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3472 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3473 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3474 ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3475 /*Check both scanlines.*/
3476 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3477 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3478 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3479 ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3480 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3481 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3482 ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3483 ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3485 /*Make destination bitmap top-down.*/
3486 bi.bmiHeader.biHeight = -2;
3487 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3488 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3489 ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3490 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3491 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3492 ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3493 /*Check second scanline.*/
3494 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3495 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3496 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3497 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3498 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3499 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3500 /*Check both scanlines.*/
3501 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3502 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3503 ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3504 ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3505 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3506 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3507 ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3508 ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3510 DeleteObject(bmpbt);
3511 DeleteObject(bmptb);
3514 static void test_GetSetDIBits_rtl(void)
3517 HBITMAP bitmap, orig_bitmap;
3520 DWORD bits_1[8 * 8], bits_2[8 * 8];
3524 win_skip("Don't have SetLayout\n");
3528 hdc = GetDC( NULL );
3529 hdc_mem = CreateCompatibleDC( hdc );
3530 pSetLayout( hdc_mem, LAYOUT_LTR );
3532 bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
3533 orig_bitmap = SelectObject( hdc_mem, bitmap );
3534 SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
3535 SelectObject( hdc_mem, orig_bitmap );
3537 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3538 info.bmiHeader.biWidth = 8;
3539 info.bmiHeader.biHeight = 8;
3540 info.bmiHeader.biPlanes = 1;
3541 info.bmiHeader.biBitCount = 32;
3542 info.bmiHeader.biCompression = BI_RGB;
3544 /* First show that GetDIBits ignores the layout mode. */
3546 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3547 ok(ret == 8, "got %d\n", ret);
3548 ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
3550 pSetLayout( hdc_mem, LAYOUT_RTL );
3552 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3553 ok(ret == 8, "got %d\n", ret);
3555 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3557 /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
3558 followed by a GetDIBits and show that the bits remain unchanged. */
3560 pSetLayout( hdc_mem, LAYOUT_LTR );
3562 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3563 ok(ret == 8, "got %d\n", ret);
3564 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3565 ok(ret == 8, "got %d\n", ret);
3566 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3568 pSetLayout( hdc_mem, LAYOUT_RTL );
3570 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3571 ok(ret == 8, "got %d\n", ret);
3572 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3573 ok(ret == 8, "got %d\n", ret);
3574 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3576 DeleteObject( bitmap );
3577 DeleteDC( hdc_mem );
3578 ReleaseDC( NULL, hdc );
3581 static void test_GetDIBits_scanlines(void)
3583 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3584 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3586 HDC hdc = GetDC( NULL );
3588 DWORD data[128], inverted_bits[64];
3591 memset( info, 0, sizeof(bmi_buf) );
3593 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3594 info->bmiHeader.biWidth = 8;
3595 info->bmiHeader.biHeight = 8;
3596 info->bmiHeader.biPlanes = 1;
3597 info->bmiHeader.biBitCount = 32;
3598 info->bmiHeader.biCompression = BI_RGB;
3600 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3602 for (i = 0; i < 64; i++)
3605 inverted_bits[56 - (i & ~7) + (i & 7)] = i;
3610 memset( data, 0xaa, sizeof(data) );
3612 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3613 ok( ret == 8, "got %d\n", ret );
3614 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3615 memset( data, 0xaa, sizeof(data) );
3617 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3618 ok( ret == 5, "got %d\n", ret );
3619 ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
3620 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3621 memset( data, 0xaa, sizeof(data) );
3623 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3624 ok( ret == 7, "got %d\n", ret );
3625 ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
3626 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3627 memset( data, 0xaa, sizeof(data) );
3629 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3630 ok( ret == 1, "got %d\n", ret );
3631 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3632 memset( data, 0xaa, sizeof(data) );
3634 info->bmiHeader.biHeight = 16;
3635 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3636 ok( ret == 5, "got %d\n", ret );
3637 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3638 ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
3639 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3640 memset( data, 0xaa, sizeof(data) );
3642 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3643 ok( ret == 6, "got %d\n", ret );
3644 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3645 ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
3646 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3647 memset( data, 0xaa, sizeof(data) );
3649 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3650 ok( ret == 0, "got %d\n", ret );
3651 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3652 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3653 memset( data, 0xaa, sizeof(data) );
3655 info->bmiHeader.biHeight = 5;
3656 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3657 ok( ret == 2, "got %d\n", ret );
3658 ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
3659 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3660 memset( data, 0xaa, sizeof(data) );
3664 info->bmiHeader.biHeight = -8;
3665 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3666 ok( ret == 8, "got %d\n", ret );
3667 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3668 memset( data, 0xaa, sizeof(data) );
3670 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3671 ok( ret == 5, "got %d\n", ret );
3672 ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
3673 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3674 memset( data, 0xaa, sizeof(data) );
3676 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3677 ok( ret == 7, "got %d\n", ret );
3678 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3679 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3680 memset( data, 0xaa, sizeof(data) );
3682 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3683 ok( ret == 4, "got %d\n", ret );
3684 ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
3685 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3686 memset( data, 0xaa, sizeof(data) );
3688 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3689 ok( ret == 5, "got %d\n", ret );
3690 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3691 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3692 memset( data, 0xaa, sizeof(data) );
3694 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3695 ok( ret == 5, "got %d\n", ret );
3696 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3697 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3698 memset( data, 0xaa, sizeof(data) );
3700 info->bmiHeader.biHeight = -16;
3701 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3702 ok( ret == 8, "got %d\n", ret );
3703 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3704 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3705 memset( data, 0xaa, sizeof(data) );
3707 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3708 ok( ret == 5, "got %d\n", ret );
3709 ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
3710 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3711 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3712 memset( data, 0xaa, sizeof(data) );
3714 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3715 ok( ret == 8, "got %d\n", ret );
3716 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3717 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3718 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3719 memset( data, 0xaa, sizeof(data) );
3721 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3722 ok( ret == 8, "got %d\n", ret );
3723 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3724 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3725 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3726 memset( data, 0xaa, sizeof(data) );
3728 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3729 ok( ret == 7, "got %d\n", ret );
3730 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3731 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3732 memset( data, 0xaa, sizeof(data) );
3734 ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
3735 ok( ret == 1, "got %d\n", ret );
3736 for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3737 memset( data, 0xaa, sizeof(data) );
3739 info->bmiHeader.biHeight = -5;
3740 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3741 ok( ret == 2, "got %d\n", ret );
3742 ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
3743 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3744 memset( data, 0xaa, sizeof(data) );
3746 DeleteObject( dib );
3748 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3749 info->bmiHeader.biWidth = 8;
3750 info->bmiHeader.biHeight = -8;
3751 info->bmiHeader.biPlanes = 1;
3752 info->bmiHeader.biBitCount = 32;
3753 info->bmiHeader.biCompression = BI_RGB;
3755 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3757 for (i = 0; i < 64; i++) dib_bits[i] = i;
3761 info->bmiHeader.biHeight = -8;
3762 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3763 ok( ret == 8, "got %d\n", ret );
3764 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3765 memset( data, 0xaa, sizeof(data) );
3767 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3768 ok( ret == 5, "got %d\n", ret );
3769 ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
3770 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3771 memset( data, 0xaa, sizeof(data) );
3773 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3774 ok( ret == 7, "got %d\n", ret );
3775 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3776 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3777 memset( data, 0xaa, sizeof(data) );
3779 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3780 ok( ret == 4, "got %d\n", ret );
3781 ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
3782 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3783 memset( data, 0xaa, sizeof(data) );
3785 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3786 ok( ret == 5, "got %d\n", ret );
3787 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3788 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3789 memset( data, 0xaa, sizeof(data) );
3791 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3792 ok( ret == 5, "got %d\n", ret );
3793 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3794 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3795 memset( data, 0xaa, sizeof(data) );
3797 info->bmiHeader.biHeight = -16;
3798 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3799 ok( ret == 8, "got %d\n", ret );
3800 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3801 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3802 memset( data, 0xaa, sizeof(data) );
3804 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3805 ok( ret == 5, "got %d\n", ret );
3806 ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
3807 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3808 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3809 memset( data, 0xaa, sizeof(data) );
3811 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3812 ok( ret == 8, "got %d\n", ret );
3813 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3814 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3815 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3816 memset( data, 0xaa, sizeof(data) );
3818 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3819 ok( ret == 8, "got %d\n", ret );
3820 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3821 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3822 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3823 memset( data, 0xaa, sizeof(data) );
3825 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3826 ok( ret == 7, "got %d\n", ret );
3827 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3828 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3829 memset( data, 0xaa, sizeof(data) );
3831 info->bmiHeader.biHeight = -5;
3832 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3833 ok( ret == 2, "got %d\n", ret );
3834 ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
3835 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3836 memset( data, 0xaa, sizeof(data) );
3841 info->bmiHeader.biHeight = 8;
3843 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3844 ok( ret == 8, "got %d\n", ret );
3845 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3846 memset( data, 0xaa, sizeof(data) );
3848 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3849 ok( ret == 5, "got %d\n", ret );
3850 ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
3851 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3852 memset( data, 0xaa, sizeof(data) );
3854 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3855 ok( ret == 7, "got %d\n", ret );
3856 ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
3857 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3858 memset( data, 0xaa, sizeof(data) );
3860 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3861 ok( ret == 1, "got %d\n", ret );
3862 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3863 memset( data, 0xaa, sizeof(data) );
3865 info->bmiHeader.biHeight = 16;
3866 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3867 ok( ret == 5, "got %d\n", ret );
3868 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3869 ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
3870 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3871 memset( data, 0xaa, sizeof(data) );
3873 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3874 ok( ret == 6, "got %d\n", ret );
3875 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3876 ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
3877 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3878 memset( data, 0xaa, sizeof(data) );
3880 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3881 ok( ret == 0, "got %d\n", ret );
3882 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3883 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3884 memset( data, 0xaa, sizeof(data) );
3886 info->bmiHeader.biHeight = 5;
3887 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3888 ok( ret == 2, "got %d\n", ret );
3889 ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
3890 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3891 memset( data, 0xaa, sizeof(data) );
3893 DeleteObject( dib );
3895 ReleaseDC( NULL, hdc );
3899 static void test_SetDIBits(void)
3901 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3902 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3904 HDC hdc = GetDC( NULL );
3905 DWORD data[128], inverted_data[128];
3909 memset( info, 0, sizeof(bmi_buf) );
3911 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3912 info->bmiHeader.biWidth = 8;
3913 info->bmiHeader.biHeight = 8;
3914 info->bmiHeader.biPlanes = 1;
3915 info->bmiHeader.biBitCount = 32;
3916 info->bmiHeader.biCompression = BI_RGB;
3918 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3919 memset( dib_bits, 0xaa, 64 * 4 );
3921 for (i = 0; i < 128; i++)
3924 inverted_data[120 - (i & ~7) + (i & 7)] = i;
3929 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3930 ok( ret == 8, "got %d\n", ret );
3931 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
3932 memset( dib_bits, 0xaa, 64 * 4 );
3934 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3935 ok( ret == 5, "got %d\n", ret );
3936 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3937 ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
3938 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3939 memset( dib_bits, 0xaa, 64 * 4 );
3941 /* top of dst is aligned with startscans down for the top of the src.
3942 Then starting from the bottom of src, lines rows are copied across. */
3944 info->bmiHeader.biHeight = 16;
3945 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3946 ok( ret == 12, "got %d\n", ret );
3947 ok( !memcmp( dib_bits, data + 56, 40 * 4 ), "bits differ\n");
3948 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3949 memset( dib_bits, 0xaa, 64 * 4 );
3951 info->bmiHeader.biHeight = 5;
3952 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3953 ok( ret == 2, "got %d\n", ret );
3954 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3955 ok( !memcmp( dib_bits + 32, data, 16 * 4 ), "bits differ\n");
3956 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3957 memset( dib_bits, 0xaa, 64 * 4 );
3960 info->bmiHeader.biHeight = -8;
3961 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3962 ok( ret == 8, "got %d\n", ret );
3963 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3964 memset( dib_bits, 0xaa, 64 * 4 );
3966 /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
3967 we copy lines rows from the top of the src */
3969 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3970 ok( ret == 5, "got %d\n", ret );
3971 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3972 ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
3973 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3974 memset( dib_bits, 0xaa, 64 * 4 );
3976 info->bmiHeader.biHeight = -16;
3977 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3978 ok( ret == 12, "got %d\n", ret );
3979 ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
3980 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3981 memset( dib_bits, 0xaa, 64 * 4 );
3983 ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3984 ok( ret == 12, "got %d\n", ret );
3985 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3986 memset( dib_bits, 0xaa, 64 * 4 );
3988 ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3989 ok( ret == 12, "got %d\n", ret );
3990 ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
3991 memset( dib_bits, 0xaa, 64 * 4 );
3993 info->bmiHeader.biHeight = -5;
3994 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3995 ok( ret == 2, "got %d\n", ret );
3996 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3997 ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
3998 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3999 memset( dib_bits, 0xaa, 64 * 4 );
4001 DeleteObject( dib );
4003 info->bmiHeader.biHeight = -8;
4005 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4006 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4010 /* like the t-d -> b-u case. */
4012 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4013 ok( ret == 8, "got %d\n", ret );
4014 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4015 memset( dib_bits, 0xaa, 64 * 4 );
4017 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4018 ok( ret == 5, "got %d\n", ret );
4019 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4020 ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
4021 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4022 memset( dib_bits, 0xaa, 64 * 4 );
4024 info->bmiHeader.biHeight = -16;
4025 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4026 ok( ret == 12, "got %d\n", ret );
4027 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4028 ok( !memcmp( dib_bits + 24, data, 40 * 4 ), "bits differ\n");
4029 memset( dib_bits, 0xaa, 64 * 4 );
4031 info->bmiHeader.biHeight = -5;
4032 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4033 ok( ret == 2, "got %d\n", ret );
4034 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4035 ok( !memcmp( dib_bits + 16, data, 16 * 4 ), "bits differ\n");
4036 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4037 memset( dib_bits, 0xaa, 64 * 4 );
4040 /* like the b-u -> b-u case */
4042 info->bmiHeader.biHeight = 8;
4043 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4044 ok( ret == 8, "got %d\n", ret );
4045 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4046 memset( dib_bits, 0xaa, 64 * 4 );
4048 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4049 ok( ret == 5, "got %d\n", ret );
4050 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4051 ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
4052 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4053 memset( dib_bits, 0xaa, 64 * 4 );
4055 info->bmiHeader.biHeight = 16;
4056 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4057 ok( ret == 12, "got %d\n", ret );
4058 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4059 ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
4060 memset( dib_bits, 0xaa, 64 * 4 );
4062 info->bmiHeader.biHeight = 5;
4063 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4064 ok( ret == 2, "got %d\n", ret );
4065 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4066 ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
4067 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4068 memset( dib_bits, 0xaa, 64 * 4 );
4070 DeleteObject( dib );
4071 ReleaseDC( NULL, hdc );
4074 static void test_SetDIBits_RLE4(void)
4076 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
4077 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
4079 HDC hdc = GetDC( NULL );
4080 BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00, /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
4081 0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
4082 0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00, /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
4083 0x00, 0x02, 0x01, 0x02, 0x05, 0x87, /* dx=1, dy=2, 8, 7, 8, 7, 8 */
4084 0x00, 0x01 }; /* <eod> */
4087 DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
4088 0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
4089 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4090 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4091 0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
4092 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4093 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4094 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4096 memset( info, 0, sizeof(bmi_buf) );
4098 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4099 info->bmiHeader.biWidth = 8;
4100 info->bmiHeader.biHeight = 8;
4101 info->bmiHeader.biPlanes = 1;
4102 info->bmiHeader.biBitCount = 32;
4103 info->bmiHeader.biCompression = BI_RGB;
4105 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4106 memset( dib_bits, 0xaa, 64 * 4 );
4108 info->bmiHeader.biBitCount = 4;
4109 info->bmiHeader.biCompression = BI_RLE4;
4110 info->bmiHeader.biSizeImage = sizeof(rle4_data);
4112 for (i = 0; i < 16; i++)
4114 info->bmiColors[i].rgbRed = i;
4115 info->bmiColors[i].rgbGreen = i;
4116 info->bmiColors[i].rgbBlue = i;
4117 info->bmiColors[i].rgbReserved = 0;
4120 ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
4121 ok( ret == 8, "got %d\n", ret );
4122 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
4123 memset( dib_bits, 0xaa, 64 * 4 );
4125 DeleteObject( dib );
4126 ReleaseDC( NULL, hdc );
4129 static void test_SetDIBits_RLE8(void)
4131 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
4132 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
4134 HDC hdc = GetDC( NULL );
4135 BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00, /* 2, 2, 2, f0, f0, f0, f0, <eol> */
4136 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4137 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4138 0x00, 0x01 }; /* <eod> */
4141 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4142 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4143 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4144 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4145 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
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 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4150 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4151 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4152 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4153 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4154 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4155 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4156 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4158 memset( info, 0, sizeof(bmi_buf) );
4160 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4161 info->bmiHeader.biWidth = 8;
4162 info->bmiHeader.biHeight = 8;
4163 info->bmiHeader.biPlanes = 1;
4164 info->bmiHeader.biBitCount = 32;
4165 info->bmiHeader.biCompression = BI_RGB;
4167 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4168 memset( dib_bits, 0xaa, 64 * 4 );
4170 info->bmiHeader.biBitCount = 8;
4171 info->bmiHeader.biCompression = BI_RLE8;
4172 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4174 for (i = 0; i < 256; i++)
4176 info->bmiColors[i].rgbRed = i;
4177 info->bmiColors[i].rgbGreen = i;
4178 info->bmiColors[i].rgbBlue = i;
4179 info->bmiColors[i].rgbReserved = 0;
4182 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4183 ok( ret == 8, "got %d\n", ret );
4184 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4185 memset( dib_bits, 0xaa, 64 * 4 );
4187 /* startscan and lines are ignored, unless lines == 0 */
4188 ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4189 ok( ret == 8, "got %d\n", ret );
4190 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4191 memset( dib_bits, 0xaa, 64 * 4 );
4193 ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4194 ok( ret == 8, "got %d\n", ret );
4195 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4196 memset( dib_bits, 0xaa, 64 * 4 );
4198 ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4199 ok( ret == 0, "got %d\n", ret );
4200 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4201 memset( dib_bits, 0xaa, 64 * 4 );
4203 /* reduce width to 4, left-hand side of dst is touched. */
4204 info->bmiHeader.biWidth = 4;
4205 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4206 ok( ret == 8, "got %d\n", ret );
4207 for (i = 0; i < 64; i++)
4209 DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4210 ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4212 memset( dib_bits, 0xaa, 64 * 4 );
4214 /* Show that the top lines are aligned by adjusting the height of the src */
4216 /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4217 info->bmiHeader.biWidth = 8;
4218 info->bmiHeader.biHeight = 4;
4219 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4220 ok( ret == 4, "got %d\n", ret );
4221 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4222 ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4223 memset( dib_bits, 0xaa, 64 * 4 );
4225 /* increase the height to 9 -> everything moves down one row. */
4226 info->bmiHeader.biHeight = 9;
4227 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4228 ok( ret == 9, "got %d\n", ret );
4229 ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4230 for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4231 memset( dib_bits, 0xaa, 64 * 4 );
4233 /* top-down compressed dibs are invalid */
4234 info->bmiHeader.biHeight = -8;
4235 SetLastError( 0xdeadbeef );
4236 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4237 ok( ret == 0, "got %d\n", ret );
4238 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4239 DeleteObject( dib );
4243 info->bmiHeader.biHeight = -8;
4244 info->bmiHeader.biBitCount = 32;
4245 info->bmiHeader.biCompression = BI_RGB;
4246 info->bmiHeader.biSizeImage = 0;
4248 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4249 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4251 info->bmiHeader.biHeight = 8;
4252 info->bmiHeader.biBitCount = 8;
4253 info->bmiHeader.biCompression = BI_RLE8;
4254 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4256 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4257 ok( ret == 8, "got %d\n", ret );
4258 ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4259 memset( dib_bits, 0xaa, 64 * 4 );
4261 info->bmiHeader.biHeight = 4;
4262 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4263 ok( ret == 4, "got %d\n", ret );
4264 ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4265 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4266 memset( dib_bits, 0xaa, 64 * 4 );
4268 info->bmiHeader.biHeight = 9;
4269 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4270 ok( ret == 9, "got %d\n", ret );
4271 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4272 ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4273 memset( dib_bits, 0xaa, 64 * 4 );
4275 DeleteObject( dib );
4277 ReleaseDC( NULL, hdc );
4280 static void test_SetDIBitsToDevice(void)
4282 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
4283 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
4285 HDC hdc = CreateCompatibleDC( 0 );
4286 DWORD data[128], inverted_data[128];
4290 memset( info, 0, sizeof(bmi_buf) );
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 );
4645 static void test_SetDIBitsToDevice_RLE8(void)
4647 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
4648 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
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 memset( info, 0, sizeof(bmi_buf) );
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 );
4870 hdll = GetModuleHandle("gdi32.dll");
4871 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
4872 pSetLayout = (void*)GetProcAddress(hdll, "SetLayout");
4874 test_createdibitmap();
4877 test_mono_dibsection();
4880 test_GetDIBits_selected_DIB(1);
4881 test_GetDIBits_selected_DIB(4);
4882 test_GetDIBits_selected_DIB(8);
4883 test_GetDIBits_selected_DDB(TRUE);
4884 test_GetDIBits_selected_DDB(FALSE);
4886 test_GetDIBits_BI_BITFIELDS();
4887 test_select_object();
4888 test_CreateBitmap();
4891 test_StretchDIBits();
4892 test_GdiAlphaBlend();
4893 test_32bit_bitmap_blt();
4894 test_bitmapinfoheadersize();
4897 test_GetDIBits_top_down(16);
4898 test_GetDIBits_top_down(24);
4899 test_GetDIBits_top_down(32);
4900 test_GetSetDIBits_rtl();
4901 test_GetDIBits_scanlines();
4903 test_SetDIBits_RLE4();
4904 test_SetDIBits_RLE8();
4905 test_SetDIBitsToDevice();
4906 test_SetDIBitsToDevice_RLE8();