2 * Unit test suite for bitmaps
4 * Copyright 2004 Huw Davies
5 * Copyright 2006 Dmitry Timoshkov
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
33 #include "wine/test.h"
35 static BOOL (WINAPI *pGdiAlphaBlend)(HDC,int,int,int,int,HDC,int,int,int,int,BLENDFUNCTION);
36 static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
38 static inline int get_bitmap_stride( int width, int bpp )
40 return ((width * bpp + 15) >> 3) & ~1;
43 static inline int get_dib_stride( int width, int bpp )
45 return ((width * bpp + 31) >> 3) & ~3;
48 static inline int get_dib_image_size( const BITMAPINFO *info )
50 return get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount )
51 * abs( info->bmiHeader.biHeight );
54 static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHEADER *bmih)
59 BYTE buf[512], buf_cmp[512];
61 ret = GetObject(hbm, sizeof(bm), &bm);
62 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
64 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
65 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
66 ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
67 width_bytes = get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel);
68 ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
69 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
70 ok(bm.bmBitsPixel == expected_depth, "wrong bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, expected_depth);
71 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
73 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
74 assert(sizeof(buf) == sizeof(buf_cmp));
76 SetLastError(0xdeadbeef);
77 ret = GetBitmapBits(hbm, 0, NULL);
78 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
80 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
81 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
83 memset(buf, 0xAA, sizeof(buf));
84 ret = GetBitmapBits(hbm, sizeof(buf), buf);
85 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
86 ok(!memcmp(buf, buf_cmp, sizeof(buf)),
87 "buffers do not match, depth %d\n", bmih->biBitCount);
89 /* test various buffer sizes for GetObject */
90 ret = GetObject(hbm, sizeof(*bma) * 2, bma);
91 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
93 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
94 ok(ret == 0, "%d != 0\n", ret);
96 ret = GetObject(hbm, 0, &bm);
97 ok(ret == 0, "%d != 0\n", ret);
99 ret = GetObject(hbm, 1, &bm);
100 ok(ret == 0, "%d != 0\n", ret);
102 ret = GetObject(hbm, 0, NULL);
103 ok(ret == sizeof(bm), "wrong size %d\n", ret);
106 static void test_createdibitmap(void)
109 BITMAPINFOHEADER bmih;
111 HBITMAP hbm, hbm_colour, hbm_old;
116 screen_depth = GetDeviceCaps(hdc, BITSPIXEL);
117 memset(&bmih, 0, sizeof(bmih));
118 bmih.biSize = sizeof(bmih);
122 bmih.biBitCount = 32;
123 bmih.biCompression = BI_RGB;
125 hbm = CreateDIBitmap(hdc, NULL, CBM_INIT, NULL, NULL, 0);
126 ok(hbm == NULL, "CreateDIBitmap should fail\n");
127 hbm = CreateDIBitmap(hdc, NULL, 0, NULL, NULL, 0);
128 ok(hbm == NULL, "CreateDIBitmap should fail\n");
130 /* First create an un-initialised bitmap. The depth of the bitmap
131 should match that of the hdc and not that supplied in bmih.
134 /* First try 32 bits */
135 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
136 ok(hbm != NULL, "CreateDIBitmap failed\n");
137 test_bitmap_info(hbm, screen_depth, &bmih);
141 bmih.biBitCount = 16;
142 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
143 ok(hbm != NULL, "CreateDIBitmap failed\n");
144 test_bitmap_info(hbm, screen_depth, &bmih);
149 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
150 ok(hbm != NULL, "CreateDIBitmap failed\n");
151 test_bitmap_info(hbm, screen_depth, &bmih);
154 /* Now with a monochrome dc we expect a monochrome bitmap */
155 hdcmem = CreateCompatibleDC(hdc);
157 /* First try 32 bits */
158 bmih.biBitCount = 32;
159 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
160 ok(hbm != NULL, "CreateDIBitmap failed\n");
161 test_bitmap_info(hbm, 1, &bmih);
165 bmih.biBitCount = 16;
166 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
167 ok(hbm != NULL, "CreateDIBitmap failed\n");
168 test_bitmap_info(hbm, 1, &bmih);
173 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
174 ok(hbm != NULL, "CreateDIBitmap failed\n");
175 test_bitmap_info(hbm, 1, &bmih);
178 /* Now select a polychrome bitmap into the dc and we expect
179 screen_depth bitmaps again */
180 hbm_colour = CreateCompatibleBitmap(hdc, bmih.biWidth, bmih.biHeight);
181 test_bitmap_info(hbm_colour, screen_depth, &bmih);
182 hbm_old = SelectObject(hdcmem, hbm_colour);
184 /* First try 32 bits */
185 bmih.biBitCount = 32;
186 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
187 ok(hbm != NULL, "CreateDIBitmap failed\n");
188 test_bitmap_info(hbm, screen_depth, &bmih);
192 bmih.biBitCount = 16;
193 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
194 ok(hbm != NULL, "CreateDIBitmap failed\n");
195 test_bitmap_info(hbm, screen_depth, &bmih);
200 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
201 ok(hbm != NULL, "CreateDIBitmap failed\n");
202 test_bitmap_info(hbm, screen_depth, &bmih);
205 SelectObject(hdcmem, hbm_old);
206 DeleteObject(hbm_colour);
209 bmih.biBitCount = 32;
210 hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0);
211 ok(hbm != NULL, "CreateDIBitmap failed\n");
212 test_bitmap_info(hbm, 1, &bmih);
215 /* Test how formats are converted */
221 memset(&bm, 0, sizeof(bm));
222 bm.bmiHeader.biSize = sizeof(bm.bmiHeader);
223 bm.bmiHeader.biWidth = 1;
224 bm.bmiHeader.biHeight = 1;
225 bm.bmiHeader.biPlanes = 1;
226 bm.bmiHeader.biBitCount= 24;
227 bm.bmiHeader.biCompression= BI_RGB;
228 bm.bmiHeader.biSizeImage = 0;
229 hbm = CreateDIBitmap(hdc, &bmih, CBM_INIT, &pixel, &bm, DIB_RGB_COLORS);
230 ok(hbm != NULL, "CreateDIBitmap failed\n");
233 bm.bmiHeader.biBitCount= 32;
234 GetDIBits(hdc, hbm, 0, 1, &pixel, &bm, DIB_RGB_COLORS);
235 ok(pixel == 0x00ffffff, "Reading a 32 bit pixel from a DDB returned %08x\n", pixel);
241 static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
247 INT ret, bm_width_bytes, dib_width_bytes;
250 ret = GetObject(hbm, sizeof(bm), &bm);
251 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
253 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
254 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
255 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
256 dib_width_bytes = get_dib_stride(bm.bmWidth, bm.bmBitsPixel);
257 bm_width_bytes = get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel);
258 if (bm.bmWidthBytes != dib_width_bytes) /* Win2k bug */
259 ok(bm.bmWidthBytes == bm_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, bm_width_bytes);
261 ok(bm.bmWidthBytes == dib_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, dib_width_bytes);
262 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
263 ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount);
264 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
266 buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);
268 /* GetBitmapBits returns not 32-bit aligned data */
269 SetLastError(0xdeadbeef);
270 ret = GetBitmapBits(hbm, 0, NULL);
271 ok(ret == bm_width_bytes * bm.bmHeight,
272 "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
274 memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
275 ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
276 ok(ret == bm_width_bytes * bm.bmHeight, "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
278 HeapFree(GetProcessHeap(), 0, buf);
280 /* test various buffer sizes for GetObject */
281 memset(&ds, 0xAA, sizeof(ds));
282 ret = GetObject(hbm, sizeof(*bma) * 2, bma);
283 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
284 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
285 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
286 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
288 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
289 ok(ret == 0, "%d != 0\n", ret);
291 ret = GetObject(hbm, 0, &bm);
292 ok(ret == 0, "%d != 0\n", ret);
294 ret = GetObject(hbm, 1, &bm);
295 ok(ret == 0, "%d != 0\n", ret);
297 /* test various buffer sizes for GetObject */
298 ret = GetObject(hbm, 0, NULL);
299 ok(ret == sizeof(bm), "wrong size %d\n", ret);
301 ret = GetObject(hbm, sizeof(*dsa) * 2, dsa);
302 ok(ret == sizeof(*dsa), "wrong size %d\n", ret);
304 memset(&ds, 0xAA, sizeof(ds));
305 ret = GetObject(hbm, sizeof(ds), &ds);
306 ok(ret == sizeof(ds), "wrong size %d\n", ret);
308 ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
309 if (ds.dsBm.bmWidthBytes != bm_width_bytes) /* Win2k bug */
310 ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%u != %u\n",
311 ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
312 ok(bmih->biSizeImage == 0, "%u != 0\n", bmih->biSizeImage);
313 ds.dsBmih.biSizeImage = 0;
315 ok(ds.dsBmih.biSize == bmih->biSize, "%u != %u\n", ds.dsBmih.biSize, bmih->biSize);
316 ok(ds.dsBmih.biWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
317 ok(ds.dsBmih.biHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
318 ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes);
319 ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount);
320 ok(ds.dsBmih.biCompression == bmih->biCompression ||
321 ((bmih->biBitCount == 32) && broken(ds.dsBmih.biCompression == BI_BITFIELDS)), /* nt4 sp1 and 2 */
322 "%u != %u\n", ds.dsBmih.biCompression, bmih->biCompression);
323 ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%u != %u\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
324 ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%d != %d\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
325 ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%d != %d\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);
327 memset(&ds, 0xAA, sizeof(ds));
328 ret = GetObject(hbm, sizeof(ds) - 4, &ds);
329 ok(ret == sizeof(ds.dsBm), "wrong size %d\n", ret);
330 ok(ds.dsBm.bmWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
331 ok(ds.dsBm.bmHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
332 ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);
334 ret = GetObject(hbm, 0, &ds);
335 ok(ret == 0, "%d != 0\n", ret);
337 ret = GetObject(hbm, 1, &ds);
338 ok(ret == 0, "%d != 0\n", ret);
341 #define test_color_todo(got, exp, txt, todo) \
342 if (!todo && got != exp && screen_depth < 24) { \
343 todo_wine ok(0, #txt " failed at %d-bit screen depth: got 0x%06x expected 0x%06x - skipping DIB tests\n", \
344 screen_depth, (UINT)got, (UINT)exp); \
346 } else if (todo) todo_wine { ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp); } \
347 else ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp) \
349 #define test_color(hdc, color, exp, todo_setp, todo_getp) \
352 c = SetPixel(hdc, 0, 0, color); \
353 test_color_todo(c, exp, SetPixel, todo_setp); \
354 c = GetPixel(hdc, 0, 0); \
355 test_color_todo(c, exp, GetPixel, todo_getp); \
358 static void test_dib_bits_access( HBITMAP hdib, void *bits )
360 MEMORY_BASIC_INFORMATION info;
361 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
363 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
365 char filename[MAX_PATH];
370 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
371 "VirtualQuery failed\n");
372 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
373 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
374 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
375 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
376 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
377 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
379 memset( pbmi, 0, sizeof(bmibuf) );
380 memset( data, 0xcc, sizeof(data) );
381 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
382 pbmi->bmiHeader.biHeight = 16;
383 pbmi->bmiHeader.biWidth = 16;
384 pbmi->bmiHeader.biBitCount = 32;
385 pbmi->bmiHeader.biPlanes = 1;
386 pbmi->bmiHeader.biCompression = BI_RGB;
390 ret = SetDIBits( hdc, hdib, 0, 16, data, pbmi, DIB_RGB_COLORS );
391 ok(ret == 16, "SetDIBits failed: expected 16 got %d\n", ret);
395 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
396 "VirtualQuery failed\n");
397 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
398 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
399 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
400 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
401 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
402 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
404 /* try writing protected bits to a file */
406 GetTempFileNameA( ".", "dib", 0, filename );
407 file = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
408 CREATE_ALWAYS, 0, 0 );
409 ok( file != INVALID_HANDLE_VALUE, "failed to open %s error %u\n", filename, GetLastError() );
410 ret = WriteFile( file, bits, 8192, &written, NULL );
411 ok( ret, "WriteFile failed error %u\n", GetLastError() );
412 if (ret) ok( written == 8192, "only wrote %u bytes\n", written );
414 DeleteFileA( filename );
417 static void test_dibsections(void)
419 HDC hdc, hdcmem, hdcmem2;
420 HBITMAP hdib, oldbm, hdib2, oldbm2;
421 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
422 char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
423 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
424 BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
430 char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
431 LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
434 HPALETTE hpal, oldpal;
439 MEMORY_BASIC_INFORMATION info;
442 screen_depth = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
444 memset(pbmi, 0, sizeof(bmibuf));
445 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
446 pbmi->bmiHeader.biHeight = 100;
447 pbmi->bmiHeader.biWidth = 512;
448 pbmi->bmiHeader.biBitCount = 24;
449 pbmi->bmiHeader.biPlanes = 1;
450 pbmi->bmiHeader.biCompression = BI_RGB;
452 SetLastError(0xdeadbeef);
454 /* invalid pointer for BITMAPINFO
455 (*bits should be NULL on error) */
456 bits = (BYTE*)0xdeadbeef;
457 hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
458 ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n");
460 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
461 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
462 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
463 ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
465 /* test the DIB memory */
466 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
467 "VirtualQuery failed\n");
468 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
469 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
470 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
471 ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
472 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
473 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
474 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
476 test_dib_bits_access( hdib, bits );
478 test_dib_info(hdib, bits, &pbmi->bmiHeader);
481 /* Test a top-down DIB. */
482 pbmi->bmiHeader.biHeight = -100;
483 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
484 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
485 test_dib_info(hdib, bits, &pbmi->bmiHeader);
488 pbmi->bmiHeader.biHeight = 100;
489 pbmi->bmiHeader.biBitCount = 8;
490 pbmi->bmiHeader.biCompression = BI_RLE8;
491 SetLastError(0xdeadbeef);
492 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
493 ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
494 ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
496 pbmi->bmiHeader.biBitCount = 16;
497 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
498 ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
499 ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
500 ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
501 SetLastError(0xdeadbeef);
502 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
503 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
505 /* test the DIB memory */
506 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
507 "VirtualQuery failed\n");
508 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
509 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
510 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
511 ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
512 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
513 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
514 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
516 test_dib_info(hdib, bits, &pbmi->bmiHeader);
519 memset(pbmi, 0, sizeof(bmibuf));
520 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
521 pbmi->bmiHeader.biHeight = 16;
522 pbmi->bmiHeader.biWidth = 16;
523 pbmi->bmiHeader.biBitCount = 1;
524 pbmi->bmiHeader.biPlanes = 1;
525 pbmi->bmiHeader.biCompression = BI_RGB;
526 pbmi->bmiColors[0].rgbRed = 0xff;
527 pbmi->bmiColors[0].rgbGreen = 0;
528 pbmi->bmiColors[0].rgbBlue = 0;
529 pbmi->bmiColors[1].rgbRed = 0;
530 pbmi->bmiColors[1].rgbGreen = 0;
531 pbmi->bmiColors[1].rgbBlue = 0xff;
533 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
534 ok(hdib != NULL, "CreateDIBSection failed\n");
535 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
536 ok(dibsec.dsBmih.biClrUsed == 2,
537 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
539 /* Test if the old BITMAPCOREINFO structure is supported */
541 pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
542 pbci->bmciHeader.bcBitCount = 0;
544 ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
545 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
546 ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
547 && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
548 "GetDIBits didn't fill in the BITMAPCOREHEADER structure properly\n");
550 ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
551 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
552 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
553 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
554 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
555 "The color table has not been translated to the old BITMAPCOREINFO format\n");
557 hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
558 ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
560 ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
561 ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
562 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
563 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
564 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
565 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
566 "The color table has not been translated to the old BITMAPCOREINFO format\n");
568 DeleteObject(hcoredib);
570 hdcmem = CreateCompatibleDC(hdc);
571 oldbm = SelectObject(hdcmem, hdib);
573 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
574 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
575 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
576 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
577 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
578 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
580 c0 = RGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen, pbmi->bmiColors[0].rgbBlue);
581 c1 = RGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen, pbmi->bmiColors[1].rgbBlue);
583 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
584 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
585 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
586 test_color(hdcmem, PALETTEINDEX(0), c0, 1, 1);
587 test_color(hdcmem, PALETTEINDEX(1), c0, 1, 1);
588 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
589 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen,
590 pbmi->bmiColors[0].rgbBlue), c0, 1, 1);
591 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen,
592 pbmi->bmiColors[1].rgbBlue), c1, 1, 1);
593 test_color(hdcmem, PALETTERGB(0, 0, 0), c0, 1, 1);
594 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
595 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1, 1, 1);
597 SelectObject(hdcmem, oldbm);
600 pbmi->bmiColors[0].rgbRed = 0xff;
601 pbmi->bmiColors[0].rgbGreen = 0xff;
602 pbmi->bmiColors[0].rgbBlue = 0xff;
603 pbmi->bmiColors[1].rgbRed = 0;
604 pbmi->bmiColors[1].rgbGreen = 0;
605 pbmi->bmiColors[1].rgbBlue = 0;
607 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
608 ok(hdib != NULL, "CreateDIBSection failed\n");
610 test_dib_info(hdib, bits, &pbmi->bmiHeader);
612 oldbm = SelectObject(hdcmem, hdib);
614 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
615 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
616 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
617 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
618 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
619 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
621 SelectObject(hdcmem, oldbm);
622 test_dib_info(hdib, bits, &pbmi->bmiHeader);
625 pbmi->bmiHeader.biBitCount = 4;
626 for (i = 0; i < 16; i++) {
627 pbmi->bmiColors[i].rgbRed = i;
628 pbmi->bmiColors[i].rgbGreen = 16-i;
629 pbmi->bmiColors[i].rgbBlue = 0;
631 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
632 ok(hdib != NULL, "CreateDIBSection failed\n");
633 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
634 ok(dibsec.dsBmih.biClrUsed == 16,
635 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
636 test_dib_info(hdib, bits, &pbmi->bmiHeader);
639 pbmi->bmiHeader.biBitCount = 8;
641 for (i = 0; i < 128; i++) {
642 pbmi->bmiColors[i].rgbRed = 255 - i * 2;
643 pbmi->bmiColors[i].rgbGreen = i * 2;
644 pbmi->bmiColors[i].rgbBlue = 0;
645 pbmi->bmiColors[255 - i].rgbRed = 0;
646 pbmi->bmiColors[255 - i].rgbGreen = i * 2;
647 pbmi->bmiColors[255 - i].rgbBlue = 255 - i * 2;
649 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
650 ok(hdib != NULL, "CreateDIBSection failed\n");
651 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
652 ok(dibsec.dsBmih.biClrUsed == 256,
653 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
655 oldbm = SelectObject(hdcmem, hdib);
657 for (i = 0; i < 256; i++) {
658 test_color(hdcmem, DIBINDEX(i),
659 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
660 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue),
661 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
664 SelectObject(hdcmem, oldbm);
665 test_dib_info(hdib, bits, &pbmi->bmiHeader);
668 pbmi->bmiHeader.biBitCount = 1;
670 /* Now create a palette and a palette indexed dib section */
671 memset(plogpal, 0, sizeof(logpalbuf));
672 plogpal->palVersion = 0x300;
673 plogpal->palNumEntries = 2;
674 plogpal->palPalEntry[0].peRed = 0xff;
675 plogpal->palPalEntry[0].peBlue = 0xff;
676 plogpal->palPalEntry[1].peGreen = 0xff;
678 index = (WORD*)pbmi->bmiColors;
681 hpal = CreatePalette(plogpal);
682 ok(hpal != NULL, "CreatePalette failed\n");
683 oldpal = SelectPalette(hdc, hpal, TRUE);
684 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
685 ok(hdib != NULL, "CreateDIBSection failed\n");
686 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
687 ok(dibsec.dsBmih.biClrUsed == 2, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
689 /* The colour table has already been grabbed from the dc, so we select back the
692 SelectPalette(hdc, oldpal, TRUE);
693 oldbm = SelectObject(hdcmem, hdib);
694 oldpal = SelectPalette(hdcmem, hpal, TRUE);
696 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
697 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
698 ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
699 rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
700 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
701 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
702 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
704 c0 = RGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen, plogpal->palPalEntry[0].peBlue);
705 c1 = RGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen, plogpal->palPalEntry[1].peBlue);
707 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
708 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
709 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
710 test_color(hdcmem, PALETTEINDEX(0), c0, 0, 1);
711 test_color(hdcmem, PALETTEINDEX(1), c1, 0, 1);
712 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
713 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen,
714 plogpal->palPalEntry[0].peBlue), c0, 1, 1);
715 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen,
716 plogpal->palPalEntry[1].peBlue), c1, 1, 1);
717 test_color(hdcmem, PALETTERGB(0, 0, 0), c1, 1, 1);
718 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
719 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0, 1, 1);
720 test_color(hdcmem, PALETTERGB(0, 1, 0), c1, 1, 1);
721 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1, 1, 1);
722 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0, 1, 1);
724 /* Bottom and 2nd row from top green, everything else magenta */
725 bits[0] = bits[1] = 0xff;
726 bits[13 * 4] = bits[13*4 + 1] = 0xff;
728 test_dib_info(hdib, bits, &pbmi->bmiHeader);
730 pbmi->bmiHeader.biBitCount = 32;
732 hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
733 ok(hdib2 != NULL, "CreateDIBSection failed\n");
734 hdcmem2 = CreateCompatibleDC(hdc);
735 oldbm2 = SelectObject(hdcmem2, hdib2);
737 BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
739 ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
740 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
742 SelectObject(hdcmem2, oldbm2);
743 test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
746 SelectObject(hdcmem, oldbm);
747 SelectPalette(hdcmem, oldpal, TRUE);
752 pbmi->bmiHeader.biBitCount = 8;
754 memset(plogpal, 0, sizeof(logpalbuf));
755 plogpal->palVersion = 0x300;
756 plogpal->palNumEntries = 256;
758 for (i = 0; i < 128; i++) {
759 plogpal->palPalEntry[i].peRed = 255 - i * 2;
760 plogpal->palPalEntry[i].peBlue = i * 2;
761 plogpal->palPalEntry[i].peGreen = 0;
762 plogpal->palPalEntry[255 - i].peRed = 0;
763 plogpal->palPalEntry[255 - i].peGreen = i * 2;
764 plogpal->palPalEntry[255 - i].peBlue = 255 - i * 2;
767 index = (WORD*)pbmi->bmiColors;
768 for (i = 0; i < 256; i++) {
772 hpal = CreatePalette(plogpal);
773 ok(hpal != NULL, "CreatePalette failed\n");
774 oldpal = SelectPalette(hdc, hpal, TRUE);
775 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
776 ok(hdib != NULL, "CreateDIBSection failed\n");
777 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
778 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
780 test_dib_info(hdib, bits, &pbmi->bmiHeader);
782 SelectPalette(hdc, oldpal, TRUE);
783 oldbm = SelectObject(hdcmem, hdib);
784 oldpal = SelectPalette(hdcmem, hpal, TRUE);
786 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
787 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
788 for (i = 0; i < 256; i++) {
789 ok(rgb[i].rgbRed == plogpal->palPalEntry[i].peRed &&
790 rgb[i].rgbBlue == plogpal->palPalEntry[i].peBlue &&
791 rgb[i].rgbGreen == plogpal->palPalEntry[i].peGreen,
792 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
793 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
796 for (i = 0; i < 256; i++) {
797 test_color(hdcmem, DIBINDEX(i),
798 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
799 test_color(hdcmem, PALETTEINDEX(i),
800 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
801 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue),
802 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
805 SelectPalette(hdcmem, oldpal, TRUE);
806 SelectObject(hdcmem, oldbm);
815 static void test_dib_formats(void)
820 int planes, bpp, compr;
824 BOOL expect_ok, todo;
826 bi = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
828 memdc = CreateCompatibleDC( 0 );
829 hbmp = CreateCompatibleBitmap( hdc, 10, 10 );
831 memset( data, 0xaa, sizeof(data) );
833 for (bpp = 0; bpp <= 64; bpp++)
835 for (planes = 0; planes <= 64; planes++)
837 for (compr = 0; compr < 8; compr++)
844 case 24: expect_ok = (compr == BI_RGB); break;
846 case 32: expect_ok = (compr == BI_RGB || compr == BI_BITFIELDS); break;
847 default: expect_ok = FALSE; break;
849 todo = (compr == BI_BITFIELDS); /* wine doesn't like strange bitfields */
851 memset( bi, 0, sizeof(bi->bmiHeader) );
852 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
853 bi->bmiHeader.biWidth = 2;
854 bi->bmiHeader.biHeight = 2;
855 bi->bmiHeader.biPlanes = planes;
856 bi->bmiHeader.biBitCount = bpp;
857 bi->bmiHeader.biCompression = compr;
858 bi->bmiHeader.biSizeImage = 0;
859 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
860 ret = GetDIBits(hdc, hbmp, 0, 0, data, bi, DIB_RGB_COLORS);
861 if (expect_ok || (!bpp && compr != BI_JPEG && compr != BI_PNG) ||
862 (bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8))
863 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
865 ok( !ret || broken(!bpp && (compr == BI_JPEG || compr == BI_PNG)), /* nt4 */
866 "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
868 /* all functions check planes except GetDIBits with 0 lines */
869 if (!planes) expect_ok = FALSE;
870 memset( bi, 0, sizeof(bi->bmiHeader) );
871 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
872 bi->bmiHeader.biWidth = 2;
873 bi->bmiHeader.biHeight = 2;
874 bi->bmiHeader.biPlanes = planes;
875 bi->bmiHeader.biBitCount = bpp;
876 bi->bmiHeader.biCompression = compr;
877 bi->bmiHeader.biSizeImage = 0;
878 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
880 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
881 if (expect_ok && (planes == 1 || planes * bpp <= 16))
882 ok( hdib != NULL, "CreateDIBSection failed for %u/%u/%u\n", bpp, planes, compr );
884 ok( hdib == NULL, "CreateDIBSection succeeded for %u/%u/%u\n", bpp, planes, compr );
885 if (hdib) DeleteObject( hdib );
887 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, data, bi, DIB_RGB_COLORS );
888 /* no sanity checks in CreateDIBitmap except compression */
889 if (compr == BI_JPEG || compr == BI_PNG)
890 ok( hdib == NULL || broken(hdib != NULL), /* nt4 */
891 "CreateDIBitmap succeeded for %u/%u/%u\n", bpp, planes, compr );
893 ok( hdib != NULL, "CreateDIBitmap failed for %u/%u/%u\n", bpp, planes, compr );
894 if (hdib) DeleteObject( hdib );
896 /* RLE needs a size */
897 bi->bmiHeader.biSizeImage = 0;
898 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
902 todo_wine ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
904 ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
908 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
909 "SetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
910 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
914 todo_wine ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
916 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
920 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
921 "SetDIBitsToDevice succeeded for %u/%u/%u\n", bpp, planes, compr );
922 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
926 todo_wine ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
928 ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
932 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
933 "StretchDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
935 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
937 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
939 ok( !ret, "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
940 ok( bi->bmiHeader.biBitCount == bpp, "GetDIBits modified bpp %u/%u\n",
941 bpp, bi->bmiHeader.biBitCount );
943 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
944 bi->bmiHeader.biWidth = 2;
945 bi->bmiHeader.biHeight = 2;
946 bi->bmiHeader.biPlanes = planes;
947 bi->bmiHeader.biBitCount = bpp;
948 bi->bmiHeader.biCompression = compr;
949 bi->bmiHeader.biSizeImage = 1;
950 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
951 /* RLE allowed with valid biSizeImage */
952 if ((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)) expect_ok = TRUE;
954 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
958 todo_wine ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
960 ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
963 ok( !ret, "SetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
964 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
968 todo_wine ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
970 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
973 ok( !ret, "SetDIBitsToDevice succeeded for %u/%u/%u\n", bpp, planes, compr );
974 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
978 todo_wine ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
980 ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
983 ok( !ret, "StretchDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
985 bi->bmiHeader.biSizeImage = 0;
986 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
987 if (expect_ok || !bpp)
988 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
990 ok( !ret, "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
995 memset( bi, 0, sizeof(bi->bmiHeader) );
996 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
997 bi->bmiHeader.biWidth = 2;
998 bi->bmiHeader.biHeight = 2;
999 bi->bmiHeader.biPlanes = 1;
1000 bi->bmiHeader.biBitCount = 16;
1001 bi->bmiHeader.biCompression = BI_BITFIELDS;
1002 bi->bmiHeader.biSizeImage = 0;
1003 *(DWORD *)&bi->bmiColors[0] = 0;
1004 *(DWORD *)&bi->bmiColors[1] = 0;
1005 *(DWORD *)&bi->bmiColors[2] = 0;
1007 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1008 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1009 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1010 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1011 /* other functions don't check */
1012 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1013 ok( hdib != NULL, "CreateDIBitmap failed with null bitfields\n" );
1014 DeleteObject( hdib );
1015 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1016 todo_wine ok( ret, "SetDIBitsToDevice failed with null bitfields\n" );
1017 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1018 todo_wine ok( ret, "StretchDIBits failed with null bitfields\n" );
1019 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1020 ok( ret, "GetDIBits failed with null bitfields\n" );
1021 bi->bmiHeader.biPlanes = 1;
1022 bi->bmiHeader.biBitCount = 16;
1023 bi->bmiHeader.biCompression = BI_BITFIELDS;
1024 bi->bmiHeader.biSizeImage = 0;
1025 *(DWORD *)&bi->bmiColors[0] = 0;
1026 *(DWORD *)&bi->bmiColors[1] = 0;
1027 *(DWORD *)&bi->bmiColors[2] = 0;
1028 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1029 ok( ret, "GetDIBits failed with null bitfields\n" );
1031 /* all fields must be non-zero */
1032 *(DWORD *)&bi->bmiColors[0] = 3;
1033 *(DWORD *)&bi->bmiColors[1] = 0;
1034 *(DWORD *)&bi->bmiColors[2] = 7;
1035 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1036 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1037 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1038 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1040 /* garbage is ok though */
1041 *(DWORD *)&bi->bmiColors[0] = 0x55;
1042 *(DWORD *)&bi->bmiColors[1] = 0x44;
1043 *(DWORD *)&bi->bmiColors[2] = 0x33;
1044 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1045 ok( hdib != NULL, "CreateDIBSection failed with bad bitfields\n" );
1046 if (hdib) DeleteObject( hdib );
1047 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1048 todo_wine ok( ret, "SetDIBits failed with bad bitfields\n" );
1050 bi->bmiHeader.biWidth = -2;
1051 bi->bmiHeader.biHeight = 2;
1052 bi->bmiHeader.biBitCount = 32;
1053 bi->bmiHeader.biCompression = BI_RGB;
1054 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1055 ok( hdib == NULL, "CreateDIBSection succeeded with negative width\n" );
1056 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1057 ok( hdib == NULL, "CreateDIBitmap succeeded with negative width\n" );
1058 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1059 ok( !ret, "SetDIBits succeeded with negative width\n" );
1060 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1061 ok( !ret, "SetDIBitsToDevice succeeded with negative width\n" );
1062 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1063 ok( !ret, "StretchDIBits succeeded with negative width\n" );
1064 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1065 ok( !ret, "GetDIBits succeeded with negative width\n" );
1066 bi->bmiHeader.biWidth = -2;
1067 bi->bmiHeader.biHeight = 2;
1068 bi->bmiHeader.biBitCount = 32;
1069 bi->bmiHeader.biCompression = BI_RGB;
1070 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1071 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with negative width\n" );
1073 bi->bmiHeader.biWidth = 0;
1074 bi->bmiHeader.biHeight = 2;
1075 bi->bmiHeader.biBitCount = 32;
1076 bi->bmiHeader.biCompression = BI_RGB;
1077 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1078 ok( hdib == NULL, "CreateDIBSection succeeded with zero width\n" );
1079 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1080 ok( hdib != NULL, "CreateDIBitmap failed with zero width\n" );
1081 DeleteObject( hdib );
1082 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1083 ok( !ret || broken(ret), /* nt4 */ "SetDIBits succeeded with zero width\n" );
1084 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1085 ok( !ret || broken(ret), /* nt4 */ "SetDIBitsToDevice succeeded with zero width\n" );
1086 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1087 ok( !ret || broken(ret), /* nt4 */ "StretchDIBits succeeded with zero width\n" );
1088 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1089 ok( !ret, "GetDIBits succeeded with zero width\n" );
1090 bi->bmiHeader.biWidth = 0;
1091 bi->bmiHeader.biHeight = 2;
1092 bi->bmiHeader.biBitCount = 32;
1093 bi->bmiHeader.biCompression = BI_RGB;
1094 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1095 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero width\n" );
1097 bi->bmiHeader.biWidth = 2;
1098 bi->bmiHeader.biHeight = 0;
1099 bi->bmiHeader.biBitCount = 32;
1100 bi->bmiHeader.biCompression = BI_RGB;
1101 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1102 ok( hdib == NULL, "CreateDIBSection succeeded with zero height\n" );
1103 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1104 ok( hdib != NULL, "CreateDIBitmap failed with zero height\n" );
1105 DeleteObject( hdib );
1106 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1107 ok( !ret, "SetDIBits succeeded with zero height\n" );
1108 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1109 ok( !ret, "SetDIBitsToDevice succeeded with zero height\n" );
1110 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1111 ok( !ret, "StretchDIBits succeeded with zero height\n" );
1112 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1113 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1114 bi->bmiHeader.biWidth = 2;
1115 bi->bmiHeader.biHeight = 0;
1116 bi->bmiHeader.biBitCount = 32;
1117 bi->bmiHeader.biCompression = BI_RGB;
1118 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1119 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1122 DeleteObject( hbmp );
1123 ReleaseDC( 0, hdc );
1124 HeapFree( GetProcessHeap(), 0, bi );
1127 static void test_mono_dibsection(void)
1130 HBITMAP old_bm, mono_ds;
1131 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
1132 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
1139 memdc = CreateCompatibleDC(hdc);
1141 memset(pbmi, 0, sizeof(bmibuf));
1142 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
1143 pbmi->bmiHeader.biHeight = 10;
1144 pbmi->bmiHeader.biWidth = 10;
1145 pbmi->bmiHeader.biBitCount = 1;
1146 pbmi->bmiHeader.biPlanes = 1;
1147 pbmi->bmiHeader.biCompression = BI_RGB;
1148 pbmi->bmiColors[0].rgbRed = 0xff;
1149 pbmi->bmiColors[0].rgbGreen = 0xff;
1150 pbmi->bmiColors[0].rgbBlue = 0xff;
1151 pbmi->bmiColors[1].rgbRed = 0x0;
1152 pbmi->bmiColors[1].rgbGreen = 0x0;
1153 pbmi->bmiColors[1].rgbBlue = 0x0;
1156 * First dib section is 'inverted' ie color[0] is white, color[1] is black
1159 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1160 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1161 old_bm = SelectObject(memdc, mono_ds);
1163 /* black border, white interior */
1164 Rectangle(memdc, 0, 0, 10, 10);
1165 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1166 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1168 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1170 memset(bits, 0, sizeof(bits));
1173 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1174 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1176 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1178 pbmi->bmiColors[0].rgbRed = 0x0;
1179 pbmi->bmiColors[0].rgbGreen = 0x0;
1180 pbmi->bmiColors[0].rgbBlue = 0x0;
1181 pbmi->bmiColors[1].rgbRed = 0xff;
1182 pbmi->bmiColors[1].rgbGreen = 0xff;
1183 pbmi->bmiColors[1].rgbBlue = 0xff;
1185 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1186 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1188 SelectObject(memdc, old_bm);
1189 DeleteObject(mono_ds);
1192 * Next dib section is 'normal' ie color[0] is black, color[1] is white
1195 pbmi->bmiColors[0].rgbRed = 0x0;
1196 pbmi->bmiColors[0].rgbGreen = 0x0;
1197 pbmi->bmiColors[0].rgbBlue = 0x0;
1198 pbmi->bmiColors[1].rgbRed = 0xff;
1199 pbmi->bmiColors[1].rgbGreen = 0xff;
1200 pbmi->bmiColors[1].rgbBlue = 0xff;
1202 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1203 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1204 old_bm = SelectObject(memdc, mono_ds);
1206 /* black border, white interior */
1207 Rectangle(memdc, 0, 0, 10, 10);
1208 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
1209 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
1211 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
1213 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1214 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1216 /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
1218 pbmi->bmiColors[0].rgbRed = 0xff;
1219 pbmi->bmiColors[0].rgbGreen = 0xff;
1220 pbmi->bmiColors[0].rgbBlue = 0xff;
1221 pbmi->bmiColors[1].rgbRed = 0x0;
1222 pbmi->bmiColors[1].rgbGreen = 0x0;
1223 pbmi->bmiColors[1].rgbBlue = 0x0;
1225 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1226 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1229 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
1232 pbmi->bmiColors[0].rgbRed = 0xff;
1233 pbmi->bmiColors[0].rgbGreen = 0xff;
1234 pbmi->bmiColors[0].rgbBlue = 0xff;
1235 pbmi->bmiColors[1].rgbRed = 0x0;
1236 pbmi->bmiColors[1].rgbGreen = 0x0;
1237 pbmi->bmiColors[1].rgbBlue = 0x0;
1238 num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors);
1239 ok(num == 2, "num = %d\n", num);
1241 /* black border, white interior */
1242 Rectangle(memdc, 0, 0, 10, 10);
1243 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1244 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1246 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1248 memset(bits, 0, sizeof(bits));
1251 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1252 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1254 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1256 pbmi->bmiColors[0].rgbRed = 0x0;
1257 pbmi->bmiColors[0].rgbGreen = 0x0;
1258 pbmi->bmiColors[0].rgbBlue = 0x0;
1259 pbmi->bmiColors[1].rgbRed = 0xff;
1260 pbmi->bmiColors[1].rgbGreen = 0xff;
1261 pbmi->bmiColors[1].rgbBlue = 0xff;
1263 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1264 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1266 SelectObject(memdc, old_bm);
1267 DeleteObject(mono_ds);
1270 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
1273 pbmi->bmiColors[0].rgbRed = 0xff;
1274 pbmi->bmiColors[0].rgbGreen = 0x0;
1275 pbmi->bmiColors[0].rgbBlue = 0x0;
1276 pbmi->bmiColors[1].rgbRed = 0xfe;
1277 pbmi->bmiColors[1].rgbGreen = 0x0;
1278 pbmi->bmiColors[1].rgbBlue = 0x0;
1280 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1281 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1282 old_bm = SelectObject(memdc, mono_ds);
1284 /* black border, white interior */
1285 Rectangle(memdc, 0, 0, 10, 10);
1286 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1287 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1289 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1291 pbmi->bmiColors[0].rgbRed = 0x0;
1292 pbmi->bmiColors[0].rgbGreen = 0x0;
1293 pbmi->bmiColors[0].rgbBlue = 0x0;
1294 pbmi->bmiColors[1].rgbRed = 0xff;
1295 pbmi->bmiColors[1].rgbGreen = 0xff;
1296 pbmi->bmiColors[1].rgbBlue = 0xff;
1298 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1299 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1301 /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
1303 pbmi->bmiColors[0].rgbRed = 0xff;
1304 pbmi->bmiColors[0].rgbGreen = 0xff;
1305 pbmi->bmiColors[0].rgbBlue = 0xff;
1306 pbmi->bmiColors[1].rgbRed = 0x0;
1307 pbmi->bmiColors[1].rgbGreen = 0x0;
1308 pbmi->bmiColors[1].rgbBlue = 0x0;
1310 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1311 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1313 SelectObject(memdc, old_bm);
1314 DeleteObject(mono_ds);
1320 static void test_bitmap(void)
1322 char buf[256], buf_cmp[256];
1323 HBITMAP hbmp, hbmp_old;
1329 hdc = CreateCompatibleDC(0);
1332 SetLastError(0xdeadbeef);
1333 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1336 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1337 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1338 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1343 SetLastError(0xdeadbeef);
1344 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1347 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1348 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1349 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1354 SetLastError(0xdeadbeef);
1355 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1356 ok(!hbmp, "CreateBitmap should fail\n");
1358 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1359 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1363 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1364 assert(hbmp != NULL);
1366 ret = GetObject(hbmp, sizeof(bm), &bm);
1367 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1369 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1370 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1371 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1372 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1373 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1374 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1375 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1377 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1378 assert(sizeof(buf) == sizeof(buf_cmp));
1380 ret = GetBitmapBits(hbmp, 0, NULL);
1381 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1383 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1384 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1386 memset(buf, 0xAA, sizeof(buf));
1387 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1388 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1389 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1391 hbmp_old = SelectObject(hdc, hbmp);
1393 ret = GetObject(hbmp, sizeof(bm), &bm);
1394 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1396 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1397 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1398 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1399 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1400 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1401 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1402 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1404 memset(buf, 0xAA, sizeof(buf));
1405 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1406 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1407 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1409 hbmp_old = SelectObject(hdc, hbmp_old);
1410 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1412 /* test various buffer sizes for GetObject */
1413 ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
1414 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1416 ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1417 ok(ret == 0, "%d != 0\n", ret);
1419 ret = GetObject(hbmp, 0, &bm);
1420 ok(ret == 0, "%d != 0\n", ret);
1422 ret = GetObject(hbmp, 1, &bm);
1423 ok(ret == 0, "%d != 0\n", ret);
1429 static void test_bmBits(void)
1435 memset(bits, 0, sizeof(bits));
1436 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1437 ok(hbmp != NULL, "CreateBitmap failed\n");
1439 memset(&bmp, 0xFF, sizeof(bmp));
1440 ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1441 "GetObject failed or returned a wrong structure size\n");
1442 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1447 static void test_GetDIBits_selected_DIB(UINT bpp)
1454 UINT dib_size, dib32_size;
1461 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1462 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
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);
1552 HeapFree(GetProcessHeap(), 0, info2);
1553 HeapFree(GetProcessHeap(), 0, info);
1556 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1570 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1571 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1573 width = height = 16;
1575 /* Create a DDB (device-dependent bitmap) */
1579 ddb = CreateBitmap(width, height, 1, 1, NULL);
1583 HDC screen_dc = GetDC(NULL);
1584 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1585 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1586 ReleaseDC(NULL, screen_dc);
1589 /* Set the pixels */
1590 ddb_dc = CreateCompatibleDC(NULL);
1591 old_bmp = SelectObject(ddb_dc, ddb);
1592 for (i = 0; i < width; i++)
1594 for (j=0; j < height; j++)
1596 BYTE c = (i * width + j) % 256;
1597 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1600 SelectObject(ddb_dc, old_bmp);
1602 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1603 info->bmiHeader.biWidth = width;
1604 info->bmiHeader.biHeight = height;
1605 info->bmiHeader.biPlanes = 1;
1606 info->bmiHeader.biBitCount = bpp;
1607 info->bmiHeader.biCompression = BI_RGB;
1609 dc = CreateCompatibleDC(NULL);
1611 /* Fill in biSizeImage */
1612 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1613 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1615 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1616 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1619 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1620 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1622 /* Copy the DIB attributes but not the color table */
1623 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1625 /* Select the DDB into another DC */
1626 old_bmp = SelectObject(ddb_dc, ddb);
1629 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1630 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1632 /* Compare the color table and the bits */
1635 for (i=0; i < (1u << bpp); i++)
1636 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1637 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1638 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1639 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1640 "color table entry %d differs (bpp %d)\n", i, bpp );
1643 ok( !memcmp( bits, bits2, info->bmiHeader.biSizeImage ), "bit mismatch (bpp %d)\n", bpp );
1645 /* Test the palette */
1646 if (info2->bmiHeader.biBitCount <= 8)
1648 WORD *colors = (WORD*)info2->bmiColors;
1650 /* Get the palette indices */
1651 res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1652 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1654 for (i = 0; i < (1 << info->bmiHeader.biBitCount); i++)
1655 ok( colors[i] == i, "%d: got %d (bpp %d)\n", i, colors[i], bpp );
1658 HeapFree(GetProcessHeap(), 0, bits2);
1659 HeapFree(GetProcessHeap(), 0, bits);
1662 SelectObject(ddb_dc, old_bmp);
1665 HeapFree(GetProcessHeap(), 0, info2);
1666 HeapFree(GetProcessHeap(), 0, info);
1669 static void test_GetDIBits(void)
1671 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1672 static const BYTE bmp_bits_1[16 * 2] =
1674 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1675 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1676 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1677 0xff,0xff, 0,0, 0xff,0xff, 0,0
1679 /* 4-bytes aligned 1-bit DIB data: 16x16 */
1680 static const BYTE dib_bits_1[16 * 4] =
1682 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1683 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1684 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1685 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1687 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1688 static const BYTE bmp_bits_24[16 * 16*3] =
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1716 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1717 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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1719 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1720 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1721 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 /* 4-bytes aligned 24-bit DIB data: 16x16 */
1724 static const BYTE dib_bits_24[16 * 16*3] =
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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,
1753 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1754 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1755 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1756 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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1762 int i, bytes, lines;
1764 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1765 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1766 PALETTEENTRY pal_ents[20];
1770 /* 1-bit source bitmap data */
1771 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1772 ok(hbmp != 0, "CreateBitmap failed\n");
1774 memset(&bm, 0xAA, sizeof(bm));
1775 bytes = GetObject(hbmp, sizeof(bm), &bm);
1776 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1777 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1778 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1779 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1780 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1781 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1782 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1783 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1785 bytes = GetBitmapBits(hbmp, 0, NULL);
1786 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1787 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1788 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1789 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1791 /* retrieve 1-bit DIB data */
1792 memset(bi, 0, sizeof(*bi));
1793 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1794 bi->bmiHeader.biWidth = bm.bmWidth;
1795 bi->bmiHeader.biHeight = bm.bmHeight;
1796 bi->bmiHeader.biPlanes = 1;
1797 bi->bmiHeader.biBitCount = 1;
1798 bi->bmiHeader.biCompression = BI_RGB;
1799 bi->bmiHeader.biSizeImage = 0;
1800 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1801 SetLastError(0xdeadbeef);
1802 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1803 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1804 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1805 broken(GetLastError() == 0xdeadbeef), /* winnt */
1806 "wrong error %u\n", GetLastError());
1807 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1809 memset(buf, 0xAA, sizeof(buf));
1810 SetLastError(0xdeadbeef);
1811 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1812 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1813 lines, bm.bmHeight, GetLastError());
1814 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1816 /* the color table consists of black and white */
1817 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1818 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1819 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1820 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1821 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1822 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1823 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1824 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1825 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1826 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1827 for (i = 2; i < 256; i++)
1829 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1830 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1831 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1832 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1833 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1836 /* returned bits are DWORD aligned and upside down */
1837 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1839 /* Test the palette indices */
1840 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1841 SetLastError(0xdeadbeef);
1842 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1843 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1844 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1845 for (i = 2; i < 256; i++)
1846 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[1]);
1848 /* retrieve 24-bit DIB data */
1849 memset(bi, 0, sizeof(*bi));
1850 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1851 bi->bmiHeader.biWidth = bm.bmWidth;
1852 bi->bmiHeader.biHeight = bm.bmHeight;
1853 bi->bmiHeader.biPlanes = 1;
1854 bi->bmiHeader.biBitCount = 24;
1855 bi->bmiHeader.biCompression = BI_RGB;
1856 bi->bmiHeader.biSizeImage = 0;
1857 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1858 memset(buf, 0xAA, sizeof(buf));
1859 SetLastError(0xdeadbeef);
1860 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1861 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1862 lines, bm.bmHeight, GetLastError());
1863 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1865 /* the color table doesn't exist for 24-bit images */
1866 for (i = 0; i < 256; i++)
1868 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1869 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1870 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1871 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1872 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1875 /* returned bits are DWORD aligned and upside down */
1876 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1879 /* 24-bit source bitmap data */
1880 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1881 ok(hbmp != 0, "CreateBitmap failed\n");
1882 SetLastError(0xdeadbeef);
1883 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1884 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1885 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1886 lines, bm.bmHeight, GetLastError());
1888 memset(&bm, 0xAA, sizeof(bm));
1889 bytes = GetObject(hbmp, sizeof(bm), &bm);
1890 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1891 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1892 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1893 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1894 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1895 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1896 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1897 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1899 bytes = GetBitmapBits(hbmp, 0, NULL);
1900 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
1901 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1902 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1903 bm.bmWidthBytes * bm.bmHeight, bytes);
1905 /* retrieve 1-bit DIB data */
1906 memset(bi, 0, sizeof(*bi));
1907 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1908 bi->bmiHeader.biWidth = bm.bmWidth;
1909 bi->bmiHeader.biHeight = bm.bmHeight;
1910 bi->bmiHeader.biPlanes = 1;
1911 bi->bmiHeader.biBitCount = 1;
1912 bi->bmiHeader.biCompression = BI_RGB;
1913 bi->bmiHeader.biSizeImage = 0;
1914 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1915 memset(buf, 0xAA, sizeof(buf));
1916 SetLastError(0xdeadbeef);
1917 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1918 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1919 lines, bm.bmHeight, GetLastError());
1920 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1922 /* the color table consists of black and white */
1923 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1924 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1925 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1926 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1927 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1928 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1929 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1930 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1931 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1932 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1933 for (i = 2; i < 256; i++)
1935 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1936 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1937 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1938 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1939 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1942 /* returned bits are DWORD aligned and upside down */
1943 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1945 /* Test the palette indices */
1946 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1947 SetLastError(0xdeadbeef);
1948 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1949 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1950 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1951 for (i = 2; i < 256; i++)
1952 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[i]);
1954 /* retrieve 4-bit DIB data */
1955 memset(bi, 0, sizeof(*bi));
1956 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1957 bi->bmiHeader.biWidth = bm.bmWidth;
1958 bi->bmiHeader.biHeight = bm.bmHeight;
1959 bi->bmiHeader.biPlanes = 1;
1960 bi->bmiHeader.biBitCount = 4;
1961 bi->bmiHeader.biCompression = BI_RGB;
1962 bi->bmiHeader.biSizeImage = 0;
1963 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1964 memset(buf, 0xAA, sizeof(buf));
1965 SetLastError(0xdeadbeef);
1966 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1967 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1968 lines, bm.bmHeight, GetLastError());
1970 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
1972 for (i = 0; i < 16; i++)
1975 int entry = i < 8 ? i : i + 4;
1977 if(entry == 7) entry = 12;
1978 else if(entry == 12) entry = 7;
1980 expect.rgbRed = pal_ents[entry].peRed;
1981 expect.rgbGreen = pal_ents[entry].peGreen;
1982 expect.rgbBlue = pal_ents[entry].peBlue;
1983 expect.rgbReserved = 0;
1985 ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
1986 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
1987 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
1988 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1989 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1992 /* retrieve 8-bit DIB data */
1993 memset(bi, 0, sizeof(*bi));
1994 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1995 bi->bmiHeader.biWidth = bm.bmWidth;
1996 bi->bmiHeader.biHeight = bm.bmHeight;
1997 bi->bmiHeader.biPlanes = 1;
1998 bi->bmiHeader.biBitCount = 8;
1999 bi->bmiHeader.biCompression = BI_RGB;
2000 bi->bmiHeader.biSizeImage = 0;
2001 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
2002 memset(buf, 0xAA, sizeof(buf));
2003 SetLastError(0xdeadbeef);
2004 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2005 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2006 lines, bm.bmHeight, GetLastError());
2008 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2010 for (i = 0; i < 256; i++)
2014 if (i < 10 || i >= 246)
2016 int entry = i < 10 ? i : i - 236;
2017 expect.rgbRed = pal_ents[entry].peRed;
2018 expect.rgbGreen = pal_ents[entry].peGreen;
2019 expect.rgbBlue = pal_ents[entry].peBlue;
2023 expect.rgbRed = (i & 0x07) << 5;
2024 expect.rgbGreen = (i & 0x38) << 2;
2025 expect.rgbBlue = i & 0xc0;
2027 expect.rgbReserved = 0;
2029 ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
2030 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2031 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2032 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
2033 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
2036 /* retrieve 24-bit DIB data */
2037 memset(bi, 0, sizeof(*bi));
2038 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2039 bi->bmiHeader.biWidth = bm.bmWidth;
2040 bi->bmiHeader.biHeight = bm.bmHeight;
2041 bi->bmiHeader.biPlanes = 1;
2042 bi->bmiHeader.biBitCount = 24;
2043 bi->bmiHeader.biCompression = BI_RGB;
2044 bi->bmiHeader.biSizeImage = 0;
2045 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
2046 memset(buf, 0xAA, sizeof(buf));
2047 SetLastError(0xdeadbeef);
2048 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2049 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2050 lines, bm.bmHeight, GetLastError());
2051 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2053 /* the color table doesn't exist for 24-bit images */
2054 for (i = 0; i < 256; i++)
2056 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
2057 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
2058 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2059 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
2060 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
2063 /* returned bits are DWORD aligned and upside down */
2064 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2070 static void test_GetDIBits_BI_BITFIELDS(void)
2072 /* Try a screen resolution detection technique
2073 * from the September 1999 issue of Windows Developer's Journal
2074 * which seems to be in widespread use.
2075 * http://www.lesher.ws/highcolor.html
2076 * http://www.lesher.ws/vidfmt.c
2077 * It hinges on being able to retrieve the bitmaps
2078 * for the three primary colors in non-paletted 16 bit mode.
2080 char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
2082 LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
2083 DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
2089 memset(dibinfo, 0, sizeof(dibinfo_buf));
2090 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2093 ok(hdc != NULL, "GetDC failed?\n");
2094 hbm = CreateCompatibleBitmap(hdc, 1, 1);
2095 ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
2097 /* Call GetDIBits to fill in bmiHeader. */
2098 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2099 ok(ret == 1, "GetDIBits failed\n");
2100 if (dibinfo->bmiHeader.biBitCount > 8)
2102 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2103 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2104 "compression is %u (%d bpp)\n", dibinfo->bmiHeader.biCompression, dibinfo->bmiHeader.biBitCount );
2106 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2108 ok( !bitmasks[0], "red mask is set\n" );
2109 ok( !bitmasks[1], "green mask is set\n" );
2110 ok( !bitmasks[2], "blue mask is set\n" );
2112 /* test with NULL bits pointer and correct bpp */
2113 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2114 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2115 ok(ret == 1, "GetDIBits failed\n");
2117 ok( bitmasks[0] != 0, "red mask is not set\n" );
2118 ok( bitmasks[1] != 0, "green mask is not set\n" );
2119 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2120 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2122 /* test with valid bits pointer */
2123 memset(dibinfo, 0, sizeof(dibinfo_buf));
2124 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2125 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2126 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2127 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2128 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2129 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2131 ok( bitmasks[0] != 0, "red mask is not set\n" );
2132 ok( bitmasks[1] != 0, "green mask is not set\n" );
2133 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2134 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2136 /* now with bits and 0 lines */
2137 memset(dibinfo, 0, sizeof(dibinfo_buf));
2138 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2139 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2140 SetLastError(0xdeadbeef);
2141 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2142 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2144 ok( !bitmasks[0], "red mask is set\n" );
2145 ok( !bitmasks[1], "green mask is set\n" );
2146 ok( !bitmasks[2], "blue mask is set\n" );
2147 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2149 memset(bitmasks, 0, 3*sizeof(DWORD));
2150 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2151 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2152 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2154 ok( bitmasks[0] != 0, "red mask is not set\n" );
2155 ok( bitmasks[1] != 0, "green mask is not set\n" );
2156 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2157 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2160 else skip("bitmap in colortable mode, skipping BI_BITFIELDS tests\n");
2164 /* same thing now with a 32-bpp DIB section */
2166 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2167 dibinfo->bmiHeader.biWidth = 1;
2168 dibinfo->bmiHeader.biHeight = 1;
2169 dibinfo->bmiHeader.biPlanes = 1;
2170 dibinfo->bmiHeader.biBitCount = 32;
2171 dibinfo->bmiHeader.biCompression = BI_RGB;
2172 dibinfo->bmiHeader.biSizeImage = 0;
2173 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2174 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2175 dibinfo->bmiHeader.biClrUsed = 0;
2176 dibinfo->bmiHeader.biClrImportant = 0;
2177 bitmasks[0] = 0x0000ff;
2178 bitmasks[1] = 0x00ff00;
2179 bitmasks[2] = 0xff0000;
2180 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2181 ok( hbm != 0, "failed to create bitmap\n" );
2183 memset(dibinfo, 0, sizeof(dibinfo_buf));
2184 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2185 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2186 ok(ret == 1, "GetDIBits failed\n");
2187 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2189 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2190 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2191 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2192 ok( !bitmasks[0], "red mask is set\n" );
2193 ok( !bitmasks[1], "green mask is set\n" );
2194 ok( !bitmasks[2], "blue mask is set\n" );
2196 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2197 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2198 ok(ret == 1, "GetDIBits failed\n");
2199 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2200 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2201 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2202 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2203 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2205 ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
2206 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2207 ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
2209 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2213 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2214 dibinfo->bmiHeader.biWidth = 1;
2215 dibinfo->bmiHeader.biHeight = 1;
2216 dibinfo->bmiHeader.biPlanes = 1;
2217 dibinfo->bmiHeader.biBitCount = 32;
2218 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2219 dibinfo->bmiHeader.biSizeImage = 0;
2220 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2221 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2222 dibinfo->bmiHeader.biClrUsed = 0;
2223 dibinfo->bmiHeader.biClrImportant = 0;
2224 bitmasks[0] = 0x0000ff;
2225 bitmasks[1] = 0x00ff00;
2226 bitmasks[2] = 0xff0000;
2227 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2228 ok( hbm != 0, "failed to create bitmap\n" );
2232 memset(dibinfo, 0, sizeof(dibinfo_buf));
2233 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2234 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2235 ok(ret == 1, "GetDIBits failed\n");
2237 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
2238 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2239 ok( !bitmasks[0], "red mask is set\n" );
2240 ok( !bitmasks[1], "green mask is set\n" );
2241 ok( !bitmasks[2], "blue mask is set\n" );
2243 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2244 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2245 ok(ret == 1, "GetDIBits failed\n");
2246 ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
2247 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2248 ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
2249 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2254 /* 24-bpp DIB sections don't have bitfields */
2256 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2257 dibinfo->bmiHeader.biWidth = 1;
2258 dibinfo->bmiHeader.biHeight = 1;
2259 dibinfo->bmiHeader.biPlanes = 1;
2260 dibinfo->bmiHeader.biBitCount = 24;
2261 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2262 dibinfo->bmiHeader.biSizeImage = 0;
2263 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2264 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2265 dibinfo->bmiHeader.biClrUsed = 0;
2266 dibinfo->bmiHeader.biClrImportant = 0;
2267 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2268 ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
2269 dibinfo->bmiHeader.biCompression = BI_RGB;
2270 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2271 ok( hbm != 0, "failed to create bitmap\n" );
2273 memset(dibinfo, 0, sizeof(dibinfo_buf));
2274 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2275 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2276 ok(ret == 1, "GetDIBits failed\n");
2277 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2279 ok( dibinfo->bmiHeader.biCompression == BI_RGB,
2280 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2281 ok( !bitmasks[0], "red mask is set\n" );
2282 ok( !bitmasks[1], "green mask is set\n" );
2283 ok( !bitmasks[2], "blue mask is set\n" );
2285 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2286 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2287 ok(ret == 1, "GetDIBits failed\n");
2288 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2289 ok( !bitmasks[0], "red mask is set\n" );
2290 ok( !bitmasks[1], "green mask is set\n" );
2291 ok( !bitmasks[2], "blue mask is set\n" );
2292 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2295 ReleaseDC(NULL, hdc);
2298 static void test_select_object(void)
2301 HBITMAP hbm, hbm_old;
2303 DWORD depths[] = {8, 15, 16, 24, 32};
2308 ok(hdc != 0, "GetDC(0) failed\n");
2309 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2310 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2312 hbm_old = SelectObject(hdc, hbm);
2313 ok(hbm_old == 0, "SelectObject should fail\n");
2318 hdc = CreateCompatibleDC(0);
2319 ok(hdc != 0, "GetDC(0) failed\n");
2320 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2321 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2323 hbm_old = SelectObject(hdc, hbm);
2324 ok(hbm_old != 0, "SelectObject failed\n");
2325 hbm_old = SelectObject(hdc, hbm_old);
2326 ok(hbm_old == hbm, "SelectObject failed\n");
2330 /* test an 1-bpp bitmap */
2331 planes = GetDeviceCaps(hdc, PLANES);
2334 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
2335 ok(hbm != 0, "CreateBitmap failed\n");
2337 hbm_old = SelectObject(hdc, hbm);
2338 ok(hbm_old != 0, "SelectObject failed\n");
2339 hbm_old = SelectObject(hdc, hbm_old);
2340 ok(hbm_old == hbm, "SelectObject failed\n");
2344 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
2345 /* test a color bitmap to dc bpp matching */
2346 planes = GetDeviceCaps(hdc, PLANES);
2347 bpp = GetDeviceCaps(hdc, BITSPIXEL);
2349 hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
2350 ok(hbm != 0, "CreateBitmap failed\n");
2352 hbm_old = SelectObject(hdc, hbm);
2353 if(depths[i] == bpp ||
2354 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
2356 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
2357 SelectObject(hdc, hbm_old);
2359 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
2362 memset(&bm, 0xAA, sizeof(bm));
2363 bytes = GetObject(hbm, sizeof(bm), &bm);
2364 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2365 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2366 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
2367 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
2368 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2369 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
2370 if(depths[i] == 15) {
2371 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
2373 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2375 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2383 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
2388 ret = GetObjectType(hbmp);
2389 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
2391 ret = GetObject(hbmp, 0, 0);
2392 ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
2394 memset(&bm, 0xDA, sizeof(bm));
2395 SetLastError(0xdeadbeef);
2396 ret = GetObject(hbmp, sizeof(bm), &bm);
2397 if (!ret) /* XP, only for curObj2 */ return;
2398 ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
2399 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2400 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2401 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2402 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2403 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2404 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2405 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2408 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2410 static void test_CreateBitmap(void)
2413 HDC screenDC = GetDC(0);
2414 HDC hdc = CreateCompatibleDC(screenDC);
2417 /* all of these are the stock monochrome bitmap */
2418 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2419 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2420 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2421 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2422 HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2423 HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2425 /* these 2 are not the stock monochrome bitmap */
2426 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2427 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2429 HBITMAP old1 = SelectObject(hdc, bm2);
2430 HBITMAP old2 = SelectObject(screenDC, bm3);
2431 SelectObject(hdc, old1);
2432 SelectObject(screenDC, old2);
2434 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2435 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2436 bm, bm1, bm4, bm5, curObj1, old1);
2437 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2439 ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
2440 ok(old2 == 0, "old2 %p\n", old2);
2442 test_mono_1x1_bmp(bm);
2443 test_mono_1x1_bmp(bm1);
2444 test_mono_1x1_bmp(bm2);
2445 test_mono_1x1_bmp(bm3);
2446 test_mono_1x1_bmp(bm4);
2447 test_mono_1x1_bmp(bm5);
2448 test_mono_1x1_bmp(old1);
2449 test_mono_1x1_bmp(curObj1);
2459 ReleaseDC(0, screenDC);
2461 /* show that Windows ignores the provided bm.bmWidthBytes */
2465 bmp.bmWidthBytes = 28;
2467 bmp.bmBitsPixel = 1;
2469 bm = CreateBitmapIndirect(&bmp);
2470 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2471 test_mono_1x1_bmp(bm);
2474 /* Test how the bmBitsPixel field is treated */
2475 for(i = 1; i <= 33; i++) {
2479 bmp.bmWidthBytes = 28;
2481 bmp.bmBitsPixel = i;
2483 SetLastError(0xdeadbeef);
2484 bm = CreateBitmapIndirect(&bmp);
2486 DWORD error = GetLastError();
2487 ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
2488 ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2492 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2493 GetObject(bm, sizeof(bmp), &bmp);
2500 } else if(i <= 16) {
2502 } else if(i <= 24) {
2504 } else if(i <= 32) {
2507 ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2508 i, bmp.bmBitsPixel, expect);
2513 static void test_bitmapinfoheadersize(void)
2520 memset(&bmi, 0, sizeof(BITMAPINFO));
2521 bmi.bmiHeader.biHeight = 100;
2522 bmi.bmiHeader.biWidth = 512;
2523 bmi.bmiHeader.biBitCount = 24;
2524 bmi.bmiHeader.biPlanes = 1;
2526 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2528 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2529 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2531 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2533 SetLastError(0xdeadbeef);
2534 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2535 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2538 bmi.bmiHeader.biSize++;
2540 SetLastError(0xdeadbeef);
2541 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2543 broken(!hdib), /* Win98, WinMe */
2544 "CreateDIBSection error %d\n", GetLastError());
2547 bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2549 SetLastError(0xdeadbeef);
2550 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2552 broken(!hdib), /* Win98, WinMe */
2553 "CreateDIBSection error %d\n", GetLastError());
2556 bmi.bmiHeader.biSize++;
2558 SetLastError(0xdeadbeef);
2559 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2561 broken(!hdib), /* Win98, WinMe */
2562 "CreateDIBSection error %d\n", GetLastError());
2565 bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2567 SetLastError(0xdeadbeef);
2568 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2569 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2572 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2574 SetLastError(0xdeadbeef);
2575 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2577 broken(!hdib), /* Win95 */
2578 "CreateDIBSection error %d\n", GetLastError());
2581 memset(&bci, 0, sizeof(BITMAPCOREINFO));
2582 bci.bmciHeader.bcHeight = 100;
2583 bci.bmciHeader.bcWidth = 512;
2584 bci.bmciHeader.bcBitCount = 24;
2585 bci.bmciHeader.bcPlanes = 1;
2587 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2589 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2590 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2592 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2594 SetLastError(0xdeadbeef);
2595 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2596 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2599 bci.bmciHeader.bcSize++;
2601 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2602 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2604 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2606 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2607 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2612 static void test_get16dibits(void)
2614 BYTE bits[4 * (16 / sizeof(BYTE))];
2616 HDC screen_dc = GetDC(NULL);
2619 int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2621 int overwritten_bytes = 0;
2623 memset(bits, 0, sizeof(bits));
2624 hbmp = CreateBitmap(2, 2, 1, 16, bits);
2625 ok(hbmp != NULL, "CreateBitmap failed\n");
2627 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2630 memset(info, '!', info_len);
2631 memset(info, 0, sizeof(info->bmiHeader));
2633 info->bmiHeader.biSize = sizeof(info->bmiHeader);
2634 info->bmiHeader.biWidth = 2;
2635 info->bmiHeader.biHeight = 2;
2636 info->bmiHeader.biPlanes = 1;
2637 info->bmiHeader.biCompression = BI_RGB;
2639 ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2640 ok(ret != 0, "GetDIBits failed got %d\n", ret);
2642 for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2644 overwritten_bytes++;
2645 ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2647 HeapFree(GetProcessHeap(), 0, info);
2649 ReleaseDC(NULL, screen_dc);
2652 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2653 DWORD dwRop, UINT32 expected, int line)
2655 *srcBuffer = 0xFEDCBA98;
2656 *dstBuffer = 0x89ABCDEF;
2657 Rectangle(hdcSrc, 0, 0, 1, 1); /* A null operation to ensure dibs are coerced to X11 */
2658 BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
2659 ok(expected == *dstBuffer,
2660 "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2661 dwRop, expected, *dstBuffer, line);
2664 static void test_BitBlt(void)
2666 HBITMAP bmpDst, bmpSrc;
2667 HBITMAP oldDst, oldSrc;
2668 HDC hdcScreen, hdcDst, hdcSrc;
2669 UINT32 *dstBuffer, *srcBuffer;
2670 HBRUSH hBrush, hOldBrush;
2671 BITMAPINFO bitmapInfo;
2673 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2674 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2675 bitmapInfo.bmiHeader.biWidth = 1;
2676 bitmapInfo.bmiHeader.biHeight = 1;
2677 bitmapInfo.bmiHeader.biPlanes = 1;
2678 bitmapInfo.bmiHeader.biBitCount = 32;
2679 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2680 bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2682 hdcScreen = CreateCompatibleDC(0);
2683 hdcDst = CreateCompatibleDC(hdcScreen);
2684 hdcSrc = CreateCompatibleDC(hdcDst);
2686 /* Setup the destination dib section */
2687 bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
2689 oldDst = SelectObject(hdcDst, bmpDst);
2691 hBrush = CreateSolidBrush(0x012345678);
2692 hOldBrush = SelectObject(hdcDst, hBrush);
2694 /* Setup the source dib section */
2695 bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
2697 oldSrc = SelectObject(hdcSrc, bmpSrc);
2699 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2700 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2701 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2702 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2703 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2704 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2705 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2706 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2707 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2708 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2709 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2710 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2711 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2712 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2713 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2716 SelectObject(hdcSrc, oldSrc);
2717 DeleteObject(bmpSrc);
2720 SelectObject(hdcDst, hOldBrush);
2721 DeleteObject(hBrush);
2722 SelectObject(hdcDst, oldDst);
2723 DeleteObject(bmpDst);
2727 DeleteDC(hdcScreen);
2730 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2731 DWORD dwRop, UINT32 expected, int line)
2733 *srcBuffer = 0xFEDCBA98;
2734 *dstBuffer = 0x89ABCDEF;
2735 StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
2736 ok(expected == *dstBuffer,
2737 "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2738 dwRop, expected, *dstBuffer, line);
2741 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, BITMAPINFO *dst_info, UINT32 *dstBuffer, UINT32 *srcBuffer,
2742 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2743 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2744 UINT32 *expected, int line)
2746 int dst_size = get_dib_image_size( dst_info );
2748 memset(dstBuffer, 0, dst_size);
2749 StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2750 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
2751 ok(memcmp(dstBuffer, expected, dst_size) == 0,
2752 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2753 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2754 expected[0], expected[1], expected[2], expected[3],
2755 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2756 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2757 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2760 static void test_StretchBlt(void)
2762 HBITMAP bmpDst, bmpSrc;
2763 HBITMAP oldDst, oldSrc;
2764 HDC hdcScreen, hdcDst, hdcSrc;
2765 UINT32 *dstBuffer, *srcBuffer;
2766 HBRUSH hBrush, hOldBrush;
2767 BITMAPINFO biDst, biSrc;
2768 UINT32 expected[256];
2771 memset(&biDst, 0, sizeof(BITMAPINFO));
2772 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2773 biDst.bmiHeader.biWidth = 16;
2774 biDst.bmiHeader.biHeight = -16;
2775 biDst.bmiHeader.biPlanes = 1;
2776 biDst.bmiHeader.biBitCount = 32;
2777 biDst.bmiHeader.biCompression = BI_RGB;
2778 memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
2780 hdcScreen = CreateCompatibleDC(0);
2781 hdcDst = CreateCompatibleDC(hdcScreen);
2782 hdcSrc = CreateCompatibleDC(hdcDst);
2785 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2787 oldDst = SelectObject(hdcDst, bmpDst);
2789 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2791 oldSrc = SelectObject(hdcSrc, bmpSrc);
2793 hBrush = CreateSolidBrush(0x012345678);
2794 hOldBrush = SelectObject(hdcDst, hBrush);
2796 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2797 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2798 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2799 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2800 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2801 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2802 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2803 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2804 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2805 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2806 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2807 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2808 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2809 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2810 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2812 SelectObject(hdcDst, hOldBrush);
2813 DeleteObject(hBrush);
2815 /* Top-down to top-down tests */
2816 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2817 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2819 memset( expected, 0, get_dib_image_size( &biDst ) );
2820 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2821 expected[16] = 0xFEDCBA98, expected[17] = 0x76543210;
2822 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2823 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2825 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2826 expected[16] = 0x00000000, expected[17] = 0x00000000;
2827 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2828 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
2830 expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
2831 expected[16] = 0xCAFED00D, expected[17] = 0xCAFED00D;
2832 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2833 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
2835 /* This is an example of the dst width (height) == 1 exception, explored below */
2836 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2837 expected[16] = 0x00000000, expected[17] = 0x00000000;
2838 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2839 0, 0, 1, 1, 0, 0, 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 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2846 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2847 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
2848 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2849 1, 1, -2, -2, 0, 0, 2, 2, expected, __LINE__);
2851 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2852 expected[16] = 0x00000000, expected[17] = 0x00000000;
2853 todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2854 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
2856 expected[0] = 0x00000000, expected[1] = 0x00000000;
2857 expected[16] = 0x00000000, expected[17] = 0xCAFED00D, expected[18] = 0xFEEDFACE;
2858 expected[32] = 0x00000000, expected[33] = 0xFEDCBA98, expected[34] = 0x76543210;
2860 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2861 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2863 /* when dst width is 1 merge src width - 1 pixels */
2864 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
2865 srcBuffer[0] = 0x0000ff00, srcBuffer[1] = 0x0000f0f0, srcBuffer[2] = 0x0000cccc, srcBuffer[3] = 0x0000aaaa;
2866 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2868 memset( expected, 0, get_dib_image_size( &biDst ) );
2869 expected[0] = srcBuffer[0];
2870 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2871 0, 0, 1, 1, 0, 0, 2, 1, expected, __LINE__);
2873 expected[0] = srcBuffer[0] & srcBuffer[1];
2874 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2875 0, 0, 1, 1, 0, 0, 3, 1, expected, __LINE__);
2877 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
2878 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2879 0, 0, 1, 1, 0, 0, 4, 1, expected, __LINE__);
2881 /* this doesn't happen if the src width is -ve */
2882 expected[0] = srcBuffer[1] & srcBuffer[2];
2883 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2884 0, 0, 1, 1, 2, 0, -2, 1, expected, __LINE__);
2886 /* when dst width > 1 behaviour reverts to what one would expect */
2887 expected[0] = srcBuffer[0] & srcBuffer[1], expected[1] = srcBuffer[2] & srcBuffer[3];
2888 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2889 0, 0, 2, 1, 0, 0, 4, 1, expected, __LINE__);
2891 /* similarly in the vertical direction */
2892 memset( expected, 0, get_dib_image_size( &biDst ) );
2893 expected[0] = srcBuffer[0];
2894 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2895 0, 0, 1, 1, 0, 0, 1, 2, expected, __LINE__);
2897 /* check that it's the dst size in device units that needs to be 1 */
2898 SetMapMode( hdcDst, MM_ISOTROPIC );
2899 SetWindowExtEx( hdcDst, 200, 200, NULL );
2900 SetViewportExtEx( hdcDst, 100, 100, NULL );
2902 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)
3243 BLENDFUNCTION blend;
3245 if (!pGdiAlphaBlend)
3247 win_skip("GdiAlphaBlend() is not implemented\n");
3251 hdcNull = GetDC(NULL);
3252 hdcDst = CreateCompatibleDC(hdcNull);
3253 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
3254 hdcSrc = CreateCompatibleDC(hdcNull);
3256 bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3257 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3258 bmi->bmiHeader.biHeight = 20;
3259 bmi->bmiHeader.biWidth = 20;
3260 bmi->bmiHeader.biBitCount = 32;
3261 bmi->bmiHeader.biPlanes = 1;
3262 bmi->bmiHeader.biCompression = BI_RGB;
3263 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3264 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3266 oldDst = SelectObject(hdcDst, bmpDst);
3267 oldSrc = SelectObject(hdcSrc, bmpSrc);
3269 blend.BlendOp = AC_SRC_OVER;
3270 blend.BlendFlags = 0;
3271 blend.SourceConstantAlpha = 128;
3272 blend.AlphaFormat = 0;
3274 SetLastError(0xdeadbeef);
3275 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3276 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3278 SetLastError(0xdeadbeef);
3279 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3280 ok( !ret, "GdiAlphaBlend succeeded\n" );
3281 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3283 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3284 ok( !ret, "GdiAlphaBlend succeeded\n" );
3285 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend);
3286 ok( !ret, "GdiAlphaBlend succeeded\n" );
3287 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3288 ok( !ret, "GdiAlphaBlend succeeded\n" );
3289 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3290 ok( !ret, "GdiAlphaBlend succeeded\n" );
3292 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
3293 SetLastError(0xdeadbeef);
3294 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3295 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3296 SetLastError(0xdeadbeef);
3297 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3298 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3299 SetMapMode(hdcSrc, MM_ANISOTROPIC);
3300 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
3301 SetLastError(0xdeadbeef);
3302 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend);
3303 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3304 SetLastError(0xdeadbeef);
3305 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend);
3306 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3308 SetLastError(0xdeadbeef);
3309 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend);
3310 ok( !ret, "GdiAlphaBlend succeeded\n" );
3311 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3313 /* AC_SRC_ALPHA requires 32-bpp BI_RGB format */
3315 blend.AlphaFormat = AC_SRC_ALPHA;
3316 SetLastError(0xdeadbeef);
3317 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3318 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3320 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3321 ((DWORD *)bmi->bmiColors)[0] = 0xff0000;
3322 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3323 ((DWORD *)bmi->bmiColors)[2] = 0x0000ff;
3324 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3325 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3326 oldSrc = SelectObject(hdcSrc, bmpSrc);
3327 DeleteObject( oldSrc );
3329 SetLastError(0xdeadbeef);
3330 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3331 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3333 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3334 ((DWORD *)bmi->bmiColors)[0] = 0x0000ff;
3335 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3336 ((DWORD *)bmi->bmiColors)[2] = 0xff0000;
3337 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3338 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3339 oldSrc = SelectObject(hdcSrc, bmpSrc);
3340 DeleteObject( oldSrc );
3342 SetLastError(0xdeadbeef);
3343 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3344 ok( !ret, "GdiAlphaBlend succeeded\n" );
3345 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3347 bmi->bmiHeader.biBitCount = 24;
3348 bmi->bmiHeader.biCompression = BI_RGB;
3349 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3350 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3351 oldSrc = SelectObject(hdcSrc, bmpSrc);
3352 DeleteObject( oldSrc );
3354 SetLastError(0xdeadbeef);
3355 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3356 ok( !ret, "GdiAlphaBlend succeeded\n" );
3357 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3359 bmi->bmiHeader.biBitCount = 1;
3360 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3361 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3362 oldSrc = SelectObject(hdcSrc, bmpSrc);
3363 DeleteObject( oldSrc );
3365 SetLastError(0xdeadbeef);
3366 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3367 ok( !ret, "GdiAlphaBlend succeeded\n" );
3368 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3370 bmpSrc = CreateBitmap( 100, 100, 1, 1, NULL );
3371 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3372 oldSrc = SelectObject(hdcSrc, bmpSrc);
3373 DeleteObject( oldSrc );
3375 SetLastError(0xdeadbeef);
3376 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3377 ok( !ret, "GdiAlphaBlend succeeded\n" );
3378 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3380 SelectObject(hdcDst, oldDst);
3381 SelectObject(hdcSrc, oldSrc);
3382 DeleteObject(bmpSrc);
3383 DeleteObject(bmpDst);
3387 ReleaseDC(NULL, hdcNull);
3391 static void test_clipping(void)
3399 HDC hdcDst = CreateCompatibleDC( NULL );
3400 HDC hdcSrc = CreateCompatibleDC( NULL );
3402 BITMAPINFO bmpinfo={{0}};
3403 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3404 bmpinfo.bmiHeader.biWidth = 100;
3405 bmpinfo.bmiHeader.biHeight = 100;
3406 bmpinfo.bmiHeader.biPlanes = 1;
3407 bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3408 bmpinfo.bmiHeader.biCompression = BI_RGB;
3410 bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3411 ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3412 SelectObject( hdcDst, bmpDst );
3414 bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3415 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3416 SelectObject( hdcSrc, bmpSrc );
3418 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3419 ok(result, "BitBlt failed\n");
3421 hRgn = CreateRectRgn( 0,0,0,0 );
3422 SelectClipRgn( hdcDst, hRgn );
3424 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3425 ok(result, "BitBlt failed\n");
3427 DeleteObject( bmpDst );
3428 DeleteObject( bmpSrc );
3429 DeleteObject( hRgn );
3434 static void test_32bit_bitmap_blt(void)
3437 HBITMAP bmpSrc, bmpDst;
3438 HBITMAP oldSrc, oldDst;
3439 HDC hdcSrc, hdcDst, hdcScreen;
3441 DWORD colorSrc = 0x11223344;
3443 memset(&biDst, 0, sizeof(BITMAPINFO));
3444 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3445 biDst.bmiHeader.biWidth = 2;
3446 biDst.bmiHeader.biHeight = -2;
3447 biDst.bmiHeader.biPlanes = 1;
3448 biDst.bmiHeader.biBitCount = 32;
3449 biDst.bmiHeader.biCompression = BI_RGB;
3451 hdcScreen = CreateCompatibleDC(0);
3452 if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3454 DeleteDC(hdcScreen);
3455 trace("Skipping 32-bit DDB test\n");
3459 hdcSrc = CreateCompatibleDC(hdcScreen);
3460 bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3461 oldSrc = SelectObject(hdcSrc, bmpSrc);
3463 hdcDst = CreateCompatibleDC(hdcScreen);
3464 bmpDst = CreateDIBSection(hdcDst, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3465 oldDst = SelectObject(hdcDst, bmpDst);
3467 StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3468 ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3471 SelectObject(hdcDst, oldDst);
3472 DeleteObject(bmpDst);
3475 SelectObject(hdcSrc, oldSrc);
3476 DeleteObject(bmpSrc);
3479 DeleteDC(hdcScreen);
3483 * Used by test_GetDIBits_top_down to create the bitmap to test against.
3485 static void setup_picture(char *picture, int bpp)
3493 /*Set the first byte in each pixel to the index of that pixel.*/
3494 for (i = 0; i < 4; i++)
3495 picture[i * (bpp / 8)] = i;
3500 /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
3507 static void test_GetDIBits_top_down(int bpp)
3510 HBITMAP bmptb, bmpbt;
3516 memset( &bi, 0, sizeof(bi) );
3517 bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
3518 bi.bmiHeader.biWidth=2;
3519 bi.bmiHeader.biHeight=2;
3520 bi.bmiHeader.biPlanes=1;
3521 bi.bmiHeader.biBitCount=bpp;
3522 bi.bmiHeader.biCompression=BI_RGB;
3524 /*Get the device context for the screen.*/
3526 ok(hdc != NULL, "Could not get a handle to a device context.\n");
3528 /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
3529 bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3530 ok(bmpbt != NULL, "Could not create a DIB section.\n");
3531 /*Now that we have a pointer to the pixels, we write to them.*/
3532 setup_picture((char*)picture, bpp);
3533 /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
3534 bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
3535 bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3536 ok(bmptb != NULL, "Could not create a DIB section.\n");
3537 /*Write to this top to bottom bitmap.*/
3538 setup_picture((char*)picture, bpp);
3540 bi.bmiHeader.biWidth = 1;
3542 bi.bmiHeader.biHeight = 2;
3543 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3544 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3545 /*Check the first byte of the pixel.*/
3546 ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3547 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3548 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3549 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3550 /*Check second scanline.*/
3551 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3552 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3553 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3554 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3555 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3556 ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3557 /*Check both scanlines.*/
3558 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3559 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3560 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3561 ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3562 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3563 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3564 ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3565 ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3567 /*Make destination bitmap top-down.*/
3568 bi.bmiHeader.biHeight = -2;
3569 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3570 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3571 ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3572 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3573 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3574 ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3575 /*Check second scanline.*/
3576 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3577 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3578 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3579 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3580 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3581 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3582 /*Check both scanlines.*/
3583 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3584 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3585 ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3586 ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3587 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3588 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3589 ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3590 ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3592 DeleteObject(bmpbt);
3593 DeleteObject(bmptb);
3596 static void test_GetSetDIBits_rtl(void)
3599 HBITMAP bitmap, orig_bitmap;
3602 DWORD bits_1[8 * 8], bits_2[8 * 8];
3606 win_skip("Don't have SetLayout\n");
3610 hdc = GetDC( NULL );
3611 hdc_mem = CreateCompatibleDC( hdc );
3612 pSetLayout( hdc_mem, LAYOUT_LTR );
3614 bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
3615 orig_bitmap = SelectObject( hdc_mem, bitmap );
3616 SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
3617 SelectObject( hdc_mem, orig_bitmap );
3619 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3620 info.bmiHeader.biWidth = 8;
3621 info.bmiHeader.biHeight = 8;
3622 info.bmiHeader.biPlanes = 1;
3623 info.bmiHeader.biBitCount = 32;
3624 info.bmiHeader.biCompression = BI_RGB;
3626 /* First show that GetDIBits ignores the layout mode. */
3628 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3629 ok(ret == 8, "got %d\n", ret);
3630 ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
3632 pSetLayout( hdc_mem, LAYOUT_RTL );
3634 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3635 ok(ret == 8, "got %d\n", ret);
3637 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3639 /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
3640 followed by a GetDIBits and show that the bits remain unchanged. */
3642 pSetLayout( hdc_mem, LAYOUT_LTR );
3644 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3645 ok(ret == 8, "got %d\n", ret);
3646 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3647 ok(ret == 8, "got %d\n", ret);
3648 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3650 pSetLayout( hdc_mem, LAYOUT_RTL );
3652 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3653 ok(ret == 8, "got %d\n", ret);
3654 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3655 ok(ret == 8, "got %d\n", ret);
3656 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3658 DeleteObject( bitmap );
3659 DeleteDC( hdc_mem );
3660 ReleaseDC( NULL, hdc );
3663 static void test_GetDIBits_scanlines(void)
3667 HDC hdc = GetDC( NULL );
3669 DWORD data[128], inverted_bits[64];
3672 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
3674 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3675 info->bmiHeader.biWidth = 8;
3676 info->bmiHeader.biHeight = 8;
3677 info->bmiHeader.biPlanes = 1;
3678 info->bmiHeader.biBitCount = 32;
3679 info->bmiHeader.biCompression = BI_RGB;
3681 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3683 for (i = 0; i < 64; i++)
3686 inverted_bits[56 - (i & ~7) + (i & 7)] = i;
3691 memset( data, 0xaa, sizeof(data) );
3693 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3694 ok( ret == 8, "got %d\n", ret );
3695 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3696 memset( data, 0xaa, sizeof(data) );
3698 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3699 ok( ret == 5, "got %d\n", ret );
3700 ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
3701 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3702 memset( data, 0xaa, sizeof(data) );
3704 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3705 ok( ret == 7, "got %d\n", ret );
3706 ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
3707 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3708 memset( data, 0xaa, sizeof(data) );
3710 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3711 ok( ret == 1, "got %d\n", ret );
3712 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3713 memset( data, 0xaa, sizeof(data) );
3715 info->bmiHeader.biHeight = 16;
3716 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3717 ok( ret == 5, "got %d\n", ret );
3718 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3719 ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
3720 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3721 memset( data, 0xaa, sizeof(data) );
3723 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3724 ok( ret == 6, "got %d\n", ret );
3725 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3726 ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
3727 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3728 memset( data, 0xaa, sizeof(data) );
3730 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3731 ok( ret == 0, "got %d\n", ret );
3732 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3733 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3734 memset( data, 0xaa, sizeof(data) );
3736 info->bmiHeader.biHeight = 5;
3737 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3738 ok( ret == 2, "got %d\n", ret );
3739 ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
3740 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3741 memset( data, 0xaa, sizeof(data) );
3745 info->bmiHeader.biHeight = -8;
3746 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3747 ok( ret == 8, "got %d\n", ret );
3748 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3749 memset( data, 0xaa, sizeof(data) );
3751 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3752 ok( ret == 5, "got %d\n", ret );
3753 ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
3754 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3755 memset( data, 0xaa, sizeof(data) );
3757 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3758 ok( ret == 7, "got %d\n", ret );
3759 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3760 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3761 memset( data, 0xaa, sizeof(data) );
3763 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3764 ok( ret == 4, "got %d\n", ret );
3765 ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
3766 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3767 memset( data, 0xaa, sizeof(data) );
3769 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3770 ok( ret == 5, "got %d\n", ret );
3771 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3772 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3773 memset( data, 0xaa, sizeof(data) );
3775 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3776 ok( ret == 5, "got %d\n", ret );
3777 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3778 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3779 memset( data, 0xaa, sizeof(data) );
3781 info->bmiHeader.biHeight = -16;
3782 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3783 ok( ret == 8, "got %d\n", ret );
3784 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3785 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3786 memset( data, 0xaa, sizeof(data) );
3788 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3789 ok( ret == 5, "got %d\n", ret );
3790 ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
3791 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3792 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3793 memset( data, 0xaa, sizeof(data) );
3795 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3796 ok( ret == 8, "got %d\n", ret );
3797 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3798 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3799 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3800 memset( data, 0xaa, sizeof(data) );
3802 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3803 ok( ret == 8, "got %d\n", ret );
3804 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3805 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3806 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3807 memset( data, 0xaa, sizeof(data) );
3809 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3810 ok( ret == 7, "got %d\n", ret );
3811 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3812 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3813 memset( data, 0xaa, sizeof(data) );
3815 ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
3816 ok( ret == 1, "got %d\n", ret );
3817 for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3818 memset( data, 0xaa, sizeof(data) );
3820 info->bmiHeader.biHeight = -5;
3821 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3822 ok( ret == 2, "got %d\n", ret );
3823 ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
3824 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3825 memset( data, 0xaa, sizeof(data) );
3827 DeleteObject( dib );
3829 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3830 info->bmiHeader.biWidth = 8;
3831 info->bmiHeader.biHeight = -8;
3832 info->bmiHeader.biPlanes = 1;
3833 info->bmiHeader.biBitCount = 32;
3834 info->bmiHeader.biCompression = BI_RGB;
3836 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3838 for (i = 0; i < 64; i++) dib_bits[i] = i;
3842 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, dib_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, dib_bits + 16, 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, dib_bits, 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, 4, 12, data, info, DIB_RGB_COLORS );
3861 ok( ret == 4, "got %d\n", ret );
3862 ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
3863 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3864 memset( data, 0xaa, sizeof(data) );
3866 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3867 ok( ret == 5, "got %d\n", ret );
3868 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3869 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3870 memset( data, 0xaa, sizeof(data) );
3872 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3873 ok( ret == 5, "got %d\n", ret );
3874 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3875 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3876 memset( data, 0xaa, sizeof(data) );
3878 info->bmiHeader.biHeight = -16;
3879 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3880 ok( ret == 8, "got %d\n", ret );
3881 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3882 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3883 memset( data, 0xaa, sizeof(data) );
3885 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3886 ok( ret == 5, "got %d\n", ret );
3887 ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
3888 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3889 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3890 memset( data, 0xaa, sizeof(data) );
3892 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3893 ok( ret == 8, "got %d\n", ret );
3894 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3895 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3896 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3897 memset( data, 0xaa, sizeof(data) );
3899 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3900 ok( ret == 8, "got %d\n", ret );
3901 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3902 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3903 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3904 memset( data, 0xaa, sizeof(data) );
3906 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3907 ok( ret == 7, "got %d\n", ret );
3908 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3909 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3910 memset( data, 0xaa, sizeof(data) );
3912 info->bmiHeader.biHeight = -5;
3913 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3914 ok( ret == 2, "got %d\n", ret );
3915 ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
3916 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3917 memset( data, 0xaa, sizeof(data) );
3922 info->bmiHeader.biHeight = 8;
3924 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3925 ok( ret == 8, "got %d\n", ret );
3926 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3927 memset( data, 0xaa, sizeof(data) );
3929 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3930 ok( ret == 5, "got %d\n", ret );
3931 ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
3932 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3933 memset( data, 0xaa, sizeof(data) );
3935 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3936 ok( ret == 7, "got %d\n", ret );
3937 ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
3938 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3939 memset( data, 0xaa, sizeof(data) );
3941 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3942 ok( ret == 1, "got %d\n", ret );
3943 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3944 memset( data, 0xaa, sizeof(data) );
3946 info->bmiHeader.biHeight = 16;
3947 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3948 ok( ret == 5, "got %d\n", ret );
3949 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3950 ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
3951 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3952 memset( data, 0xaa, sizeof(data) );
3954 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3955 ok( ret == 6, "got %d\n", ret );
3956 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3957 ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
3958 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3959 memset( data, 0xaa, sizeof(data) );
3961 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3962 ok( ret == 0, "got %d\n", ret );
3963 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3964 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3965 memset( data, 0xaa, sizeof(data) );
3967 info->bmiHeader.biHeight = 5;
3968 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3969 ok( ret == 2, "got %d\n", ret );
3970 ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
3971 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3972 memset( data, 0xaa, sizeof(data) );
3974 DeleteObject( dib );
3976 ReleaseDC( NULL, hdc );
3977 HeapFree( GetProcessHeap(), 0, info );
3981 static void test_SetDIBits(void)
3985 HDC hdc = GetDC( NULL );
3986 DWORD data[128], inverted_data[128];
3990 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
3992 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3993 info->bmiHeader.biWidth = 8;
3994 info->bmiHeader.biHeight = 8;
3995 info->bmiHeader.biPlanes = 1;
3996 info->bmiHeader.biBitCount = 32;
3997 info->bmiHeader.biCompression = BI_RGB;
3999 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4000 memset( dib_bits, 0xaa, 64 * 4 );
4002 for (i = 0; i < 128; i++)
4005 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4010 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4011 ok( ret == 8, "got %d\n", ret );
4012 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4013 memset( dib_bits, 0xaa, 64 * 4 );
4015 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4016 ok( ret == 5, "got %d\n", ret );
4017 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4018 ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
4019 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4020 memset( dib_bits, 0xaa, 64 * 4 );
4022 /* top of dst is aligned with startscans down for the top of the src.
4023 Then starting from the bottom of src, lines rows are copied across. */
4025 info->bmiHeader.biHeight = 16;
4026 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4027 ok( ret == 12, "got %d\n", ret );
4028 ok( !memcmp( dib_bits, data + 56, 40 * 4 ), "bits differ\n");
4029 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4030 memset( dib_bits, 0xaa, 64 * 4 );
4032 info->bmiHeader.biHeight = 5;
4033 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4034 ok( ret == 2, "got %d\n", ret );
4035 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4036 ok( !memcmp( dib_bits + 32, data, 16 * 4 ), "bits differ\n");
4037 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4038 memset( dib_bits, 0xaa, 64 * 4 );
4041 info->bmiHeader.biHeight = -8;
4042 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4043 ok( ret == 8, "got %d\n", ret );
4044 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4045 memset( dib_bits, 0xaa, 64 * 4 );
4047 /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
4048 we copy lines rows from the top of the src */
4050 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4051 ok( ret == 5, "got %d\n", ret );
4052 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4053 ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
4054 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4055 memset( dib_bits, 0xaa, 64 * 4 );
4057 info->bmiHeader.biHeight = -16;
4058 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4059 ok( ret == 12, "got %d\n", ret );
4060 ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
4061 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4062 memset( dib_bits, 0xaa, 64 * 4 );
4064 ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4065 ok( ret == 12, "got %d\n", ret );
4066 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4067 memset( dib_bits, 0xaa, 64 * 4 );
4069 ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4070 ok( ret == 12, "got %d\n", ret );
4071 ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
4072 memset( dib_bits, 0xaa, 64 * 4 );
4074 info->bmiHeader.biHeight = -5;
4075 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4076 ok( ret == 2, "got %d\n", ret );
4077 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4078 ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
4079 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4080 memset( dib_bits, 0xaa, 64 * 4 );
4082 DeleteObject( dib );
4084 info->bmiHeader.biHeight = -8;
4086 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4087 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4091 /* like the t-d -> b-u case. */
4093 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4094 ok( ret == 8, "got %d\n", ret );
4095 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4096 memset( dib_bits, 0xaa, 64 * 4 );
4098 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4099 ok( ret == 5, "got %d\n", ret );
4100 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4101 ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
4102 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4103 memset( dib_bits, 0xaa, 64 * 4 );
4105 info->bmiHeader.biHeight = -16;
4106 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4107 ok( ret == 12, "got %d\n", ret );
4108 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4109 ok( !memcmp( dib_bits + 24, data, 40 * 4 ), "bits differ\n");
4110 memset( dib_bits, 0xaa, 64 * 4 );
4112 info->bmiHeader.biHeight = -5;
4113 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4114 ok( ret == 2, "got %d\n", ret );
4115 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4116 ok( !memcmp( dib_bits + 16, data, 16 * 4 ), "bits differ\n");
4117 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4118 memset( dib_bits, 0xaa, 64 * 4 );
4121 /* like the b-u -> b-u case */
4123 info->bmiHeader.biHeight = 8;
4124 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4125 ok( ret == 8, "got %d\n", ret );
4126 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4127 memset( dib_bits, 0xaa, 64 * 4 );
4129 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4130 ok( ret == 5, "got %d\n", ret );
4131 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4132 ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
4133 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4134 memset( dib_bits, 0xaa, 64 * 4 );
4136 info->bmiHeader.biHeight = 16;
4137 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4138 ok( ret == 12, "got %d\n", ret );
4139 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4140 ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
4141 memset( dib_bits, 0xaa, 64 * 4 );
4143 info->bmiHeader.biHeight = 5;
4144 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4145 ok( ret == 2, "got %d\n", ret );
4146 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4147 ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
4148 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4149 memset( dib_bits, 0xaa, 64 * 4 );
4151 DeleteObject( dib );
4152 ReleaseDC( NULL, hdc );
4153 HeapFree( GetProcessHeap(), 0, info );
4156 static void test_SetDIBits_RLE4(void)
4160 HDC hdc = GetDC( NULL );
4161 BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00, /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
4162 0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
4163 0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00, /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
4164 0x00, 0x02, 0x01, 0x02, 0x05, 0x87, /* dx=1, dy=2, 8, 7, 8, 7, 8 */
4165 0x00, 0x01 }; /* <eod> */
4168 DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
4169 0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
4170 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4171 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4172 0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
4173 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4174 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4175 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4177 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4179 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4180 info->bmiHeader.biWidth = 8;
4181 info->bmiHeader.biHeight = 8;
4182 info->bmiHeader.biPlanes = 1;
4183 info->bmiHeader.biBitCount = 32;
4184 info->bmiHeader.biCompression = BI_RGB;
4186 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4187 memset( dib_bits, 0xaa, 64 * 4 );
4189 info->bmiHeader.biBitCount = 4;
4190 info->bmiHeader.biCompression = BI_RLE4;
4191 info->bmiHeader.biSizeImage = sizeof(rle4_data);
4193 for (i = 0; i < 16; i++)
4195 info->bmiColors[i].rgbRed = i;
4196 info->bmiColors[i].rgbGreen = i;
4197 info->bmiColors[i].rgbBlue = i;
4198 info->bmiColors[i].rgbReserved = 0;
4201 ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
4202 ok( ret == 8, "got %d\n", ret );
4203 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
4204 memset( dib_bits, 0xaa, 64 * 4 );
4206 DeleteObject( dib );
4207 ReleaseDC( NULL, hdc );
4208 HeapFree( GetProcessHeap(), 0, info );
4211 static void test_SetDIBits_RLE8(void)
4215 HDC hdc = GetDC( NULL );
4216 BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00, /* 2, 2, 2, f0, f0, f0, f0, <eol> */
4217 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4218 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4219 0x00, 0x01 }; /* <eod> */
4222 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4223 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4224 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4225 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4226 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4227 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4228 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4229 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4230 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4231 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4232 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4233 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4234 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4235 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4236 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4237 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4239 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4241 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4242 info->bmiHeader.biWidth = 8;
4243 info->bmiHeader.biHeight = 8;
4244 info->bmiHeader.biPlanes = 1;
4245 info->bmiHeader.biBitCount = 32;
4246 info->bmiHeader.biCompression = BI_RGB;
4248 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4249 memset( dib_bits, 0xaa, 64 * 4 );
4251 info->bmiHeader.biBitCount = 8;
4252 info->bmiHeader.biCompression = BI_RLE8;
4253 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4255 for (i = 0; i < 256; i++)
4257 info->bmiColors[i].rgbRed = i;
4258 info->bmiColors[i].rgbGreen = i;
4259 info->bmiColors[i].rgbBlue = i;
4260 info->bmiColors[i].rgbReserved = 0;
4263 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4264 ok( ret == 8, "got %d\n", ret );
4265 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4266 memset( dib_bits, 0xaa, 64 * 4 );
4268 /* startscan and lines are ignored, unless lines == 0 */
4269 ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4270 ok( ret == 8, "got %d\n", ret );
4271 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4272 memset( dib_bits, 0xaa, 64 * 4 );
4274 ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4275 ok( ret == 8, "got %d\n", ret );
4276 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4277 memset( dib_bits, 0xaa, 64 * 4 );
4279 ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4280 ok( ret == 0, "got %d\n", ret );
4281 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4282 memset( dib_bits, 0xaa, 64 * 4 );
4284 /* reduce width to 4, left-hand side of dst is touched. */
4285 info->bmiHeader.biWidth = 4;
4286 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4287 ok( ret == 8, "got %d\n", ret );
4288 for (i = 0; i < 64; i++)
4290 DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4291 ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4293 memset( dib_bits, 0xaa, 64 * 4 );
4295 /* Show that the top lines are aligned by adjusting the height of the src */
4297 /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4298 info->bmiHeader.biWidth = 8;
4299 info->bmiHeader.biHeight = 4;
4300 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4301 ok( ret == 4, "got %d\n", ret );
4302 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4303 ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4304 memset( dib_bits, 0xaa, 64 * 4 );
4306 /* increase the height to 9 -> everything moves down one row. */
4307 info->bmiHeader.biHeight = 9;
4308 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4309 ok( ret == 9, "got %d\n", ret );
4310 ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4311 for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4312 memset( dib_bits, 0xaa, 64 * 4 );
4314 /* top-down compressed dibs are invalid */
4315 info->bmiHeader.biHeight = -8;
4316 SetLastError( 0xdeadbeef );
4317 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4318 ok( ret == 0, "got %d\n", ret );
4319 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4320 DeleteObject( dib );
4324 info->bmiHeader.biHeight = -8;
4325 info->bmiHeader.biBitCount = 32;
4326 info->bmiHeader.biCompression = BI_RGB;
4327 info->bmiHeader.biSizeImage = 0;
4329 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4330 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4332 info->bmiHeader.biHeight = 8;
4333 info->bmiHeader.biBitCount = 8;
4334 info->bmiHeader.biCompression = BI_RLE8;
4335 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4337 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4338 ok( ret == 8, "got %d\n", ret );
4339 ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4340 memset( dib_bits, 0xaa, 64 * 4 );
4342 info->bmiHeader.biHeight = 4;
4343 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4344 ok( ret == 4, "got %d\n", ret );
4345 ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4346 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4347 memset( dib_bits, 0xaa, 64 * 4 );
4349 info->bmiHeader.biHeight = 9;
4350 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4351 ok( ret == 9, "got %d\n", ret );
4352 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4353 ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4354 memset( dib_bits, 0xaa, 64 * 4 );
4356 DeleteObject( dib );
4357 ReleaseDC( NULL, hdc );
4358 HeapFree( GetProcessHeap(), 0, info );
4361 static void test_SetDIBitsToDevice(void)
4365 HDC hdc = CreateCompatibleDC( 0 );
4366 DWORD data[128], inverted_data[128];
4370 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4372 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4373 info->bmiHeader.biWidth = 8;
4374 info->bmiHeader.biHeight = 8;
4375 info->bmiHeader.biPlanes = 1;
4376 info->bmiHeader.biBitCount = 32;
4377 info->bmiHeader.biCompression = BI_RGB;
4379 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4380 memset( dib_bits, 0xaa, 64 * 4 );
4381 SelectObject( hdc, dib );
4383 for (i = 0; i < 128; i++)
4386 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4391 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4392 ok( ret == 8, "got %d\n", ret );
4393 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4394 memset( dib_bits, 0xaa, 64 * 4 );
4396 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4397 ok( ret == 5, "got %d\n", ret );
4398 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4399 for (i = 8; i < 48; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4400 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4401 memset( dib_bits, 0xaa, 64 * 4 );
4403 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 3, 1, 5, data, info, DIB_RGB_COLORS );
4404 ok( ret == 5, "got %d\n", ret );
4405 for (i = 0; i < 24; i++) ok( dib_bits[i] == data[i + 16], "%d: got %08x\n", i, dib_bits[i] );
4406 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4407 memset( dib_bits, 0xaa, 64 * 4 );
4409 info->bmiHeader.biHeight = 16;
4410 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4411 ok( ret == 7, "got %d\n", ret );
4412 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4413 for (i = 8; i < 64; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4414 memset( dib_bits, 0xaa, 64 * 4 );
4416 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 8, 0, 6, 1, 12, data, info, DIB_RGB_COLORS );
4417 ok( ret == 12, "got %d\n", ret );
4418 for (i = 0; i < 40; i++) ok( dib_bits[i] == data[i + 56], "%d: got %08x\n", i, dib_bits[i] );
4419 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4420 memset( dib_bits, 0xaa, 64 * 4 );
4422 ret = SetDIBitsToDevice( hdc, 0, -4, 8, 8, 0, 3, 1, 12, data, info, DIB_RGB_COLORS );
4423 ok( ret == 10, "got %d\n", ret );
4424 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4425 for (i = 32; i < 64; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4426 memset( dib_bits, 0xaa, 64 * 4 );
4428 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, -3, 1, 12, data, info, DIB_RGB_COLORS );
4429 ok( ret == 4, "got %d\n", ret );
4430 for (i = 0; i < 32; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4431 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4432 memset( dib_bits, 0xaa, 64 * 4 );
4434 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 5, 0, -2, 1, 12, data, info, DIB_RGB_COLORS );
4435 ok( ret == 2, "got %d\n", ret );
4436 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4437 for (i = 32; i < 48; i++) ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4438 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4439 memset( dib_bits, 0xaa, 64 * 4 );
4441 info->bmiHeader.biHeight = 5;
4442 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 2, 2, data, info, DIB_RGB_COLORS );
4443 ok( ret == 2, "got %d\n", ret );
4444 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4445 for (i = 16; i < 32; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4446 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4447 memset( dib_bits, 0xaa, 64 * 4 );
4449 ret = SetDIBitsToDevice( hdc, 3, 3, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4450 ok( ret == 3, "got %d\n", ret );
4451 for (i = 0; i < 64; i++)
4452 if (i == 27 || i == 28 || i == 35 || i == 36)
4453 ok( dib_bits[i] == data[i - 18], "%d: got %08x\n", i, dib_bits[i] );
4455 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4456 memset( dib_bits, 0xaa, 64 * 4 );
4458 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4459 ok( ret == 5, "got %d\n", ret );
4460 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4461 memset( dib_bits, 0xaa, 64 * 4 );
4463 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4464 ok( ret == 0, "got %d\n", ret );
4465 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4466 memset( dib_bits, 0xaa, 64 * 4 );
4468 SetMapMode( hdc, MM_ANISOTROPIC );
4469 SetWindowExtEx( hdc, 3, 3, NULL );
4470 ret = SetDIBitsToDevice( hdc, 2, 2, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4471 ok( ret == 3, "got %d\n", ret );
4472 for (i = 0; i < 64; i++)
4473 if (i == 41 || i == 42 || i == 49 || i == 50)
4474 ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4476 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4477 memset( dib_bits, 0xaa, 64 * 4 );
4479 SetWindowExtEx( hdc, -1, -1, NULL );
4480 ret = SetDIBitsToDevice( hdc, 2, 2, 4, 4, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4481 ok( ret == 4, "got %d\n", ret );
4482 for (i = 0; i < 64; i++)
4483 if (i == 48 || i == 49 || i == 56 || i == 57)
4484 ok( dib_bits[i] == data[i - 37], "%d: got %08x\n", i, dib_bits[i] );
4486 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4487 memset( dib_bits, 0xaa, 64 * 4 );
4488 SetMapMode( hdc, MM_TEXT );
4492 pSetLayout( hdc, LAYOUT_RTL );
4493 ret = SetDIBitsToDevice( hdc, 1, 2, 3, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4494 ok( ret == 3, "got %d\n", ret );
4495 for (i = 0; i < 64; i++)
4496 if (i == 36 || i == 37 || i == 38 || i == 44 || i == 45 || i == 46)
4497 ok( dib_bits[i] == data[i - 27], "%d: got %08x\n", i, dib_bits[i] );
4499 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4500 memset( dib_bits, 0xaa, 64 * 4 );
4501 pSetLayout( hdc, LAYOUT_LTR );
4505 info->bmiHeader.biHeight = -8;
4506 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4507 ok( ret == 8, "got %d\n", ret );
4508 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4509 memset( dib_bits, 0xaa, 64 * 4 );
4511 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4512 ok( ret == 5, "got %d\n", ret );
4513 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4514 for (i = 8; i < 48; i++) ok( dib_bits[i] == inverted_data[i + 80], "%d: got %08x\n", i, dib_bits[i] );
4515 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4516 memset( dib_bits, 0xaa, 64 * 4 );
4518 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 4, 1, 5, data, info, DIB_RGB_COLORS );
4519 ok( ret == 5, "got %d\n", ret );
4520 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4521 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4522 memset( dib_bits, 0xaa, 64 * 4 );
4524 info->bmiHeader.biHeight = -16;
4525 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4526 ok( ret == 12, "got %d\n", ret );
4527 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4528 for (i = 8; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4529 memset( dib_bits, 0xaa, 64 * 4 );
4531 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, 7, 1, 12, data, info, DIB_RGB_COLORS );
4532 ok( ret == 12, "got %d\n", ret );
4533 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4534 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4535 memset( dib_bits, 0xaa, 64 * 4 );
4537 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 4, 12, data, info, DIB_RGB_COLORS );
4538 ok( ret == 12, "got %d\n", ret );
4539 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4540 for (i = 32; i < 64; i++) ok( dib_bits[i] == inverted_data[i], "%d: got %08x\n", i, dib_bits[i] );
4541 memset( dib_bits, 0xaa, 64 * 4 );
4543 ret = SetDIBitsToDevice( hdc, 0, -3, 8, 8, 0, 2, 4, 12, data, info, DIB_RGB_COLORS );
4544 ok( ret == 12, "got %d\n", ret );
4545 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4546 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4547 memset( dib_bits, 0xaa, 64 * 4 );
4549 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, -2, 4, 12, data, info, DIB_RGB_COLORS );
4550 ok( ret == 12, "got %d\n", ret );
4551 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4552 for (i = 24; i < 40; i++) ok( dib_bits[i] == inverted_data[i + 8], "%d: got %08x\n", i, dib_bits[i] );
4553 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4554 memset( dib_bits, 0xaa, 64 * 4 );
4556 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 5, 12, data, info, DIB_RGB_COLORS );
4557 ok( ret == 12, "got %d\n", ret );
4558 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4559 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4560 memset( dib_bits, 0xaa, 64 * 4 );
4562 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4563 ok( ret == 12, "got %d\n", ret );
4564 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4565 memset( dib_bits, 0xaa, 64 * 4 );
4567 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -2, -4, 0, 12, data, info, DIB_RGB_COLORS );
4568 ok( ret == 12, "got %d\n", ret );
4569 for (i = 0; i < 64; i++)
4570 if (i == 31 || i == 39 || i == 47 || i == 55 || i == 63)
4571 ok( dib_bits[i] == inverted_data[i + 1], "%d: got %08x\n", i, dib_bits[i] );
4573 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4574 memset( dib_bits, 0xaa, 64 * 4 );
4576 info->bmiHeader.biHeight = -5;
4577 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4578 ok( ret == 2, "got %d\n", ret );
4579 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4580 for (i = 8; i < 24; i++) ok( dib_bits[i] == inverted_data[i + 104], "%d: got %08x\n", i, dib_bits[i] );
4581 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4582 memset( dib_bits, 0xaa, 64 * 4 );
4584 ret = SetDIBitsToDevice( hdc, 5, 4, 2, 2, 6, 3, 1, 5, data, info, DIB_RGB_COLORS );
4585 ok( ret == 5, "got %d\n", ret );
4586 for (i = 0; i < 64; i++)
4587 if (i == 21 || i == 22 || i == 29 || i == 30)
4588 ok( dib_bits[i] == inverted_data[i + 89], "%d: got %08x\n", i, dib_bits[i] );
4590 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4591 memset( dib_bits, 0xaa, 64 * 4 );
4593 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4594 ok( ret == 5, "got %d\n", ret );
4595 for (i = 0; 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 = -8;
4600 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4601 DeleteObject( SelectObject( hdc, dib ));
4602 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4606 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4607 ok( ret == 8, "got %d\n", ret );
4608 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4609 memset( dib_bits, 0xaa, 64 * 4 );
4611 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4612 ok( ret == 5, "got %d\n", ret );
4613 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4614 for (i = 16; i < 56; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4615 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4616 memset( dib_bits, 0xaa, 64 * 4 );
4618 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 3, 0, 2, 1, 5, data, info, DIB_RGB_COLORS );
4619 ok( ret == 5, "got %d\n", ret );
4620 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4621 for (i = 24; i < 48; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4622 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4623 memset( dib_bits, 0xaa, 64 * 4 );
4625 info->bmiHeader.biHeight = -16;
4626 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4627 ok( ret == 12, "got %d\n", ret );
4628 for (i = 0; i < 56; i++) ok( dib_bits[i] == data[i + 40], "%d: got %08x\n", i, dib_bits[i] );
4629 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4630 memset( dib_bits, 0xaa, 64 * 4 );
4632 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -1, -8, 0, 12, data, info, DIB_RGB_COLORS );
4633 ok( ret == 12, "got %d\n", ret );
4634 for (i = 0; i < 64; i++)
4635 if (i == 6 || i == 7)
4636 ok( dib_bits[i] == data[i + 82], "%d: got %08x\n", i, dib_bits[i] );
4638 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4639 memset( dib_bits, 0xaa, 64 * 4 );
4641 info->bmiHeader.biHeight = -5;
4642 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4643 ok( ret == 2, "got %d\n", ret );
4644 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4645 for (i = 40; i < 56; i++) ok( dib_bits[i] == data[i - 40], "%d: got %08x\n", i, dib_bits[i] );
4646 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4647 memset( dib_bits, 0xaa, 64 * 4 );
4649 ret = SetDIBitsToDevice( hdc, 7, 2, 8, 8, 1, 0, 0, 5, data, info, DIB_RGB_COLORS );
4650 ok( ret == 5, "got %d\n", ret );
4651 for (i = 0; i < 64; i++)
4652 if (i == 47 || i == 55 || i == 63)
4653 ok( dib_bits[i] == data[i - 46], "%d: got %08x\n", i, dib_bits[i] );
4655 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4656 memset( dib_bits, 0xaa, 64 * 4 );
4658 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4659 ok( ret == 5, "got %d\n", ret );
4660 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4661 memset( dib_bits, 0xaa, 64 * 4 );
4665 info->bmiHeader.biHeight = 8;
4666 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4667 ok( ret == 8, "got %d\n", ret );
4668 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4669 memset( dib_bits, 0xaa, 64 * 4 );
4671 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4672 ok( ret == 5, "got %d\n", ret );
4673 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4674 for (i = 16; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4675 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4676 memset( dib_bits, 0xaa, 64 * 4 );
4678 info->bmiHeader.biHeight = 16;
4679 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4680 ok( ret == 7, "got %d\n", ret );
4681 for (i = 0; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4682 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4683 memset( dib_bits, 0xaa, 64 * 4 );
4685 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, 0, -4, 1, 12, data, info, DIB_RGB_COLORS );
4686 ok( ret == 3, "got %d\n", ret );
4687 for (i = 0; i < 64; i++)
4688 if ((i >= 36 && i <= 39) || (i >= 44 && i <= 47) || (i >= 52 && i <= 55))
4689 ok( dib_bits[i] == inverted_data[i + 68], "%d: got %08x\n", i, dib_bits[i] );
4691 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4692 memset( dib_bits, 0xaa, 64 * 4 );
4694 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, -30, -30, 1, 12, data, info, DIB_RGB_COLORS );
4695 ok( ret == 0, "got %d\n", ret );
4696 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4697 memset( dib_bits, 0xaa, 64 * 4 );
4699 ret = SetDIBitsToDevice( hdc, 5, -5, 8, 16, -2, -4, 4, 12, data, info, DIB_RGB_COLORS );
4700 ok( ret == 8, "got %d\n", ret );
4701 for (i = 0; i < 64; i++)
4702 if (i == 7 || i == 15 || i == 23)
4703 ok( dib_bits[i] == inverted_data[i + 97], "%d: got %08x\n", i, dib_bits[i] );
4705 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4706 memset( dib_bits, 0xaa, 64 * 4 );
4708 info->bmiHeader.biHeight = 5;
4709 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4710 ok( ret == 2, "got %d\n", ret );
4711 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4712 for (i = 40; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4713 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4714 memset( dib_bits, 0xaa, 64 * 4 );
4716 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4717 ok( ret == 5, "got %d\n", ret );
4718 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4719 memset( dib_bits, 0xaa, 64 * 4 );
4722 DeleteObject( dib );
4723 HeapFree( GetProcessHeap(), 0, info );
4726 static void test_SetDIBitsToDevice_RLE8(void)
4730 HDC hdc = CreateCompatibleDC( 0 );
4731 BYTE rle8_data[20] = { 0x04, 0x02, 0x03, 0xf0, 0x00, 0x00, /* 2, 2, 2, 2, f0, f0, f0, <eol> */
4732 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4733 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4734 0x00, 0x01 }; /* <eod> */
4737 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4738 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4739 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4740 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4741 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4742 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4743 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4744 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4745 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4746 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4747 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4748 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4749 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4750 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4751 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4752 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4754 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4756 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4757 info->bmiHeader.biWidth = 8;
4758 info->bmiHeader.biHeight = 8;
4759 info->bmiHeader.biPlanes = 1;
4760 info->bmiHeader.biBitCount = 32;
4761 info->bmiHeader.biCompression = BI_RGB;
4763 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4764 memset( dib_bits, 0xaa, 64 * 4 );
4765 SelectObject( hdc, dib );
4767 info->bmiHeader.biBitCount = 8;
4768 info->bmiHeader.biCompression = BI_RLE8;
4769 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4771 for (i = 0; i < 256; i++)
4773 info->bmiColors[i].rgbRed = i;
4774 info->bmiColors[i].rgbGreen = i;
4775 info->bmiColors[i].rgbBlue = i;
4776 info->bmiColors[i].rgbReserved = 0;
4779 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4780 ok( ret == 8, "got %d\n", ret );
4781 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4782 memset( dib_bits, 0xaa, 64 * 4 );
4784 /* startscan and lines are ignored, unless lines == 0 */
4785 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4786 ok( ret == 8, "got %d\n", ret );
4787 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4788 memset( dib_bits, 0xaa, 64 * 4 );
4790 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4791 ok( ret == 8, "got %d\n", ret );
4792 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4793 memset( dib_bits, 0xaa, 64 * 4 );
4795 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4796 ok( ret == 0, "got %d\n", ret );
4797 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4798 memset( dib_bits, 0xaa, 64 * 4 );
4800 info->bmiHeader.biWidth = 2;
4801 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4802 ok( ret == 8, "got %d\n", ret );
4803 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4804 memset( dib_bits, 0xaa, 64 * 4 );
4806 info->bmiHeader.biWidth = 8;
4807 info->bmiHeader.biHeight = 2;
4808 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4809 ok( ret == 2, "got %d\n", ret );
4810 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4811 memset( dib_bits, 0xaa, 64 * 4 );
4813 info->bmiHeader.biHeight = 9;
4814 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4815 ok( ret == 9, "got %d\n", ret );
4816 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4817 memset( dib_bits, 0xaa, 64 * 4 );
4819 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4820 ok( ret == 9, "got %d\n", ret );
4821 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4822 memset( dib_bits, 0xaa, 64 * 4 );
4824 info->bmiHeader.biHeight = 8;
4825 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 9, rle8_data, info, DIB_RGB_COLORS );
4826 ok( ret == 8, "got %d\n", ret );
4827 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4828 memset( dib_bits, 0xaa, 64 * 4 );
4830 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4831 ok( ret == 8, "got %d\n", ret );
4832 for (i = 0; i < 40; i++) ok( dib_bits[i] == bottom_up[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4833 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4834 memset( dib_bits, 0xaa, 64 * 4 );
4836 ret = SetDIBitsToDevice( hdc, 0, 3, 4, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4837 ok( ret == 8, "got %d\n", ret );
4838 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4839 for (i = 8; i < 40; i++)
4840 if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4841 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4842 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4843 memset( dib_bits, 0xaa, 64 * 4 );
4845 ret = SetDIBitsToDevice( hdc, 3, 3, 8, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4846 ok( ret == 8, "got %d\n", ret );
4847 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4848 for (i = 8; i < 40; i++)
4849 if ((i & 7) < 3) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4850 else ok( dib_bits[i] == bottom_up[i - 11], "%d: got %08x\n", i, dib_bits[i] );
4851 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4852 memset( dib_bits, 0xaa, 64 * 4 );
4854 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 4, 2, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4855 ok( ret == 8, "got %d\n", ret );
4856 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4857 for (i = 8; i < 40; i++)
4858 if ((i & 7) < 2) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4859 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4860 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4861 memset( dib_bits, 0xaa, 64 * 4 );
4863 info->bmiHeader.biWidth = 37;
4864 info->bmiHeader.biHeight = 37;
4865 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
4866 ok( ret == 37, "got %d\n", ret );
4867 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4868 for (i = 24; i < 64; i++)
4869 if (i == 52) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
4870 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4871 else ok( dib_bits[i] == bottom_up[i - 20], "%d: got %08x\n", i, dib_bits[i] );
4872 memset( dib_bits, 0xaa, 64 * 4 );
4874 /* top-down compressed dibs are invalid */
4875 info->bmiHeader.biWidth = 8;
4876 info->bmiHeader.biHeight = -8;
4877 SetLastError( 0xdeadbeef );
4878 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4879 ok( ret == 0, "got %d\n", ret );
4880 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4884 info->bmiHeader.biHeight = -8;
4885 info->bmiHeader.biBitCount = 32;
4886 info->bmiHeader.biCompression = BI_RGB;
4887 info->bmiHeader.biSizeImage = 0;
4889 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4890 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4891 DeleteObject( SelectObject( hdc, dib ));
4893 info->bmiHeader.biHeight = 8;
4894 info->bmiHeader.biBitCount = 8;
4895 info->bmiHeader.biCompression = BI_RLE8;
4896 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4898 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4899 ok( ret == 8, "got %d\n", ret );
4900 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4901 memset( dib_bits, 0xaa, 64 * 4 );
4903 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4904 ok( ret == 8, "got %d\n", ret );
4905 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4906 memset( dib_bits, 0xaa, 64 * 4 );
4908 info->bmiHeader.biHeight = 4;
4909 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4910 ok( ret == 4, "got %d\n", ret );
4911 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4912 memset( dib_bits, 0xaa, 64 * 4 );
4914 info->bmiHeader.biHeight = 9;
4915 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4916 ok( ret == 9, "got %d\n", ret );
4917 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4918 memset( dib_bits, 0xaa, 64 * 4 );
4920 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4921 ok( ret == 9, "got %d\n", ret );
4922 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4923 memset( dib_bits, 0xaa, 64 * 4 );
4925 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 6, 2, 2, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4926 ok( ret == 9, "got %d\n", ret );
4927 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4928 for (i = 24; i < 64; i++) ok( dib_bits[i] == top_down[i - 24], "%d: got %08x\n", i, dib_bits[i] );
4929 memset( dib_bits, 0xaa, 64 * 4 );
4931 info->bmiHeader.biWidth = 37;
4932 info->bmiHeader.biHeight = 37;
4933 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
4934 ok( ret == 37, "got %d\n", ret );
4935 for (i = 0; i < 40; i++)
4936 if (i == 12) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
4937 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4938 else ok( dib_bits[i] == top_down[i + 28], "%d: got %08x\n", i, dib_bits[i] );
4939 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4940 memset( dib_bits, 0xaa, 64 * 4 );
4943 DeleteObject( dib );
4944 HeapFree( GetProcessHeap(), 0, info );
4951 hdll = GetModuleHandle("gdi32.dll");
4952 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
4953 pSetLayout = (void*)GetProcAddress(hdll, "SetLayout");
4955 test_createdibitmap();
4958 test_mono_dibsection();
4961 test_GetDIBits_selected_DIB(1);
4962 test_GetDIBits_selected_DIB(4);
4963 test_GetDIBits_selected_DIB(8);
4964 test_GetDIBits_selected_DDB(TRUE);
4965 test_GetDIBits_selected_DDB(FALSE);
4967 test_GetDIBits_BI_BITFIELDS();
4968 test_select_object();
4969 test_CreateBitmap();
4972 test_StretchDIBits();
4973 test_GdiAlphaBlend();
4974 test_32bit_bitmap_blt();
4975 test_bitmapinfoheadersize();
4978 test_GetDIBits_top_down(16);
4979 test_GetDIBits_top_down(24);
4980 test_GetDIBits_top_down(32);
4981 test_GetSetDIBits_rtl();
4982 test_GetDIBits_scanlines();
4984 test_SetDIBits_RLE4();
4985 test_SetDIBits_RLE8();
4986 test_SetDIBitsToDevice();
4987 test_SetDIBitsToDevice_RLE8();