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(hdc, color, exp) \
344 c = SetPixel(hdc, 0, 0, color); \
345 ok(c == exp, "SetPixel failed: got 0x%06x expected 0x%06x\n", c, (UINT)exp); \
346 c = GetPixel(hdc, 0, 0); \
347 ok(c == exp, "GetPixel failed: got 0x%06x expected 0x%06x\n", c, (UINT)exp); \
350 static void test_dib_bits_access( HBITMAP hdib, void *bits )
352 MEMORY_BASIC_INFORMATION info;
353 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
355 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
357 char filename[MAX_PATH];
362 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
363 "VirtualQuery failed\n");
364 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
365 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
366 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
367 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
368 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
369 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
371 memset( pbmi, 0, sizeof(bmibuf) );
372 memset( data, 0xcc, sizeof(data) );
373 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
374 pbmi->bmiHeader.biHeight = 16;
375 pbmi->bmiHeader.biWidth = 16;
376 pbmi->bmiHeader.biBitCount = 32;
377 pbmi->bmiHeader.biPlanes = 1;
378 pbmi->bmiHeader.biCompression = BI_RGB;
382 ret = SetDIBits( hdc, hdib, 0, 16, data, pbmi, DIB_RGB_COLORS );
383 ok(ret == 16, "SetDIBits failed: expected 16 got %d\n", ret);
387 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
388 "VirtualQuery failed\n");
389 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
390 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
391 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
392 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
393 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
394 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
396 /* try writing protected bits to a file */
398 GetTempFileNameA( ".", "dib", 0, filename );
399 file = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
400 CREATE_ALWAYS, 0, 0 );
401 ok( file != INVALID_HANDLE_VALUE, "failed to open %s error %u\n", filename, GetLastError() );
402 ret = WriteFile( file, bits, 8192, &written, NULL );
403 ok( ret, "WriteFile failed error %u\n", GetLastError() );
404 if (ret) ok( written == 8192, "only wrote %u bytes\n", written );
406 DeleteFileA( filename );
409 static void test_dibsections(void)
411 HDC hdc, hdcmem, hdcmem2;
412 HBITMAP hdib, oldbm, hdib2, oldbm2;
413 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
414 char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
415 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
416 BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
417 RGBQUAD *colors = pbmi->bmiColors;
418 RGBTRIPLE *ccolors = pbci->bmciColors;
424 char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
425 LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
426 PALETTEENTRY *palent = plogpal->palPalEntry;
429 HPALETTE hpal, oldpal;
433 MEMORY_BASIC_INFORMATION info;
437 memset(pbmi, 0, sizeof(bmibuf));
438 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
439 pbmi->bmiHeader.biHeight = 100;
440 pbmi->bmiHeader.biWidth = 512;
441 pbmi->bmiHeader.biBitCount = 24;
442 pbmi->bmiHeader.biPlanes = 1;
443 pbmi->bmiHeader.biCompression = BI_RGB;
445 SetLastError(0xdeadbeef);
447 /* invalid pointer for BITMAPINFO
448 (*bits should be NULL on error) */
449 bits = (BYTE*)0xdeadbeef;
450 hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
451 ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n");
453 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
454 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
455 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
456 ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
458 /* test the DIB memory */
459 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
460 "VirtualQuery failed\n");
461 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
462 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
463 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
464 ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
465 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
466 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
467 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
469 test_dib_bits_access( hdib, bits );
471 test_dib_info(hdib, bits, &pbmi->bmiHeader);
474 /* Test a top-down DIB. */
475 pbmi->bmiHeader.biHeight = -100;
476 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
477 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
478 test_dib_info(hdib, bits, &pbmi->bmiHeader);
481 pbmi->bmiHeader.biHeight = 100;
482 pbmi->bmiHeader.biBitCount = 8;
483 pbmi->bmiHeader.biCompression = BI_RLE8;
484 SetLastError(0xdeadbeef);
485 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
486 ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
487 ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
489 pbmi->bmiHeader.biBitCount = 16;
490 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
491 ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
492 ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
493 ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
494 SetLastError(0xdeadbeef);
495 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
496 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
498 /* test the DIB memory */
499 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
500 "VirtualQuery failed\n");
501 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
502 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
503 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
504 ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
505 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
506 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
507 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
509 test_dib_info(hdib, bits, &pbmi->bmiHeader);
512 memset(pbmi, 0, sizeof(bmibuf));
513 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
514 pbmi->bmiHeader.biHeight = 16;
515 pbmi->bmiHeader.biWidth = 16;
516 pbmi->bmiHeader.biBitCount = 1;
517 pbmi->bmiHeader.biPlanes = 1;
518 pbmi->bmiHeader.biCompression = BI_RGB;
519 colors[0].rgbRed = 0xff;
520 colors[0].rgbGreen = 0;
521 colors[0].rgbBlue = 0;
522 colors[1].rgbRed = 0;
523 colors[1].rgbGreen = 0;
524 colors[1].rgbBlue = 0xff;
526 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
527 ok(hdib != NULL, "CreateDIBSection failed\n");
528 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
529 ok(dibsec.dsBmih.biClrUsed == 2,
530 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
532 /* Test if the old BITMAPCOREINFO structure is supported */
534 pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
535 pbci->bmciHeader.bcBitCount = 0;
537 ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
538 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
539 ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
540 && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
541 "GetDIBits didn't fill in the BITMAPCOREHEADER structure properly\n");
543 ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
544 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
545 ok((ccolors[0].rgbtRed == 0xff) && (ccolors[0].rgbtGreen == 0) &&
546 (ccolors[0].rgbtBlue == 0) && (ccolors[1].rgbtRed == 0) &&
547 (ccolors[1].rgbtGreen == 0) && (ccolors[1].rgbtBlue == 0xff),
548 "The color table has not been translated to the old BITMAPCOREINFO format\n");
550 hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
551 ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
553 ZeroMemory(ccolors, 256 * sizeof(RGBTRIPLE));
554 ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
555 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
556 ok((ccolors[0].rgbtRed == 0xff) && (ccolors[0].rgbtGreen == 0) &&
557 (ccolors[0].rgbtBlue == 0) && (ccolors[1].rgbtRed == 0) &&
558 (ccolors[1].rgbtGreen == 0) && (ccolors[1].rgbtBlue == 0xff),
559 "The color table has not been translated to the old BITMAPCOREINFO format\n");
561 DeleteObject(hcoredib);
563 hdcmem = CreateCompatibleDC(hdc);
564 oldbm = SelectObject(hdcmem, hdib);
566 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
567 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
568 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
569 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
570 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
571 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
573 c0 = RGB(colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue);
574 c1 = RGB(colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue);
576 test_color(hdcmem, DIBINDEX(0), c0);
577 test_color(hdcmem, DIBINDEX(1), c1);
578 test_color(hdcmem, DIBINDEX(2), c0);
579 test_color(hdcmem, PALETTEINDEX(0), c0);
580 test_color(hdcmem, PALETTEINDEX(1), c0);
581 test_color(hdcmem, PALETTEINDEX(2), c0);
582 test_color(hdcmem, PALETTERGB(colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue), c0);
583 test_color(hdcmem, PALETTERGB(colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue), c1);
584 test_color(hdcmem, PALETTERGB(0, 0, 0), c0);
585 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0);
586 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1);
588 SelectObject(hdcmem, oldbm);
591 colors[0].rgbRed = 0xff;
592 colors[0].rgbGreen = 0xff;
593 colors[0].rgbBlue = 0xff;
594 colors[1].rgbRed = 0;
595 colors[1].rgbGreen = 0;
596 colors[1].rgbBlue = 0;
598 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
599 ok(hdib != NULL, "CreateDIBSection failed\n");
601 test_dib_info(hdib, bits, &pbmi->bmiHeader);
603 oldbm = SelectObject(hdcmem, hdib);
605 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
606 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
607 ok(!memcmp(rgb, colors, 2 * sizeof(RGBQUAD)),
608 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
609 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
610 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
612 SelectObject(hdcmem, oldbm);
613 test_dib_info(hdib, bits, &pbmi->bmiHeader);
616 pbmi->bmiHeader.biBitCount = 4;
617 for (i = 0; i < 16; i++) {
618 colors[i].rgbRed = i;
619 colors[i].rgbGreen = 16-i;
620 colors[i].rgbBlue = 0;
622 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
623 ok(hdib != NULL, "CreateDIBSection failed\n");
624 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
625 ok(dibsec.dsBmih.biClrUsed == 16,
626 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
627 test_dib_info(hdib, bits, &pbmi->bmiHeader);
630 pbmi->bmiHeader.biBitCount = 8;
632 for (i = 0; i < 128; i++) {
633 colors[i].rgbRed = 255 - i * 2;
634 colors[i].rgbGreen = i * 2;
635 colors[i].rgbBlue = 0;
636 colors[255 - i].rgbRed = 0;
637 colors[255 - i].rgbGreen = i * 2;
638 colors[255 - i].rgbBlue = 255 - i * 2;
640 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
641 ok(hdib != NULL, "CreateDIBSection failed\n");
642 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
643 ok(dibsec.dsBmih.biClrUsed == 256,
644 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
646 oldbm = SelectObject(hdcmem, hdib);
648 for (i = 0; i < 256; i++) {
649 test_color(hdcmem, DIBINDEX(i), RGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue));
650 test_color(hdcmem, PALETTERGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue),
651 RGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue));
654 SelectObject(hdcmem, oldbm);
655 test_dib_info(hdib, bits, &pbmi->bmiHeader);
658 pbmi->bmiHeader.biBitCount = 1;
660 /* Now create a palette and a palette indexed dib section */
661 memset(plogpal, 0, sizeof(logpalbuf));
662 plogpal->palVersion = 0x300;
663 plogpal->palNumEntries = 2;
664 palent[0].peRed = 0xff;
665 palent[0].peBlue = 0xff;
666 palent[1].peGreen = 0xff;
668 index = (WORD*)pbmi->bmiColors;
671 hpal = CreatePalette(plogpal);
672 ok(hpal != NULL, "CreatePalette failed\n");
673 oldpal = SelectPalette(hdc, hpal, TRUE);
674 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
675 ok(hdib != NULL, "CreateDIBSection failed\n");
676 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
677 ok(dibsec.dsBmih.biClrUsed == 2, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
679 /* The colour table has already been grabbed from the dc, so we select back the
682 SelectPalette(hdc, oldpal, TRUE);
683 oldbm = SelectObject(hdcmem, hdib);
684 oldpal = SelectPalette(hdcmem, hpal, TRUE);
686 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
687 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
688 ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
689 rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
690 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
691 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
692 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
694 c0 = RGB(palent[0].peRed, palent[0].peGreen, palent[0].peBlue);
695 c1 = RGB(palent[1].peRed, palent[1].peGreen, palent[1].peBlue);
697 test_color(hdcmem, DIBINDEX(0), c0);
698 test_color(hdcmem, DIBINDEX(1), c1);
699 test_color(hdcmem, DIBINDEX(2), c0);
700 test_color(hdcmem, PALETTEINDEX(0), c0);
701 test_color(hdcmem, PALETTEINDEX(1), c1);
702 test_color(hdcmem, PALETTEINDEX(2), c0);
703 test_color(hdcmem, PALETTERGB(palent[0].peRed, palent[0].peGreen, palent[0].peBlue), c0);
704 test_color(hdcmem, PALETTERGB(palent[1].peRed, palent[1].peGreen, palent[1].peBlue), c1);
705 test_color(hdcmem, PALETTERGB(0, 0, 0), c1);
706 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0);
707 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0);
708 test_color(hdcmem, PALETTERGB(0, 1, 0), c1);
709 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1);
710 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0);
712 /* Bottom and 2nd row from top green, everything else magenta */
713 bits[0] = bits[1] = 0xff;
714 bits[13 * 4] = bits[13*4 + 1] = 0xff;
716 test_dib_info(hdib, bits, &pbmi->bmiHeader);
718 pbmi->bmiHeader.biBitCount = 32;
720 hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
721 ok(hdib2 != NULL, "CreateDIBSection failed\n");
722 hdcmem2 = CreateCompatibleDC(hdc);
723 oldbm2 = SelectObject(hdcmem2, hdib2);
725 BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
727 ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
728 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
730 SelectObject(hdcmem2, oldbm2);
731 test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
734 SelectObject(hdcmem, oldbm);
735 SelectPalette(hdcmem, oldpal, TRUE);
740 pbmi->bmiHeader.biBitCount = 8;
742 memset(plogpal, 0, sizeof(logpalbuf));
743 plogpal->palVersion = 0x300;
744 plogpal->palNumEntries = 256;
746 for (i = 0; i < 128; i++) {
747 palent[i].peRed = 255 - i * 2;
748 palent[i].peBlue = i * 2;
749 palent[i].peGreen = 0;
750 palent[255 - i].peRed = 0;
751 palent[255 - i].peGreen = i * 2;
752 palent[255 - i].peBlue = 255 - i * 2;
755 index = (WORD*)pbmi->bmiColors;
756 for (i = 0; i < 256; i++) {
760 hpal = CreatePalette(plogpal);
761 ok(hpal != NULL, "CreatePalette failed\n");
762 oldpal = SelectPalette(hdc, hpal, TRUE);
763 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
764 ok(hdib != NULL, "CreateDIBSection failed\n");
765 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
766 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
768 test_dib_info(hdib, bits, &pbmi->bmiHeader);
770 SelectPalette(hdc, oldpal, TRUE);
771 oldbm = SelectObject(hdcmem, hdib);
772 oldpal = SelectPalette(hdcmem, hpal, TRUE);
774 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
775 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
776 for (i = 0; i < 256; i++) {
777 ok(rgb[i].rgbRed == palent[i].peRed &&
778 rgb[i].rgbBlue == palent[i].peBlue &&
779 rgb[i].rgbGreen == palent[i].peGreen,
780 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
781 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
784 for (i = 0; i < 256; i++) {
785 test_color(hdcmem, DIBINDEX(i), RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
786 test_color(hdcmem, PALETTEINDEX(i), RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
787 test_color(hdcmem, PALETTERGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue),
788 RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
791 SelectPalette(hdcmem, oldpal, TRUE);
792 SelectObject(hdcmem, oldbm);
801 static void test_dib_formats(void)
806 int planes, bpp, compr;
812 bi = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
814 memdc = CreateCompatibleDC( 0 );
815 hbmp = CreateCompatibleBitmap( hdc, 10, 10 );
817 memset( data, 0xaa, sizeof(data) );
819 for (bpp = 0; bpp <= 64; bpp++)
821 for (planes = 0; planes <= 64; planes++)
823 for (compr = 0; compr < 8; compr++)
830 case 24: expect_ok = (compr == BI_RGB); break;
832 case 32: expect_ok = (compr == BI_RGB || compr == BI_BITFIELDS); break;
833 default: expect_ok = FALSE; break;
836 memset( bi, 0, sizeof(bi->bmiHeader) );
837 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
838 bi->bmiHeader.biWidth = 2;
839 bi->bmiHeader.biHeight = 2;
840 bi->bmiHeader.biPlanes = planes;
841 bi->bmiHeader.biBitCount = bpp;
842 bi->bmiHeader.biCompression = compr;
843 bi->bmiHeader.biSizeImage = 0;
844 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
845 ret = GetDIBits(hdc, hbmp, 0, 0, data, bi, DIB_RGB_COLORS);
846 if (expect_ok || (!bpp && compr != BI_JPEG && compr != BI_PNG) ||
847 (bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8))
848 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
850 ok( !ret || broken(!bpp && (compr == BI_JPEG || compr == BI_PNG)), /* nt4 */
851 "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
853 /* all functions check planes except GetDIBits with 0 lines */
854 if (!planes) expect_ok = FALSE;
855 memset( bi, 0, sizeof(bi->bmiHeader) );
856 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
857 bi->bmiHeader.biWidth = 2;
858 bi->bmiHeader.biHeight = 2;
859 bi->bmiHeader.biPlanes = planes;
860 bi->bmiHeader.biBitCount = bpp;
861 bi->bmiHeader.biCompression = compr;
862 bi->bmiHeader.biSizeImage = 0;
863 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
865 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
866 if (expect_ok && (planes == 1 || planes * bpp <= 16))
867 ok( hdib != NULL, "CreateDIBSection failed for %u/%u/%u\n", bpp, planes, compr );
869 ok( hdib == NULL, "CreateDIBSection succeeded for %u/%u/%u\n", bpp, planes, compr );
870 if (hdib) DeleteObject( hdib );
872 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, data, bi, DIB_RGB_COLORS );
873 /* no sanity checks in CreateDIBitmap except compression */
874 if (compr == BI_JPEG || compr == BI_PNG)
875 ok( hdib == NULL || broken(hdib != NULL), /* nt4 */
876 "CreateDIBitmap succeeded for %u/%u/%u\n", bpp, planes, compr );
878 ok( hdib != NULL, "CreateDIBitmap failed for %u/%u/%u\n", bpp, planes, compr );
879 if (hdib) DeleteObject( hdib );
881 /* RLE needs a size */
882 bi->bmiHeader.biSizeImage = 0;
883 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
885 ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
888 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
889 "SetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
890 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
892 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
895 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
896 "SetDIBitsToDevice succeeded for %u/%u/%u\n", bpp, planes, compr );
897 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
899 ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
902 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
903 "StretchDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
905 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
907 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
909 ok( !ret, "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
910 ok( bi->bmiHeader.biBitCount == bpp, "GetDIBits modified bpp %u/%u\n",
911 bpp, bi->bmiHeader.biBitCount );
913 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
914 bi->bmiHeader.biWidth = 2;
915 bi->bmiHeader.biHeight = 2;
916 bi->bmiHeader.biPlanes = planes;
917 bi->bmiHeader.biBitCount = bpp;
918 bi->bmiHeader.biCompression = compr;
919 bi->bmiHeader.biSizeImage = 1;
920 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
921 /* RLE allowed with valid biSizeImage */
922 if ((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)) expect_ok = TRUE;
924 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
926 ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
928 ok( !ret, "SetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
929 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
931 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
933 ok( !ret, "SetDIBitsToDevice succeeded for %u/%u/%u\n", bpp, planes, compr );
934 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
936 ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
938 ok( !ret, "StretchDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
940 bi->bmiHeader.biSizeImage = 0;
941 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
942 if (expect_ok || !bpp)
943 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
945 ok( !ret, "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
950 memset( bi, 0, sizeof(bi->bmiHeader) );
951 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
952 bi->bmiHeader.biWidth = 2;
953 bi->bmiHeader.biHeight = 2;
954 bi->bmiHeader.biPlanes = 1;
955 bi->bmiHeader.biBitCount = 16;
956 bi->bmiHeader.biCompression = BI_BITFIELDS;
957 bi->bmiHeader.biSizeImage = 0;
958 *(DWORD *)&bi->bmiColors[0] = 0;
959 *(DWORD *)&bi->bmiColors[1] = 0;
960 *(DWORD *)&bi->bmiColors[2] = 0;
962 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
963 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
964 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
965 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
966 /* other functions don't check */
967 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
968 ok( hdib != NULL, "CreateDIBitmap failed with null bitfields\n" );
969 DeleteObject( hdib );
970 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
971 ok( ret, "SetDIBitsToDevice failed with null bitfields\n" );
972 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
973 ok( ret, "StretchDIBits failed with null bitfields\n" );
974 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
975 ok( ret, "GetDIBits failed with null bitfields\n" );
976 bi->bmiHeader.biPlanes = 1;
977 bi->bmiHeader.biBitCount = 16;
978 bi->bmiHeader.biCompression = BI_BITFIELDS;
979 bi->bmiHeader.biSizeImage = 0;
980 *(DWORD *)&bi->bmiColors[0] = 0;
981 *(DWORD *)&bi->bmiColors[1] = 0;
982 *(DWORD *)&bi->bmiColors[2] = 0;
983 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
984 ok( ret, "GetDIBits failed with null bitfields\n" );
986 /* all fields must be non-zero */
987 *(DWORD *)&bi->bmiColors[0] = 3;
988 *(DWORD *)&bi->bmiColors[1] = 0;
989 *(DWORD *)&bi->bmiColors[2] = 7;
990 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
991 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
992 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
993 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
995 /* garbage is ok though */
996 *(DWORD *)&bi->bmiColors[0] = 0x55;
997 *(DWORD *)&bi->bmiColors[1] = 0x44;
998 *(DWORD *)&bi->bmiColors[2] = 0x33;
999 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1000 ok( hdib != NULL, "CreateDIBSection failed with bad bitfields\n" );
1001 if (hdib) DeleteObject( hdib );
1002 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1003 ok( ret, "SetDIBits failed with bad bitfields\n" );
1005 bi->bmiHeader.biWidth = -2;
1006 bi->bmiHeader.biHeight = 2;
1007 bi->bmiHeader.biBitCount = 32;
1008 bi->bmiHeader.biCompression = BI_RGB;
1009 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1010 ok( hdib == NULL, "CreateDIBSection succeeded with negative width\n" );
1011 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1012 ok( hdib == NULL, "CreateDIBitmap succeeded with negative width\n" );
1013 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1014 ok( !ret, "SetDIBits succeeded with negative width\n" );
1015 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1016 ok( !ret, "SetDIBitsToDevice succeeded with negative width\n" );
1017 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1018 ok( !ret, "StretchDIBits succeeded with negative width\n" );
1019 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1020 ok( !ret, "GetDIBits succeeded with negative width\n" );
1021 bi->bmiHeader.biWidth = -2;
1022 bi->bmiHeader.biHeight = 2;
1023 bi->bmiHeader.biBitCount = 32;
1024 bi->bmiHeader.biCompression = BI_RGB;
1025 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1026 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with negative width\n" );
1028 bi->bmiHeader.biWidth = 0;
1029 bi->bmiHeader.biHeight = 2;
1030 bi->bmiHeader.biBitCount = 32;
1031 bi->bmiHeader.biCompression = BI_RGB;
1032 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1033 ok( hdib == NULL, "CreateDIBSection succeeded with zero width\n" );
1034 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1035 ok( hdib != NULL, "CreateDIBitmap failed with zero width\n" );
1036 DeleteObject( hdib );
1037 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1038 ok( !ret || broken(ret), /* nt4 */ "SetDIBits succeeded with zero width\n" );
1039 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1040 ok( !ret || broken(ret), /* nt4 */ "SetDIBitsToDevice succeeded with zero width\n" );
1041 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1042 ok( !ret || broken(ret), /* nt4 */ "StretchDIBits succeeded with zero width\n" );
1043 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1044 ok( !ret, "GetDIBits succeeded with zero width\n" );
1045 bi->bmiHeader.biWidth = 0;
1046 bi->bmiHeader.biHeight = 2;
1047 bi->bmiHeader.biBitCount = 32;
1048 bi->bmiHeader.biCompression = BI_RGB;
1049 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1050 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero width\n" );
1052 bi->bmiHeader.biWidth = 2;
1053 bi->bmiHeader.biHeight = 0;
1054 bi->bmiHeader.biBitCount = 32;
1055 bi->bmiHeader.biCompression = BI_RGB;
1056 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1057 ok( hdib == NULL, "CreateDIBSection succeeded with zero height\n" );
1058 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1059 ok( hdib != NULL, "CreateDIBitmap failed with zero height\n" );
1060 DeleteObject( hdib );
1061 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1062 ok( !ret, "SetDIBits succeeded with zero height\n" );
1063 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1064 ok( !ret, "SetDIBitsToDevice succeeded with zero height\n" );
1065 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1066 ok( !ret, "StretchDIBits succeeded with zero height\n" );
1067 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1068 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1069 bi->bmiHeader.biWidth = 2;
1070 bi->bmiHeader.biHeight = 0;
1071 bi->bmiHeader.biBitCount = 32;
1072 bi->bmiHeader.biCompression = BI_RGB;
1073 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1074 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1077 DeleteObject( hbmp );
1078 ReleaseDC( 0, hdc );
1079 HeapFree( GetProcessHeap(), 0, bi );
1082 static void test_mono_dibsection(void)
1085 HBITMAP old_bm, mono_ds;
1086 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
1087 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
1088 RGBQUAD *colors = pbmi->bmiColors;
1095 memdc = CreateCompatibleDC(hdc);
1097 memset(pbmi, 0, sizeof(bmibuf));
1098 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
1099 pbmi->bmiHeader.biHeight = 10;
1100 pbmi->bmiHeader.biWidth = 10;
1101 pbmi->bmiHeader.biBitCount = 1;
1102 pbmi->bmiHeader.biPlanes = 1;
1103 pbmi->bmiHeader.biCompression = BI_RGB;
1104 colors[0].rgbRed = 0xff;
1105 colors[0].rgbGreen = 0xff;
1106 colors[0].rgbBlue = 0xff;
1107 colors[1].rgbRed = 0x0;
1108 colors[1].rgbGreen = 0x0;
1109 colors[1].rgbBlue = 0x0;
1112 * First dib section is 'inverted' ie color[0] is white, color[1] is black
1115 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1116 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1117 old_bm = SelectObject(memdc, mono_ds);
1119 /* black border, white interior */
1120 Rectangle(memdc, 0, 0, 10, 10);
1121 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1122 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1124 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1126 memset(bits, 0, sizeof(bits));
1129 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1130 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1132 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1134 colors[0].rgbRed = 0x0;
1135 colors[0].rgbGreen = 0x0;
1136 colors[0].rgbBlue = 0x0;
1137 colors[1].rgbRed = 0xff;
1138 colors[1].rgbGreen = 0xff;
1139 colors[1].rgbBlue = 0xff;
1141 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1142 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1144 SelectObject(memdc, old_bm);
1145 DeleteObject(mono_ds);
1148 * Next dib section is 'normal' ie color[0] is black, color[1] is white
1151 colors[0].rgbRed = 0x0;
1152 colors[0].rgbGreen = 0x0;
1153 colors[0].rgbBlue = 0x0;
1154 colors[1].rgbRed = 0xff;
1155 colors[1].rgbGreen = 0xff;
1156 colors[1].rgbBlue = 0xff;
1158 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1159 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1160 old_bm = SelectObject(memdc, mono_ds);
1162 /* black border, white interior */
1163 Rectangle(memdc, 0, 0, 10, 10);
1164 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
1165 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
1167 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
1169 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1170 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1172 /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
1174 colors[0].rgbRed = 0xff;
1175 colors[0].rgbGreen = 0xff;
1176 colors[0].rgbBlue = 0xff;
1177 colors[1].rgbRed = 0x0;
1178 colors[1].rgbGreen = 0x0;
1179 colors[1].rgbBlue = 0x0;
1181 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1182 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1185 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
1188 colors[0].rgbRed = 0xff;
1189 colors[0].rgbGreen = 0xff;
1190 colors[0].rgbBlue = 0xff;
1191 colors[1].rgbRed = 0x0;
1192 colors[1].rgbGreen = 0x0;
1193 colors[1].rgbBlue = 0x0;
1194 num = SetDIBColorTable(memdc, 0, 2, colors);
1195 ok(num == 2, "num = %d\n", num);
1197 /* black border, white interior */
1198 Rectangle(memdc, 0, 0, 10, 10);
1199 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1200 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1202 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1204 memset(bits, 0, sizeof(bits));
1207 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1208 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1210 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1212 colors[0].rgbRed = 0x0;
1213 colors[0].rgbGreen = 0x0;
1214 colors[0].rgbBlue = 0x0;
1215 colors[1].rgbRed = 0xff;
1216 colors[1].rgbGreen = 0xff;
1217 colors[1].rgbBlue = 0xff;
1219 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1220 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1222 SelectObject(memdc, old_bm);
1223 DeleteObject(mono_ds);
1226 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
1229 colors[0].rgbRed = 0xff;
1230 colors[0].rgbGreen = 0x0;
1231 colors[0].rgbBlue = 0x0;
1232 colors[1].rgbRed = 0xfe;
1233 colors[1].rgbGreen = 0x0;
1234 colors[1].rgbBlue = 0x0;
1236 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1237 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1238 old_bm = SelectObject(memdc, mono_ds);
1240 /* black border, white interior */
1241 Rectangle(memdc, 0, 0, 10, 10);
1242 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1243 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1245 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1247 colors[0].rgbRed = 0x0;
1248 colors[0].rgbGreen = 0x0;
1249 colors[0].rgbBlue = 0x0;
1250 colors[1].rgbRed = 0xff;
1251 colors[1].rgbGreen = 0xff;
1252 colors[1].rgbBlue = 0xff;
1254 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1255 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1257 /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
1259 colors[0].rgbRed = 0xff;
1260 colors[0].rgbGreen = 0xff;
1261 colors[0].rgbBlue = 0xff;
1262 colors[1].rgbRed = 0x0;
1263 colors[1].rgbGreen = 0x0;
1264 colors[1].rgbBlue = 0x0;
1266 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1267 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1269 SelectObject(memdc, old_bm);
1270 DeleteObject(mono_ds);
1276 static void test_bitmap(void)
1278 char buf[256], buf_cmp[256];
1279 HBITMAP hbmp, hbmp_old;
1285 hdc = CreateCompatibleDC(0);
1288 SetLastError(0xdeadbeef);
1289 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1292 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1293 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1294 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1299 SetLastError(0xdeadbeef);
1300 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1303 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1304 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1305 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1310 SetLastError(0xdeadbeef);
1311 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1312 ok(!hbmp, "CreateBitmap should fail\n");
1314 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1315 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1319 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1320 assert(hbmp != NULL);
1322 ret = GetObject(hbmp, sizeof(bm), &bm);
1323 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1325 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1326 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1327 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1328 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1329 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1330 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1331 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1333 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1334 assert(sizeof(buf) == sizeof(buf_cmp));
1336 ret = GetBitmapBits(hbmp, 0, NULL);
1337 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1339 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1340 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1342 memset(buf, 0xAA, sizeof(buf));
1343 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1344 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1345 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1347 hbmp_old = SelectObject(hdc, hbmp);
1349 ret = GetObject(hbmp, sizeof(bm), &bm);
1350 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1352 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1353 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1354 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1355 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1356 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1357 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1358 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1360 memset(buf, 0xAA, sizeof(buf));
1361 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1362 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1363 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1365 hbmp_old = SelectObject(hdc, hbmp_old);
1366 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1368 /* test various buffer sizes for GetObject */
1369 ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
1370 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1372 ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1373 ok(ret == 0, "%d != 0\n", ret);
1375 ret = GetObject(hbmp, 0, &bm);
1376 ok(ret == 0, "%d != 0\n", ret);
1378 ret = GetObject(hbmp, 1, &bm);
1379 ok(ret == 0, "%d != 0\n", ret);
1385 static void test_bmBits(void)
1391 memset(bits, 0, sizeof(bits));
1392 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1393 ok(hbmp != NULL, "CreateBitmap failed\n");
1395 memset(&bmp, 0xFF, sizeof(bmp));
1396 ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1397 "GetObject failed or returned a wrong structure size\n");
1398 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1403 static void test_GetDIBits_selected_DIB(UINT bpp)
1410 UINT dib_size, dib32_size;
1417 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1418 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1420 /* Create a DIB section with a color table */
1422 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1423 info->bmiHeader.biWidth = 32;
1424 info->bmiHeader.biHeight = 32;
1425 info->bmiHeader.biPlanes = 1;
1426 info->bmiHeader.biBitCount = bpp;
1427 info->bmiHeader.biCompression = BI_RGB;
1428 info->bmiHeader.biXPelsPerMeter = 0;
1429 info->bmiHeader.biYPelsPerMeter = 0;
1430 info->bmiHeader.biClrUsed = 0;
1431 info->bmiHeader.biClrImportant = 0;
1433 for (i=0; i < (1u << bpp); i++)
1435 BYTE c = i * (1 << (8 - bpp));
1436 info->bmiColors[i].rgbRed = c;
1437 info->bmiColors[i].rgbGreen = c;
1438 info->bmiColors[i].rgbBlue = c;
1439 info->bmiColors[i].rgbReserved = 0;
1442 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1443 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1444 dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1446 /* Set the bits of the DIB section */
1447 for (i=0; i < dib_size; i++)
1449 ((BYTE *)bits)[i] = i % 256;
1452 /* Select the DIB into a DC */
1453 dib_dc = CreateCompatibleDC(NULL);
1454 old_bmp = SelectObject(dib_dc, dib);
1455 dc = CreateCompatibleDC(NULL);
1456 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
1458 /* Copy the DIB attributes but not the color table */
1459 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1461 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1462 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1464 /* Compare the color table and the bits */
1465 for (i=0; i < (1u << bpp); i++)
1466 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1467 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1468 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1469 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1470 "color table entry %d differs (bpp %d)\n", i, bpp );
1472 ok( !memcmp( bits, bits2, dib_size ), "bit mismatch (bpp %d)\n", bpp );
1474 /* Test various combinations of lines = 0 and bits2 = NULL */
1475 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1476 res = GetDIBits( dc, dib, 0, 0, bits2, info2, DIB_RGB_COLORS );
1477 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1478 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1479 "color table mismatch (bpp %d)\n", bpp );
1481 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1482 res = GetDIBits( dc, dib, 0, 0, NULL, info2, DIB_RGB_COLORS );
1483 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1484 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1485 "color table mismatch (bpp %d)\n", bpp );
1487 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1488 res = GetDIBits( dc, dib, 0, info->bmiHeader.biHeight, NULL, info2, DIB_RGB_COLORS );
1489 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1490 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1491 "color table mismatch (bpp %d)\n", bpp );
1493 /* Map into a 32bit-DIB */
1494 info2->bmiHeader.biBitCount = 32;
1495 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1496 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1498 /* Check if last pixel was set */
1499 pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
1500 ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
1502 HeapFree(GetProcessHeap(), 0, bits2);
1505 SelectObject(dib_dc, old_bmp);
1508 HeapFree(GetProcessHeap(), 0, info2);
1509 HeapFree(GetProcessHeap(), 0, info);
1512 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1526 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1527 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1529 width = height = 16;
1531 /* Create a DDB (device-dependent bitmap) */
1535 ddb = CreateBitmap(width, height, 1, 1, NULL);
1539 HDC screen_dc = GetDC(NULL);
1540 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1541 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1542 ReleaseDC(NULL, screen_dc);
1545 /* Set the pixels */
1546 ddb_dc = CreateCompatibleDC(NULL);
1547 old_bmp = SelectObject(ddb_dc, ddb);
1548 for (i = 0; i < width; i++)
1550 for (j=0; j < height; j++)
1552 BYTE c = (i * width + j) % 256;
1553 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1556 SelectObject(ddb_dc, old_bmp);
1558 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1559 info->bmiHeader.biWidth = width;
1560 info->bmiHeader.biHeight = height;
1561 info->bmiHeader.biPlanes = 1;
1562 info->bmiHeader.biBitCount = bpp;
1563 info->bmiHeader.biCompression = BI_RGB;
1565 dc = CreateCompatibleDC(NULL);
1567 /* Fill in biSizeImage */
1568 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1569 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1571 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1572 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1575 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1576 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1578 /* Copy the DIB attributes but not the color table */
1579 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1581 /* Select the DDB into another DC */
1582 old_bmp = SelectObject(ddb_dc, ddb);
1585 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1586 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1588 /* Compare the color table and the bits */
1591 for (i=0; i < (1u << bpp); i++)
1592 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1593 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1594 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1595 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1596 "color table entry %d differs (bpp %d)\n", i, bpp );
1599 ok( !memcmp( bits, bits2, info->bmiHeader.biSizeImage ), "bit mismatch (bpp %d)\n", bpp );
1601 /* Test the palette */
1602 if (info2->bmiHeader.biBitCount <= 8)
1604 WORD *colors = (WORD*)info2->bmiColors;
1606 /* Get the palette indices */
1607 res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1608 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1610 for (i = 0; i < (1 << info->bmiHeader.biBitCount); i++)
1611 ok( colors[i] == i, "%d: got %d (bpp %d)\n", i, colors[i], bpp );
1614 HeapFree(GetProcessHeap(), 0, bits2);
1615 HeapFree(GetProcessHeap(), 0, bits);
1618 SelectObject(ddb_dc, old_bmp);
1621 HeapFree(GetProcessHeap(), 0, info2);
1622 HeapFree(GetProcessHeap(), 0, info);
1625 static void test_GetDIBits(void)
1627 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1628 static const BYTE bmp_bits_1[16 * 2] =
1630 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1631 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1632 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1633 0xff,0xff, 0,0, 0xff,0xff, 0,0
1635 /* 4-bytes aligned 1-bit DIB data: 16x16 */
1636 static const BYTE dib_bits_1[16 * 4] =
1638 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1639 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1640 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1641 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1643 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1644 static const BYTE bmp_bits_24[16 * 16*3] =
1646 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1647 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1648 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1649 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1650 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1651 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1652 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1653 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1654 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1655 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1656 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1657 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1658 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1659 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1660 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1661 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1662 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1663 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1664 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1665 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1666 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1667 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1668 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1669 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1670 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1671 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1672 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1673 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1674 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1675 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1676 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1677 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1679 /* 4-bytes aligned 24-bit DIB data: 16x16 */
1680 static const BYTE dib_bits_24[16 * 16*3] =
1682 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1683 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1684 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1685 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1686 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1687 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1688 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1689 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1690 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1691 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1692 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1693 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1694 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1695 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1696 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1697 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1698 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1699 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1700 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1701 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1702 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1703 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1704 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1705 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1706 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1707 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1708 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1709 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1710 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1711 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1712 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1713 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1718 int i, bytes, lines;
1720 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1721 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1722 RGBQUAD *colors = bi->bmiColors;
1723 PALETTEENTRY pal_ents[20];
1727 /* 1-bit source bitmap data */
1728 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1729 ok(hbmp != 0, "CreateBitmap failed\n");
1731 memset(&bm, 0xAA, sizeof(bm));
1732 bytes = GetObject(hbmp, sizeof(bm), &bm);
1733 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1734 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1735 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1736 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1737 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1738 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1739 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1740 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1742 bytes = GetBitmapBits(hbmp, 0, NULL);
1743 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1744 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1745 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1746 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1748 /* retrieve 1-bit DIB data */
1749 memset(bi, 0, sizeof(*bi));
1750 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1751 bi->bmiHeader.biWidth = bm.bmWidth;
1752 bi->bmiHeader.biHeight = bm.bmHeight;
1753 bi->bmiHeader.biPlanes = 1;
1754 bi->bmiHeader.biBitCount = 1;
1755 bi->bmiHeader.biCompression = BI_RGB;
1756 bi->bmiHeader.biSizeImage = 0;
1757 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1758 SetLastError(0xdeadbeef);
1759 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1760 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1761 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1762 broken(GetLastError() == 0xdeadbeef), /* winnt */
1763 "wrong error %u\n", GetLastError());
1764 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1766 memset(buf, 0xAA, sizeof(buf));
1767 SetLastError(0xdeadbeef);
1768 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1769 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1770 lines, bm.bmHeight, GetLastError());
1771 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1773 /* the color table consists of black and white */
1774 ok(colors[0].rgbRed == 0 && colors[0].rgbGreen == 0 &&
1775 colors[0].rgbBlue == 0 && colors[0].rgbReserved == 0,
1776 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1777 colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue, colors[0].rgbReserved);
1778 ok(colors[1].rgbRed == 0xff && colors[1].rgbGreen == 0xff &&
1779 colors[1].rgbBlue == 0xff && colors[1].rgbReserved == 0,
1780 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1781 colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue, colors[1].rgbReserved);
1782 for (i = 2; i < 256; i++)
1784 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
1785 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
1786 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1787 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
1790 /* returned bits are DWORD aligned and upside down */
1791 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1793 /* Test the palette indices */
1794 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1795 SetLastError(0xdeadbeef);
1796 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1797 ok(((WORD*)colors)[0] == 0, "Color 0 is %d\n", ((WORD*)colors)[0]);
1798 ok(((WORD*)colors)[1] == 1, "Color 1 is %d\n", ((WORD*)colors)[1]);
1799 for (i = 2; i < 256; i++)
1800 ok(((WORD*)colors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)colors)[1]);
1802 /* retrieve 24-bit DIB data */
1803 memset(bi, 0, sizeof(*bi));
1804 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1805 bi->bmiHeader.biWidth = bm.bmWidth;
1806 bi->bmiHeader.biHeight = bm.bmHeight;
1807 bi->bmiHeader.biPlanes = 1;
1808 bi->bmiHeader.biBitCount = 24;
1809 bi->bmiHeader.biCompression = BI_RGB;
1810 bi->bmiHeader.biSizeImage = 0;
1811 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1812 memset(buf, 0xAA, sizeof(buf));
1813 SetLastError(0xdeadbeef);
1814 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1815 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1816 lines, bm.bmHeight, GetLastError());
1817 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1819 /* the color table doesn't exist for 24-bit images */
1820 for (i = 0; i < 256; i++)
1822 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
1823 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
1824 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1825 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
1828 /* returned bits are DWORD aligned and upside down */
1829 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1832 /* 24-bit source bitmap data */
1833 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1834 ok(hbmp != 0, "CreateBitmap failed\n");
1835 SetLastError(0xdeadbeef);
1836 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1837 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1838 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1839 lines, bm.bmHeight, GetLastError());
1841 memset(&bm, 0xAA, sizeof(bm));
1842 bytes = GetObject(hbmp, sizeof(bm), &bm);
1843 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1844 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1845 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1846 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1847 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1848 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1849 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1850 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1852 bytes = GetBitmapBits(hbmp, 0, NULL);
1853 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
1854 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1855 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1856 bm.bmWidthBytes * bm.bmHeight, bytes);
1858 /* retrieve 1-bit DIB data */
1859 memset(bi, 0, sizeof(*bi));
1860 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1861 bi->bmiHeader.biWidth = bm.bmWidth;
1862 bi->bmiHeader.biHeight = bm.bmHeight;
1863 bi->bmiHeader.biPlanes = 1;
1864 bi->bmiHeader.biBitCount = 1;
1865 bi->bmiHeader.biCompression = BI_RGB;
1866 bi->bmiHeader.biSizeImage = 0;
1867 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1868 memset(buf, 0xAA, sizeof(buf));
1869 SetLastError(0xdeadbeef);
1870 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1871 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1872 lines, bm.bmHeight, GetLastError());
1873 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1875 /* the color table consists of black and white */
1876 ok(colors[0].rgbRed == 0 && colors[0].rgbGreen == 0 &&
1877 colors[0].rgbBlue == 0 && colors[0].rgbReserved == 0,
1878 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1879 colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue, colors[0].rgbReserved);
1880 ok(colors[1].rgbRed == 0xff && colors[1].rgbGreen == 0xff &&
1881 colors[1].rgbBlue == 0xff && colors[1].rgbReserved == 0,
1882 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1883 colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue, colors[1].rgbReserved);
1884 for (i = 2; i < 256; i++)
1886 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
1887 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
1888 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1889 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
1892 /* returned bits are DWORD aligned and upside down */
1893 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1895 /* Test the palette indices */
1896 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1897 SetLastError(0xdeadbeef);
1898 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1899 ok(((WORD*)colors)[0] == 0, "Color 0 is %d\n", ((WORD*)colors)[0]);
1900 ok(((WORD*)colors)[1] == 1, "Color 1 is %d\n", ((WORD*)colors)[1]);
1901 for (i = 2; i < 256; i++)
1902 ok(((WORD*)colors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)colors)[i]);
1904 /* retrieve 4-bit DIB data */
1905 memset(bi, 0, sizeof(*bi));
1906 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1907 bi->bmiHeader.biWidth = bm.bmWidth;
1908 bi->bmiHeader.biHeight = bm.bmHeight;
1909 bi->bmiHeader.biPlanes = 1;
1910 bi->bmiHeader.biBitCount = 4;
1911 bi->bmiHeader.biCompression = BI_RGB;
1912 bi->bmiHeader.biSizeImage = 0;
1913 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1914 memset(buf, 0xAA, sizeof(buf));
1915 SetLastError(0xdeadbeef);
1916 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1917 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1918 lines, bm.bmHeight, GetLastError());
1920 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
1922 for (i = 0; i < 16; i++)
1925 int entry = i < 8 ? i : i + 4;
1927 if(entry == 7) entry = 12;
1928 else if(entry == 12) entry = 7;
1930 expect.rgbRed = pal_ents[entry].peRed;
1931 expect.rgbGreen = pal_ents[entry].peGreen;
1932 expect.rgbBlue = pal_ents[entry].peBlue;
1933 expect.rgbReserved = 0;
1935 ok(!memcmp(colors + i, &expect, sizeof(expect)),
1936 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
1937 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
1938 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
1941 /* retrieve 8-bit DIB data */
1942 memset(bi, 0, sizeof(*bi));
1943 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1944 bi->bmiHeader.biWidth = bm.bmWidth;
1945 bi->bmiHeader.biHeight = bm.bmHeight;
1946 bi->bmiHeader.biPlanes = 1;
1947 bi->bmiHeader.biBitCount = 8;
1948 bi->bmiHeader.biCompression = BI_RGB;
1949 bi->bmiHeader.biSizeImage = 0;
1950 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1951 memset(buf, 0xAA, sizeof(buf));
1952 SetLastError(0xdeadbeef);
1953 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1954 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1955 lines, bm.bmHeight, GetLastError());
1957 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
1959 for (i = 0; i < 256; i++)
1963 if (i < 10 || i >= 246)
1965 int entry = i < 10 ? i : i - 236;
1966 expect.rgbRed = pal_ents[entry].peRed;
1967 expect.rgbGreen = pal_ents[entry].peGreen;
1968 expect.rgbBlue = pal_ents[entry].peBlue;
1972 expect.rgbRed = (i & 0x07) << 5;
1973 expect.rgbGreen = (i & 0x38) << 2;
1974 expect.rgbBlue = i & 0xc0;
1976 expect.rgbReserved = 0;
1978 ok(!memcmp(colors + i, &expect, sizeof(expect)),
1979 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
1980 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
1981 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
1984 /* retrieve 24-bit DIB data */
1985 memset(bi, 0, sizeof(*bi));
1986 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1987 bi->bmiHeader.biWidth = bm.bmWidth;
1988 bi->bmiHeader.biHeight = bm.bmHeight;
1989 bi->bmiHeader.biPlanes = 1;
1990 bi->bmiHeader.biBitCount = 24;
1991 bi->bmiHeader.biCompression = BI_RGB;
1992 bi->bmiHeader.biSizeImage = 0;
1993 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1994 memset(buf, 0xAA, sizeof(buf));
1995 SetLastError(0xdeadbeef);
1996 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1997 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1998 lines, bm.bmHeight, GetLastError());
1999 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2001 /* the color table doesn't exist for 24-bit images */
2002 for (i = 0; i < 256; i++)
2004 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2005 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2006 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2007 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2010 /* returned bits are DWORD aligned and upside down */
2011 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2017 static void test_GetDIBits_BI_BITFIELDS(void)
2019 /* Try a screen resolution detection technique
2020 * from the September 1999 issue of Windows Developer's Journal
2021 * which seems to be in widespread use.
2022 * http://www.lesher.ws/highcolor.html
2023 * http://www.lesher.ws/vidfmt.c
2024 * It hinges on being able to retrieve the bitmaps
2025 * for the three primary colors in non-paletted 16 bit mode.
2027 char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
2029 LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
2030 DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
2036 memset(dibinfo, 0, sizeof(dibinfo_buf));
2037 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2040 ok(hdc != NULL, "GetDC failed?\n");
2041 hbm = CreateCompatibleBitmap(hdc, 1, 1);
2042 ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
2044 /* Call GetDIBits to fill in bmiHeader. */
2045 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2046 ok(ret == 1, "GetDIBits failed\n");
2047 if (dibinfo->bmiHeader.biBitCount > 8)
2049 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2050 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2051 "compression is %u (%d bpp)\n", dibinfo->bmiHeader.biCompression, dibinfo->bmiHeader.biBitCount );
2053 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2055 ok( !bitmasks[0], "red mask is set\n" );
2056 ok( !bitmasks[1], "green mask is set\n" );
2057 ok( !bitmasks[2], "blue mask is set\n" );
2059 /* test with NULL bits pointer and correct bpp */
2060 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2061 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2062 ok(ret == 1, "GetDIBits failed\n");
2064 ok( bitmasks[0] != 0, "red mask is not set\n" );
2065 ok( bitmasks[1] != 0, "green mask is not set\n" );
2066 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2067 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2069 /* test with valid bits pointer */
2070 memset(dibinfo, 0, sizeof(dibinfo_buf));
2071 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2072 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2073 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2074 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2075 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2076 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2078 ok( bitmasks[0] != 0, "red mask is not set\n" );
2079 ok( bitmasks[1] != 0, "green mask is not set\n" );
2080 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2081 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2083 /* now with bits and 0 lines */
2084 memset(dibinfo, 0, sizeof(dibinfo_buf));
2085 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2086 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2087 SetLastError(0xdeadbeef);
2088 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2089 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2091 ok( !bitmasks[0], "red mask is set\n" );
2092 ok( !bitmasks[1], "green mask is set\n" );
2093 ok( !bitmasks[2], "blue mask is set\n" );
2094 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2096 memset(bitmasks, 0, 3*sizeof(DWORD));
2097 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2098 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2099 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2101 ok( bitmasks[0] != 0, "red mask is not set\n" );
2102 ok( bitmasks[1] != 0, "green mask is not set\n" );
2103 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2104 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2107 else skip("bitmap in colortable mode, skipping BI_BITFIELDS tests\n");
2111 /* same thing now with a 32-bpp DIB section */
2113 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2114 dibinfo->bmiHeader.biWidth = 1;
2115 dibinfo->bmiHeader.biHeight = 1;
2116 dibinfo->bmiHeader.biPlanes = 1;
2117 dibinfo->bmiHeader.biBitCount = 32;
2118 dibinfo->bmiHeader.biCompression = BI_RGB;
2119 dibinfo->bmiHeader.biSizeImage = 0;
2120 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2121 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2122 dibinfo->bmiHeader.biClrUsed = 0;
2123 dibinfo->bmiHeader.biClrImportant = 0;
2124 bitmasks[0] = 0x0000ff;
2125 bitmasks[1] = 0x00ff00;
2126 bitmasks[2] = 0xff0000;
2127 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2128 ok( hbm != 0, "failed to create bitmap\n" );
2130 memset(dibinfo, 0, sizeof(dibinfo_buf));
2131 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2132 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2133 ok(ret == 1, "GetDIBits failed\n");
2134 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2136 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2137 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2138 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2139 ok( !bitmasks[0], "red mask is set\n" );
2140 ok( !bitmasks[1], "green mask is set\n" );
2141 ok( !bitmasks[2], "blue mask is set\n" );
2143 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2144 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2145 ok(ret == 1, "GetDIBits failed\n");
2146 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2147 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2148 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2149 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2150 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2152 ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
2153 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2154 ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
2156 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2160 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2161 dibinfo->bmiHeader.biWidth = 1;
2162 dibinfo->bmiHeader.biHeight = 1;
2163 dibinfo->bmiHeader.biPlanes = 1;
2164 dibinfo->bmiHeader.biBitCount = 32;
2165 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2166 dibinfo->bmiHeader.biSizeImage = 0;
2167 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2168 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2169 dibinfo->bmiHeader.biClrUsed = 0;
2170 dibinfo->bmiHeader.biClrImportant = 0;
2171 bitmasks[0] = 0x0000ff;
2172 bitmasks[1] = 0x00ff00;
2173 bitmasks[2] = 0xff0000;
2174 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2175 ok( hbm != 0, "failed to create bitmap\n" );
2179 memset(dibinfo, 0, sizeof(dibinfo_buf));
2180 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2181 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2182 ok(ret == 1, "GetDIBits failed\n");
2184 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
2185 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2186 ok( !bitmasks[0], "red mask is set\n" );
2187 ok( !bitmasks[1], "green mask is set\n" );
2188 ok( !bitmasks[2], "blue mask is set\n" );
2190 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2191 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2192 ok(ret == 1, "GetDIBits failed\n");
2193 ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
2194 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2195 ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
2196 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2201 /* 24-bpp DIB sections don't have bitfields */
2203 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2204 dibinfo->bmiHeader.biWidth = 1;
2205 dibinfo->bmiHeader.biHeight = 1;
2206 dibinfo->bmiHeader.biPlanes = 1;
2207 dibinfo->bmiHeader.biBitCount = 24;
2208 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2209 dibinfo->bmiHeader.biSizeImage = 0;
2210 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2211 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2212 dibinfo->bmiHeader.biClrUsed = 0;
2213 dibinfo->bmiHeader.biClrImportant = 0;
2214 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2215 ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
2216 dibinfo->bmiHeader.biCompression = BI_RGB;
2217 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2218 ok( hbm != 0, "failed to create bitmap\n" );
2220 memset(dibinfo, 0, sizeof(dibinfo_buf));
2221 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2222 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2223 ok(ret == 1, "GetDIBits failed\n");
2224 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2226 ok( dibinfo->bmiHeader.biCompression == BI_RGB,
2227 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2228 ok( !bitmasks[0], "red mask is set\n" );
2229 ok( !bitmasks[1], "green mask is set\n" );
2230 ok( !bitmasks[2], "blue mask is set\n" );
2232 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2233 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2234 ok(ret == 1, "GetDIBits failed\n");
2235 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2236 ok( !bitmasks[0], "red mask is set\n" );
2237 ok( !bitmasks[1], "green mask is set\n" );
2238 ok( !bitmasks[2], "blue mask is set\n" );
2239 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2242 ReleaseDC(NULL, hdc);
2245 static void test_select_object(void)
2248 HBITMAP hbm, hbm_old;
2250 DWORD depths[] = {8, 15, 16, 24, 32};
2255 ok(hdc != 0, "GetDC(0) failed\n");
2256 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2257 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2259 hbm_old = SelectObject(hdc, hbm);
2260 ok(hbm_old == 0, "SelectObject should fail\n");
2265 hdc = CreateCompatibleDC(0);
2266 ok(hdc != 0, "GetDC(0) failed\n");
2267 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2268 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2270 hbm_old = SelectObject(hdc, hbm);
2271 ok(hbm_old != 0, "SelectObject failed\n");
2272 hbm_old = SelectObject(hdc, hbm_old);
2273 ok(hbm_old == hbm, "SelectObject failed\n");
2277 /* test an 1-bpp bitmap */
2278 planes = GetDeviceCaps(hdc, PLANES);
2281 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
2282 ok(hbm != 0, "CreateBitmap failed\n");
2284 hbm_old = SelectObject(hdc, hbm);
2285 ok(hbm_old != 0, "SelectObject failed\n");
2286 hbm_old = SelectObject(hdc, hbm_old);
2287 ok(hbm_old == hbm, "SelectObject failed\n");
2291 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
2292 /* test a color bitmap to dc bpp matching */
2293 planes = GetDeviceCaps(hdc, PLANES);
2294 bpp = GetDeviceCaps(hdc, BITSPIXEL);
2296 hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
2297 ok(hbm != 0, "CreateBitmap failed\n");
2299 hbm_old = SelectObject(hdc, hbm);
2300 if(depths[i] == bpp ||
2301 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
2303 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
2304 SelectObject(hdc, hbm_old);
2306 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
2309 memset(&bm, 0xAA, sizeof(bm));
2310 bytes = GetObject(hbm, sizeof(bm), &bm);
2311 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2312 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2313 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
2314 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
2315 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2316 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
2317 if(depths[i] == 15) {
2318 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
2320 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2322 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2330 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
2335 ret = GetObjectType(hbmp);
2336 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
2338 ret = GetObject(hbmp, 0, 0);
2339 ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
2341 memset(&bm, 0xDA, sizeof(bm));
2342 SetLastError(0xdeadbeef);
2343 ret = GetObject(hbmp, sizeof(bm), &bm);
2344 if (!ret) /* XP, only for curObj2 */ return;
2345 ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
2346 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2347 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2348 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2349 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2350 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2351 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2352 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2355 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2357 static void test_CreateBitmap(void)
2360 HDC screenDC = GetDC(0);
2361 HDC hdc = CreateCompatibleDC(screenDC);
2364 /* all of these are the stock monochrome bitmap */
2365 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2366 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2367 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2368 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2369 HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2370 HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2372 /* these 2 are not the stock monochrome bitmap */
2373 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2374 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2376 HBITMAP old1 = SelectObject(hdc, bm2);
2377 HBITMAP old2 = SelectObject(screenDC, bm3);
2378 SelectObject(hdc, old1);
2379 SelectObject(screenDC, old2);
2381 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2382 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2383 bm, bm1, bm4, bm5, curObj1, old1);
2384 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2386 ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
2387 ok(old2 == 0, "old2 %p\n", old2);
2389 test_mono_1x1_bmp(bm);
2390 test_mono_1x1_bmp(bm1);
2391 test_mono_1x1_bmp(bm2);
2392 test_mono_1x1_bmp(bm3);
2393 test_mono_1x1_bmp(bm4);
2394 test_mono_1x1_bmp(bm5);
2395 test_mono_1x1_bmp(old1);
2396 test_mono_1x1_bmp(curObj1);
2406 ReleaseDC(0, screenDC);
2408 /* show that Windows ignores the provided bm.bmWidthBytes */
2412 bmp.bmWidthBytes = 28;
2414 bmp.bmBitsPixel = 1;
2416 bm = CreateBitmapIndirect(&bmp);
2417 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2418 test_mono_1x1_bmp(bm);
2421 /* Test how the bmBitsPixel field is treated */
2422 for(i = 1; i <= 33; i++) {
2426 bmp.bmWidthBytes = 28;
2428 bmp.bmBitsPixel = i;
2430 SetLastError(0xdeadbeef);
2431 bm = CreateBitmapIndirect(&bmp);
2433 DWORD error = GetLastError();
2434 ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
2435 ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2439 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2440 GetObject(bm, sizeof(bmp), &bmp);
2447 } else if(i <= 16) {
2449 } else if(i <= 24) {
2451 } else if(i <= 32) {
2454 ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2455 i, bmp.bmBitsPixel, expect);
2460 static void test_bitmapinfoheadersize(void)
2467 memset(&bmi, 0, sizeof(BITMAPINFO));
2468 bmi.bmiHeader.biHeight = 100;
2469 bmi.bmiHeader.biWidth = 512;
2470 bmi.bmiHeader.biBitCount = 24;
2471 bmi.bmiHeader.biPlanes = 1;
2473 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2475 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2476 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2478 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2480 SetLastError(0xdeadbeef);
2481 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2482 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2485 bmi.bmiHeader.biSize++;
2487 SetLastError(0xdeadbeef);
2488 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2490 broken(!hdib), /* Win98, WinMe */
2491 "CreateDIBSection error %d\n", GetLastError());
2494 bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2496 SetLastError(0xdeadbeef);
2497 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2499 broken(!hdib), /* Win98, WinMe */
2500 "CreateDIBSection error %d\n", GetLastError());
2503 bmi.bmiHeader.biSize++;
2505 SetLastError(0xdeadbeef);
2506 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2508 broken(!hdib), /* Win98, WinMe */
2509 "CreateDIBSection error %d\n", GetLastError());
2512 bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2514 SetLastError(0xdeadbeef);
2515 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2516 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2519 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2521 SetLastError(0xdeadbeef);
2522 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2524 broken(!hdib), /* Win95 */
2525 "CreateDIBSection error %d\n", GetLastError());
2528 memset(&bci, 0, sizeof(BITMAPCOREINFO));
2529 bci.bmciHeader.bcHeight = 100;
2530 bci.bmciHeader.bcWidth = 512;
2531 bci.bmciHeader.bcBitCount = 24;
2532 bci.bmciHeader.bcPlanes = 1;
2534 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2536 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2537 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2539 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2541 SetLastError(0xdeadbeef);
2542 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2543 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2546 bci.bmciHeader.bcSize++;
2548 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2549 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2551 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2553 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2554 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2559 static void test_get16dibits(void)
2561 BYTE bits[4 * (16 / sizeof(BYTE))];
2563 HDC screen_dc = GetDC(NULL);
2566 int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2568 int overwritten_bytes = 0;
2570 memset(bits, 0, sizeof(bits));
2571 hbmp = CreateBitmap(2, 2, 1, 16, bits);
2572 ok(hbmp != NULL, "CreateBitmap failed\n");
2574 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2577 memset(info, '!', info_len);
2578 memset(info, 0, sizeof(info->bmiHeader));
2580 info->bmiHeader.biSize = sizeof(info->bmiHeader);
2581 info->bmiHeader.biWidth = 2;
2582 info->bmiHeader.biHeight = 2;
2583 info->bmiHeader.biPlanes = 1;
2584 info->bmiHeader.biCompression = BI_RGB;
2586 ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2587 ok(ret != 0, "GetDIBits failed got %d\n", ret);
2589 for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2591 overwritten_bytes++;
2592 ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2594 HeapFree(GetProcessHeap(), 0, info);
2596 ReleaseDC(NULL, screen_dc);
2599 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2600 DWORD dwRop, UINT32 expected, int line)
2602 *srcBuffer = 0xFEDCBA98;
2603 *dstBuffer = 0x89ABCDEF;
2604 Rectangle(hdcSrc, 0, 0, 1, 1); /* A null operation to ensure dibs are coerced to X11 */
2605 BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
2606 ok(expected == *dstBuffer,
2607 "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2608 dwRop, expected, *dstBuffer, line);
2611 static void test_BitBlt(void)
2613 HBITMAP bmpDst, bmpSrc;
2614 HBITMAP oldDst, oldSrc;
2615 HDC hdcScreen, hdcDst, hdcSrc;
2616 UINT32 *dstBuffer, *srcBuffer;
2617 HBRUSH hBrush, hOldBrush;
2618 BITMAPINFO bitmapInfo;
2620 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2621 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2622 bitmapInfo.bmiHeader.biWidth = 1;
2623 bitmapInfo.bmiHeader.biHeight = 1;
2624 bitmapInfo.bmiHeader.biPlanes = 1;
2625 bitmapInfo.bmiHeader.biBitCount = 32;
2626 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2627 bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2629 hdcScreen = CreateCompatibleDC(0);
2630 hdcDst = CreateCompatibleDC(hdcScreen);
2631 hdcSrc = CreateCompatibleDC(hdcDst);
2633 /* Setup the destination dib section */
2634 bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
2636 oldDst = SelectObject(hdcDst, bmpDst);
2638 hBrush = CreateSolidBrush(0x012345678);
2639 hOldBrush = SelectObject(hdcDst, hBrush);
2641 /* Setup the source dib section */
2642 bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
2644 oldSrc = SelectObject(hdcSrc, bmpSrc);
2646 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2647 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2648 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2649 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2650 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2651 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2652 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2653 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2654 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2655 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2656 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2657 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2658 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2659 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2660 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2663 SelectObject(hdcSrc, oldSrc);
2664 DeleteObject(bmpSrc);
2667 SelectObject(hdcDst, hOldBrush);
2668 DeleteObject(hBrush);
2669 SelectObject(hdcDst, oldDst);
2670 DeleteObject(bmpDst);
2674 DeleteDC(hdcScreen);
2677 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2678 DWORD dwRop, UINT32 expected, int line)
2680 *srcBuffer = 0xFEDCBA98;
2681 *dstBuffer = 0x89ABCDEF;
2682 StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
2683 ok(expected == *dstBuffer,
2684 "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2685 dwRop, expected, *dstBuffer, line);
2688 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, BITMAPINFO *dst_info, UINT32 *dstBuffer, UINT32 *srcBuffer,
2689 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2690 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2691 UINT32 *expected, int line)
2693 int dst_size = get_dib_image_size( dst_info );
2695 memset(dstBuffer, 0, dst_size);
2696 StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2697 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
2698 ok(memcmp(dstBuffer, expected, dst_size) == 0,
2699 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2700 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2701 expected[0], expected[1], expected[2], expected[3],
2702 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2703 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2704 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2707 static void test_StretchBlt(void)
2709 HBITMAP bmpDst, bmpSrc;
2710 HBITMAP oldDst, oldSrc;
2711 HDC hdcScreen, hdcDst, hdcSrc;
2712 UINT32 *dstBuffer, *srcBuffer;
2713 HBRUSH hBrush, hOldBrush;
2714 BITMAPINFO biDst, biSrc;
2715 UINT32 expected[256];
2718 memset(&biDst, 0, sizeof(BITMAPINFO));
2719 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2720 biDst.bmiHeader.biWidth = 16;
2721 biDst.bmiHeader.biHeight = -16;
2722 biDst.bmiHeader.biPlanes = 1;
2723 biDst.bmiHeader.biBitCount = 32;
2724 biDst.bmiHeader.biCompression = BI_RGB;
2725 memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
2727 hdcScreen = CreateCompatibleDC(0);
2728 hdcDst = CreateCompatibleDC(hdcScreen);
2729 hdcSrc = CreateCompatibleDC(hdcDst);
2732 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2734 oldDst = SelectObject(hdcDst, bmpDst);
2736 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2738 oldSrc = SelectObject(hdcSrc, bmpSrc);
2740 hBrush = CreateSolidBrush(0x012345678);
2741 hOldBrush = SelectObject(hdcDst, hBrush);
2743 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2744 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2745 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2746 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2747 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2748 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2749 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2750 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2751 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2752 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2753 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2754 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2755 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2756 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2757 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2759 SelectObject(hdcDst, hOldBrush);
2760 DeleteObject(hBrush);
2762 /* Top-down to top-down tests */
2763 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2764 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2766 memset( expected, 0, get_dib_image_size( &biDst ) );
2767 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2768 expected[16] = 0xFEDCBA98, expected[17] = 0x76543210;
2769 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2770 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2772 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2773 expected[16] = 0x00000000, expected[17] = 0x00000000;
2774 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2775 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
2777 expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
2778 expected[16] = 0xCAFED00D, expected[17] = 0xCAFED00D;
2779 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2780 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
2782 /* This is an example of the dst width (height) == 1 exception, explored below */
2783 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2784 expected[16] = 0x00000000, expected[17] = 0x00000000;
2785 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2786 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
2788 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2789 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
2790 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2791 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2793 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2794 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
2795 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2796 1, 1, -2, -2, 0, 0, 2, 2, expected, __LINE__);
2798 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2799 expected[16] = 0x00000000, expected[17] = 0x00000000;
2800 todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2801 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
2803 expected[0] = 0x00000000, expected[1] = 0x00000000;
2804 expected[16] = 0x00000000, expected[17] = 0xCAFED00D, expected[18] = 0xFEEDFACE;
2805 expected[32] = 0x00000000, expected[33] = 0xFEDCBA98, expected[34] = 0x76543210;
2807 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2808 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2810 /* when dst width is 1 merge src width - 1 pixels */
2811 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
2812 srcBuffer[0] = 0x0000ff00, srcBuffer[1] = 0x0000f0f0, srcBuffer[2] = 0x0000cccc, srcBuffer[3] = 0x0000aaaa;
2813 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2815 memset( expected, 0, get_dib_image_size( &biDst ) );
2816 expected[0] = srcBuffer[0];
2817 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2818 0, 0, 1, 1, 0, 0, 2, 1, expected, __LINE__);
2820 expected[0] = srcBuffer[0] & srcBuffer[1];
2821 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2822 0, 0, 1, 1, 0, 0, 3, 1, expected, __LINE__);
2824 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
2825 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2826 0, 0, 1, 1, 0, 0, 4, 1, expected, __LINE__);
2828 /* this doesn't happen if the src width is -ve */
2829 expected[0] = srcBuffer[1] & srcBuffer[2];
2830 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2831 0, 0, 1, 1, 2, 0, -2, 1, expected, __LINE__);
2833 /* when dst width > 1 behaviour reverts to what one would expect */
2834 expected[0] = srcBuffer[0] & srcBuffer[1], expected[1] = srcBuffer[2] & srcBuffer[3];
2835 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2836 0, 0, 2, 1, 0, 0, 4, 1, expected, __LINE__);
2838 /* similarly in the vertical direction */
2839 memset( expected, 0, get_dib_image_size( &biDst ) );
2840 expected[0] = srcBuffer[0];
2841 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2842 0, 0, 1, 1, 0, 0, 1, 2, expected, __LINE__);
2844 /* check that it's the dst size in device units that needs to be 1 */
2845 SetMapMode( hdcDst, MM_ISOTROPIC );
2846 SetWindowExtEx( hdcDst, 200, 200, NULL );
2847 SetViewportExtEx( hdcDst, 100, 100, NULL );
2849 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
2850 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2851 0, 0, 2, 2, 0, 0, 4, 1, expected, __LINE__);
2852 SetMapMode( hdcDst, MM_TEXT );
2854 SelectObject(hdcDst, oldDst);
2855 DeleteObject(bmpDst);
2857 /* Top-down to bottom-up tests */
2858 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
2859 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2860 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2862 biDst.bmiHeader.biHeight = 16;
2863 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2865 oldDst = SelectObject(hdcDst, bmpDst);
2867 memset( expected, 0, get_dib_image_size( &biDst ) );
2869 expected[224] = 0xFEDCBA98, expected[225] = 0x76543210;
2870 expected[240] = 0xCAFED00D, expected[241] = 0xFEEDFACE;
2871 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2872 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2874 expected[224] = 0xFEEDFACE, expected[225] = 0xCAFED00D;
2875 expected[240] = 0x76543210, expected[241] = 0xFEDCBA98;
2876 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2877 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2879 SelectObject(hdcSrc, oldSrc);
2880 DeleteObject(bmpSrc);
2882 /* Bottom-up to bottom-up tests */
2883 biSrc.bmiHeader.biHeight = 16;
2884 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2886 srcBuffer[224] = 0xCAFED00D, srcBuffer[225] = 0xFEEDFACE;
2887 srcBuffer[240] = 0xFEDCBA98, srcBuffer[241] = 0x76543210;
2888 oldSrc = SelectObject(hdcSrc, bmpSrc);
2890 memset( expected, 0, get_dib_image_size( &biDst ) );
2892 expected[224] = 0xCAFED00D, expected[225] = 0xFEEDFACE;
2893 expected[240] = 0xFEDCBA98, expected[241] = 0x76543210;
2894 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2895 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2897 expected[224] = 0x76543210, expected[225] = 0xFEDCBA98;
2898 expected[240] = 0xFEEDFACE, expected[241] = 0xCAFED00D;
2899 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2900 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2902 SelectObject(hdcDst, oldDst);
2903 DeleteObject(bmpDst);
2905 /* Bottom-up to top-down tests */
2906 biDst.bmiHeader.biHeight = -16;
2907 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2909 oldDst = SelectObject(hdcDst, bmpDst);
2911 memset( expected, 0, get_dib_image_size( &biDst ) );
2912 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2913 expected[16] = 0xCAFED00D, expected[17] = 0xFEEDFACE;
2914 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2915 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2917 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2918 expected[16] = 0x76543210, expected[17] = 0xFEDCBA98;
2919 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2920 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2922 SelectObject(hdcSrc, oldSrc);
2923 DeleteObject(bmpSrc);
2925 biSrc.bmiHeader.biHeight = -2;
2926 biSrc.bmiHeader.biBitCount = 24;
2927 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
2928 oldSrc = SelectObject(hdcSrc, bmpSrc);
2930 memset( expected, 0, get_dib_image_size( &biDst ) );
2931 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2932 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2933 memcpy(dstBuffer, expected, 4 * sizeof(*dstBuffer));
2934 StretchBlt(hdcSrc, 0, 0, 4, 1, hdcDst, 0, 0, 4, 1, SRCCOPY );
2935 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
2936 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
2937 expected[0] = 0x00EDFACE, expected[1] = 0x00FED00D;
2938 expected[2] = 0x00543210, expected[3] = 0x00DCBA98;
2939 ok(!memcmp(dstBuffer, expected, 16),
2940 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
2941 expected[0], expected[1], expected[2], expected[3],
2942 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
2944 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2945 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2946 memcpy(srcBuffer, expected, 4 * sizeof(*dstBuffer));
2947 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
2948 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
2949 expected[0] = 0x00EDFACE, expected[1] = 0x00D00DFE;
2950 expected[2] = 0x0010CAFE, expected[3] = 0x00765432;
2951 ok(!memcmp(dstBuffer, expected, 16),
2952 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
2953 expected[0], expected[1], expected[2], expected[3],
2954 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
2956 SelectObject(hdcSrc, oldSrc);
2957 DeleteObject(bmpSrc);
2959 biSrc.bmiHeader.biBitCount = 1;
2960 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
2961 oldSrc = SelectObject(hdcSrc, bmpSrc);
2962 *((DWORD *)colors + 0) = 0x123456;
2963 *((DWORD *)colors + 1) = 0x335577;
2964 SetDIBColorTable( hdcSrc, 0, 2, colors );
2965 srcBuffer[0] = 0x55555555;
2966 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
2967 SetTextColor( hdcDst, 0 );
2968 SetBkColor( hdcDst, 0 );
2969 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
2970 expected[0] = expected[2] = 0x00123456;
2971 expected[1] = expected[3] = 0x00335577;
2972 ok(!memcmp(dstBuffer, expected, 16),
2973 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
2974 expected[0], expected[1], expected[2], expected[3],
2975 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
2977 SelectObject(hdcSrc, oldSrc);
2978 DeleteObject(bmpSrc);
2980 bmpSrc = CreateBitmap( 16, 16, 1, 1, 0 );
2981 oldSrc = SelectObject(hdcSrc, bmpSrc);
2982 SetPixel( hdcSrc, 0, 0, 0 );
2983 SetPixel( hdcSrc, 1, 0, 0xffffff );
2984 SetPixel( hdcSrc, 2, 0, 0xffffff );
2985 SetPixel( hdcSrc, 3, 0, 0 );
2986 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
2987 SetTextColor( hdcDst, RGB(0x22,0x44,0x66) );
2988 SetBkColor( hdcDst, RGB(0x65,0x43,0x21) );
2989 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
2990 expected[0] = expected[3] = 0x00224466;
2991 expected[1] = expected[2] = 0x00654321;
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 SelectObject(hdcSrc, oldSrc);
2998 DeleteObject(bmpSrc);
3002 SelectObject(hdcDst, oldDst);
3003 DeleteObject(bmpDst);
3006 DeleteDC(hdcScreen);
3009 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3010 DWORD dwRop, UINT32 expected, int line)
3012 const UINT32 buffer[2] = { 0xFEDCBA98, 0 };
3013 BITMAPINFO bitmapInfo;
3015 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3016 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3017 bitmapInfo.bmiHeader.biWidth = 2;
3018 bitmapInfo.bmiHeader.biHeight = 1;
3019 bitmapInfo.bmiHeader.biPlanes = 1;
3020 bitmapInfo.bmiHeader.biBitCount = 32;
3021 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3022 bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer);
3024 *dstBuffer = 0x89ABCDEF;
3026 StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop);
3027 ok(expected == *dstBuffer,
3028 "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
3029 dwRop, expected, *dstBuffer, line);
3032 static void check_StretchDIBits_stretch(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3033 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
3034 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
3035 UINT32 expected[4], int line)
3037 BITMAPINFO bitmapInfo;
3039 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3040 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3041 bitmapInfo.bmiHeader.biWidth = 2;
3042 bitmapInfo.bmiHeader.biHeight = -2;
3043 bitmapInfo.bmiHeader.biPlanes = 1;
3044 bitmapInfo.bmiHeader.biBitCount = 32;
3045 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3047 memset(dstBuffer, 0, 16);
3048 StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
3049 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3050 srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
3051 ok(memcmp(dstBuffer, expected, 16) == 0,
3052 "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
3053 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
3054 expected[0], expected[1], expected[2], expected[3],
3055 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
3056 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3057 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
3060 static void test_StretchDIBits(void)
3064 HDC hdcScreen, hdcDst;
3065 UINT32 *dstBuffer, srcBuffer[4];
3066 HBRUSH hBrush, hOldBrush;
3070 memset(&biDst, 0, sizeof(BITMAPINFO));
3071 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3072 biDst.bmiHeader.biWidth = 2;
3073 biDst.bmiHeader.biHeight = -2;
3074 biDst.bmiHeader.biPlanes = 1;
3075 biDst.bmiHeader.biBitCount = 32;
3076 biDst.bmiHeader.biCompression = BI_RGB;
3078 hdcScreen = CreateCompatibleDC(0);
3079 hdcDst = CreateCompatibleDC(hdcScreen);
3082 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3084 oldDst = SelectObject(hdcDst, bmpDst);
3086 hBrush = CreateSolidBrush(0x012345678);
3087 hOldBrush = SelectObject(hdcDst, hBrush);
3089 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3090 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3091 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3092 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3093 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3094 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3095 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3096 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3097 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3098 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3099 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3100 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3101 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3102 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3103 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3105 SelectObject(hdcDst, hOldBrush);
3106 DeleteObject(hBrush);
3108 /* Top-down destination tests */
3109 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3110 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
3112 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
3113 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
3114 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3115 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3117 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3118 expected[2] = 0x00000000, expected[3] = 0x00000000;
3119 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3120 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
3122 expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
3123 expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
3124 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3125 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
3127 expected[0] = 0x42441000, expected[1] = 0x00000000;
3128 expected[2] = 0x00000000, expected[3] = 0x00000000;
3129 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3130 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
3132 expected[0] = 0x00000000, expected[1] = 0x00000000;
3133 expected[2] = 0x00000000, expected[3] = 0x00000000;
3134 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3135 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3137 expected[0] = 0x00000000, expected[1] = 0x00000000;
3138 expected[2] = 0x00000000, expected[3] = 0x00000000;
3139 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3140 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3142 expected[0] = 0x00000000, expected[1] = 0x00000000;
3143 expected[2] = 0x00000000, expected[3] = 0x00000000;
3144 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3145 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
3147 expected[0] = 0x00000000, expected[1] = 0x00000000;
3148 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
3149 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3150 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3152 SelectObject(hdcDst, oldDst);
3153 DeleteObject(bmpDst);
3155 /* Bottom up destination tests */
3156 biDst.bmiHeader.biHeight = 2;
3157 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3159 oldDst = SelectObject(hdcDst, bmpDst);
3161 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3162 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
3163 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3164 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3167 SelectObject(hdcDst, oldDst);
3168 DeleteObject(bmpDst);
3171 DeleteDC(hdcScreen);
3174 static void test_GdiAlphaBlend(void)
3186 BLENDFUNCTION blend;
3188 if (!pGdiAlphaBlend)
3190 win_skip("GdiAlphaBlend() is not implemented\n");
3194 hdcNull = GetDC(NULL);
3195 hdcDst = CreateCompatibleDC(hdcNull);
3196 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
3197 hdcSrc = CreateCompatibleDC(hdcNull);
3199 bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3200 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3201 bmi->bmiHeader.biHeight = 20;
3202 bmi->bmiHeader.biWidth = 20;
3203 bmi->bmiHeader.biBitCount = 32;
3204 bmi->bmiHeader.biPlanes = 1;
3205 bmi->bmiHeader.biCompression = BI_RGB;
3206 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3207 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3209 oldDst = SelectObject(hdcDst, bmpDst);
3210 oldSrc = SelectObject(hdcSrc, bmpSrc);
3212 blend.BlendOp = AC_SRC_OVER;
3213 blend.BlendFlags = 0;
3214 blend.SourceConstantAlpha = 128;
3215 blend.AlphaFormat = 0;
3217 SetLastError(0xdeadbeef);
3218 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3219 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3221 SetLastError(0xdeadbeef);
3222 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3223 ok( !ret, "GdiAlphaBlend succeeded\n" );
3224 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3226 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3227 ok( !ret, "GdiAlphaBlend succeeded\n" );
3228 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend);
3229 ok( !ret, "GdiAlphaBlend succeeded\n" );
3230 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3231 ok( !ret, "GdiAlphaBlend succeeded\n" );
3232 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3233 ok( !ret, "GdiAlphaBlend succeeded\n" );
3235 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
3236 SetLastError(0xdeadbeef);
3237 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3238 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3239 SetLastError(0xdeadbeef);
3240 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3241 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3242 SetMapMode(hdcSrc, MM_ANISOTROPIC);
3243 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
3244 SetLastError(0xdeadbeef);
3245 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend);
3246 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3247 SetLastError(0xdeadbeef);
3248 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend);
3249 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3251 SetLastError(0xdeadbeef);
3252 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend);
3253 ok( !ret, "GdiAlphaBlend succeeded\n" );
3254 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3256 /* overlapping source and dest not allowed */
3258 SetLastError(0xdeadbeef);
3259 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 19, 19, 20, 20, blend);
3260 ok( !ret, "GdiAlphaBlend succeeded\n" );
3261 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3263 SetLastError(0xdeadbeef);
3264 ret = pGdiAlphaBlend(hdcDst, 20, 20, 20, 20, hdcDst, 1, 1, 20, 20, blend);
3265 ok( !ret, "GdiAlphaBlend succeeded\n" );
3266 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3268 SetLastError(0xdeadbeef);
3269 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 20, 10, 20, 20, blend);
3270 ok( ret, "GdiAlphaBlend succeeded\n" );
3271 SetLastError(0xdeadbeef);
3272 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 10, 20, 20, 20, blend);
3273 ok( ret, "GdiAlphaBlend succeeded\n" );
3275 /* AC_SRC_ALPHA requires 32-bpp BI_RGB format */
3277 blend.AlphaFormat = AC_SRC_ALPHA;
3278 SetLastError(0xdeadbeef);
3279 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3280 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3282 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3283 ((DWORD *)bmi->bmiColors)[0] = 0xff0000;
3284 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3285 ((DWORD *)bmi->bmiColors)[2] = 0x0000ff;
3286 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3287 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3288 oldSrc = SelectObject(hdcSrc, bmpSrc);
3289 DeleteObject( oldSrc );
3291 SetLastError(0xdeadbeef);
3292 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3293 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3295 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3296 ((DWORD *)bmi->bmiColors)[0] = 0x0000ff;
3297 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3298 ((DWORD *)bmi->bmiColors)[2] = 0xff0000;
3299 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3300 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3301 oldSrc = SelectObject(hdcSrc, bmpSrc);
3302 DeleteObject( oldSrc );
3304 SetLastError(0xdeadbeef);
3305 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3306 ok( !ret, "GdiAlphaBlend succeeded\n" );
3307 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3309 bmi->bmiHeader.biBitCount = 24;
3310 bmi->bmiHeader.biCompression = BI_RGB;
3311 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3312 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3313 oldSrc = SelectObject(hdcSrc, bmpSrc);
3314 DeleteObject( oldSrc );
3316 SetLastError(0xdeadbeef);
3317 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3318 ok( !ret, "GdiAlphaBlend succeeded\n" );
3319 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3321 bmi->bmiHeader.biBitCount = 1;
3322 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3323 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3324 oldSrc = SelectObject(hdcSrc, bmpSrc);
3325 DeleteObject( oldSrc );
3327 SetLastError(0xdeadbeef);
3328 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3329 ok( !ret, "GdiAlphaBlend succeeded\n" );
3330 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3332 bmpSrc = CreateBitmap( 100, 100, 1, 1, NULL );
3333 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3334 oldSrc = SelectObject(hdcSrc, bmpSrc);
3335 DeleteObject( oldSrc );
3337 SetLastError(0xdeadbeef);
3338 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3339 ok( !ret, "GdiAlphaBlend succeeded\n" );
3340 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3342 SelectObject(hdcDst, oldDst);
3343 SelectObject(hdcSrc, oldSrc);
3344 DeleteObject(bmpSrc);
3345 DeleteObject(bmpDst);
3349 ReleaseDC(NULL, hdcNull);
3353 static void test_clipping(void)
3361 HDC hdcDst = CreateCompatibleDC( NULL );
3362 HDC hdcSrc = CreateCompatibleDC( NULL );
3364 BITMAPINFO bmpinfo={{0}};
3365 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3366 bmpinfo.bmiHeader.biWidth = 100;
3367 bmpinfo.bmiHeader.biHeight = 100;
3368 bmpinfo.bmiHeader.biPlanes = 1;
3369 bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3370 bmpinfo.bmiHeader.biCompression = BI_RGB;
3372 bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3373 ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3374 SelectObject( hdcDst, bmpDst );
3376 bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3377 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3378 SelectObject( hdcSrc, bmpSrc );
3380 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3381 ok(result, "BitBlt failed\n");
3383 hRgn = CreateRectRgn( 0,0,0,0 );
3384 SelectClipRgn( hdcDst, hRgn );
3386 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3387 ok(result, "BitBlt failed\n");
3389 DeleteObject( bmpDst );
3390 DeleteObject( bmpSrc );
3391 DeleteObject( hRgn );
3396 static void test_32bit_bitmap_blt(void)
3399 HBITMAP bmpSrc, bmpDst;
3400 HBITMAP oldSrc, oldDst;
3401 HDC hdcSrc, hdcDst, hdcScreen;
3403 DWORD colorSrc = 0x11223344;
3405 memset(&biDst, 0, sizeof(BITMAPINFO));
3406 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3407 biDst.bmiHeader.biWidth = 2;
3408 biDst.bmiHeader.biHeight = -2;
3409 biDst.bmiHeader.biPlanes = 1;
3410 biDst.bmiHeader.biBitCount = 32;
3411 biDst.bmiHeader.biCompression = BI_RGB;
3413 hdcScreen = CreateCompatibleDC(0);
3414 if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3416 DeleteDC(hdcScreen);
3417 trace("Skipping 32-bit DDB test\n");
3421 hdcSrc = CreateCompatibleDC(hdcScreen);
3422 bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3423 oldSrc = SelectObject(hdcSrc, bmpSrc);
3425 hdcDst = CreateCompatibleDC(hdcScreen);
3426 bmpDst = CreateDIBSection(hdcDst, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3427 oldDst = SelectObject(hdcDst, bmpDst);
3429 StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3430 ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3433 SelectObject(hdcDst, oldDst);
3434 DeleteObject(bmpDst);
3437 SelectObject(hdcSrc, oldSrc);
3438 DeleteObject(bmpSrc);
3441 DeleteDC(hdcScreen);
3445 * Used by test_GetDIBits_top_down to create the bitmap to test against.
3447 static void setup_picture(char *picture, int bpp)
3455 /*Set the first byte in each pixel to the index of that pixel.*/
3456 for (i = 0; i < 4; i++)
3457 picture[i * (bpp / 8)] = i;
3462 /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
3469 static void test_GetDIBits_top_down(int bpp)
3472 HBITMAP bmptb, bmpbt;
3478 memset( &bi, 0, sizeof(bi) );
3479 bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
3480 bi.bmiHeader.biWidth=2;
3481 bi.bmiHeader.biHeight=2;
3482 bi.bmiHeader.biPlanes=1;
3483 bi.bmiHeader.biBitCount=bpp;
3484 bi.bmiHeader.biCompression=BI_RGB;
3486 /*Get the device context for the screen.*/
3488 ok(hdc != NULL, "Could not get a handle to a device context.\n");
3490 /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
3491 bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3492 ok(bmpbt != NULL, "Could not create a DIB section.\n");
3493 /*Now that we have a pointer to the pixels, we write to them.*/
3494 setup_picture((char*)picture, bpp);
3495 /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
3496 bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
3497 bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3498 ok(bmptb != NULL, "Could not create a DIB section.\n");
3499 /*Write to this top to bottom bitmap.*/
3500 setup_picture((char*)picture, bpp);
3502 bi.bmiHeader.biWidth = 1;
3504 bi.bmiHeader.biHeight = 2;
3505 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3506 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3507 /*Check the first byte of the pixel.*/
3508 ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3509 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3510 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3511 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3512 /*Check second scanline.*/
3513 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3514 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3515 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3516 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3517 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3518 ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3519 /*Check both scanlines.*/
3520 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3521 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3522 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3523 ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3524 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3525 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3526 ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3527 ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3529 /*Make destination bitmap top-down.*/
3530 bi.bmiHeader.biHeight = -2;
3531 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3532 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3533 ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3534 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3535 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3536 ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3537 /*Check second scanline.*/
3538 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3539 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3540 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3541 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3542 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3543 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3544 /*Check both scanlines.*/
3545 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3546 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3547 ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3548 ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3549 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3550 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3551 ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3552 ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3554 DeleteObject(bmpbt);
3555 DeleteObject(bmptb);
3558 static void test_GetSetDIBits_rtl(void)
3561 HBITMAP bitmap, orig_bitmap;
3564 DWORD bits_1[8 * 8], bits_2[8 * 8];
3568 win_skip("Don't have SetLayout\n");
3572 hdc = GetDC( NULL );
3573 hdc_mem = CreateCompatibleDC( hdc );
3574 pSetLayout( hdc_mem, LAYOUT_LTR );
3576 bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
3577 orig_bitmap = SelectObject( hdc_mem, bitmap );
3578 SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
3579 SelectObject( hdc_mem, orig_bitmap );
3581 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3582 info.bmiHeader.biWidth = 8;
3583 info.bmiHeader.biHeight = 8;
3584 info.bmiHeader.biPlanes = 1;
3585 info.bmiHeader.biBitCount = 32;
3586 info.bmiHeader.biCompression = BI_RGB;
3588 /* First show that GetDIBits ignores the layout mode. */
3590 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3591 ok(ret == 8, "got %d\n", ret);
3592 ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
3594 pSetLayout( hdc_mem, LAYOUT_RTL );
3596 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3597 ok(ret == 8, "got %d\n", ret);
3599 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3601 /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
3602 followed by a GetDIBits and show that the bits remain unchanged. */
3604 pSetLayout( hdc_mem, LAYOUT_LTR );
3606 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3607 ok(ret == 8, "got %d\n", ret);
3608 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3609 ok(ret == 8, "got %d\n", ret);
3610 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3612 pSetLayout( hdc_mem, LAYOUT_RTL );
3614 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3615 ok(ret == 8, "got %d\n", ret);
3616 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3617 ok(ret == 8, "got %d\n", ret);
3618 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3620 DeleteObject( bitmap );
3621 DeleteDC( hdc_mem );
3622 ReleaseDC( NULL, hdc );
3625 static void test_GetDIBits_scanlines(void)
3629 HDC hdc = GetDC( NULL );
3631 DWORD data[128], inverted_bits[64];
3634 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
3636 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3637 info->bmiHeader.biWidth = 8;
3638 info->bmiHeader.biHeight = 8;
3639 info->bmiHeader.biPlanes = 1;
3640 info->bmiHeader.biBitCount = 32;
3641 info->bmiHeader.biCompression = BI_RGB;
3643 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3645 for (i = 0; i < 64; i++)
3648 inverted_bits[56 - (i & ~7) + (i & 7)] = i;
3653 memset( data, 0xaa, sizeof(data) );
3655 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3656 ok( ret == 8, "got %d\n", ret );
3657 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3658 memset( data, 0xaa, sizeof(data) );
3660 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3661 ok( ret == 5, "got %d\n", ret );
3662 ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
3663 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3664 memset( data, 0xaa, sizeof(data) );
3666 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3667 ok( ret == 7, "got %d\n", ret );
3668 ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
3669 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3670 memset( data, 0xaa, sizeof(data) );
3672 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3673 ok( ret == 1, "got %d\n", ret );
3674 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3675 memset( data, 0xaa, sizeof(data) );
3677 info->bmiHeader.biHeight = 16;
3678 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3679 ok( ret == 5, "got %d\n", ret );
3680 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3681 ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
3682 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3683 memset( data, 0xaa, sizeof(data) );
3685 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3686 ok( ret == 6, "got %d\n", ret );
3687 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3688 ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
3689 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3690 memset( data, 0xaa, sizeof(data) );
3692 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3693 ok( ret == 0, "got %d\n", ret );
3694 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3695 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3696 memset( data, 0xaa, sizeof(data) );
3698 info->bmiHeader.biHeight = 5;
3699 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3700 ok( ret == 2, "got %d\n", ret );
3701 ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
3702 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3703 memset( data, 0xaa, sizeof(data) );
3707 info->bmiHeader.biHeight = -8;
3708 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3709 ok( ret == 8, "got %d\n", ret );
3710 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3711 memset( data, 0xaa, sizeof(data) );
3713 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3714 ok( ret == 5, "got %d\n", ret );
3715 ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
3716 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3717 memset( data, 0xaa, sizeof(data) );
3719 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3720 ok( ret == 7, "got %d\n", ret );
3721 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3722 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3723 memset( data, 0xaa, sizeof(data) );
3725 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3726 ok( ret == 4, "got %d\n", ret );
3727 ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
3728 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3729 memset( data, 0xaa, sizeof(data) );
3731 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3732 ok( ret == 5, "got %d\n", ret );
3733 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3734 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3735 memset( data, 0xaa, sizeof(data) );
3737 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3738 ok( ret == 5, "got %d\n", ret );
3739 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3740 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3741 memset( data, 0xaa, sizeof(data) );
3743 info->bmiHeader.biHeight = -16;
3744 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3745 ok( ret == 8, "got %d\n", ret );
3746 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3747 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3748 memset( data, 0xaa, sizeof(data) );
3750 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3751 ok( ret == 5, "got %d\n", ret );
3752 ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
3753 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3754 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3755 memset( data, 0xaa, sizeof(data) );
3757 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3758 ok( ret == 8, "got %d\n", ret );
3759 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3760 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3761 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3762 memset( data, 0xaa, sizeof(data) );
3764 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3765 ok( ret == 8, "got %d\n", ret );
3766 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3767 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3768 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3769 memset( data, 0xaa, sizeof(data) );
3771 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3772 ok( ret == 7, "got %d\n", ret );
3773 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3774 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3775 memset( data, 0xaa, sizeof(data) );
3777 ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
3778 ok( ret == 1, "got %d\n", ret );
3779 for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3780 memset( data, 0xaa, sizeof(data) );
3782 info->bmiHeader.biHeight = -5;
3783 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3784 ok( ret == 2, "got %d\n", ret );
3785 ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
3786 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3787 memset( data, 0xaa, sizeof(data) );
3789 DeleteObject( dib );
3791 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3792 info->bmiHeader.biWidth = 8;
3793 info->bmiHeader.biHeight = -8;
3794 info->bmiHeader.biPlanes = 1;
3795 info->bmiHeader.biBitCount = 32;
3796 info->bmiHeader.biCompression = BI_RGB;
3798 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3800 for (i = 0; i < 64; i++) dib_bits[i] = i;
3804 info->bmiHeader.biHeight = -8;
3805 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3806 ok( ret == 8, "got %d\n", ret );
3807 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3808 memset( data, 0xaa, sizeof(data) );
3810 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3811 ok( ret == 5, "got %d\n", ret );
3812 ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
3813 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3814 memset( data, 0xaa, sizeof(data) );
3816 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3817 ok( ret == 7, "got %d\n", ret );
3818 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3819 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3820 memset( data, 0xaa, sizeof(data) );
3822 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3823 ok( ret == 4, "got %d\n", ret );
3824 ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
3825 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3826 memset( data, 0xaa, sizeof(data) );
3828 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3829 ok( ret == 5, "got %d\n", ret );
3830 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3831 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3832 memset( data, 0xaa, sizeof(data) );
3834 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3835 ok( ret == 5, "got %d\n", ret );
3836 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3837 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3838 memset( data, 0xaa, sizeof(data) );
3840 info->bmiHeader.biHeight = -16;
3841 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3842 ok( ret == 8, "got %d\n", ret );
3843 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3844 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3845 memset( data, 0xaa, sizeof(data) );
3847 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3848 ok( ret == 5, "got %d\n", ret );
3849 ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
3850 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3851 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3852 memset( data, 0xaa, sizeof(data) );
3854 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3855 ok( ret == 8, "got %d\n", ret );
3856 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3857 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3858 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3859 memset( data, 0xaa, sizeof(data) );
3861 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3862 ok( ret == 8, "got %d\n", ret );
3863 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3864 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3865 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3866 memset( data, 0xaa, sizeof(data) );
3868 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3869 ok( ret == 7, "got %d\n", ret );
3870 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3871 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3872 memset( data, 0xaa, sizeof(data) );
3874 info->bmiHeader.biHeight = -5;
3875 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3876 ok( ret == 2, "got %d\n", ret );
3877 ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
3878 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3879 memset( data, 0xaa, sizeof(data) );
3884 info->bmiHeader.biHeight = 8;
3886 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3887 ok( ret == 8, "got %d\n", ret );
3888 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3889 memset( data, 0xaa, sizeof(data) );
3891 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3892 ok( ret == 5, "got %d\n", ret );
3893 ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
3894 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3895 memset( data, 0xaa, sizeof(data) );
3897 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3898 ok( ret == 7, "got %d\n", ret );
3899 ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
3900 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3901 memset( data, 0xaa, sizeof(data) );
3903 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3904 ok( ret == 1, "got %d\n", ret );
3905 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3906 memset( data, 0xaa, sizeof(data) );
3908 info->bmiHeader.biHeight = 16;
3909 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3910 ok( ret == 5, "got %d\n", ret );
3911 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3912 ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
3913 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3914 memset( data, 0xaa, sizeof(data) );
3916 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3917 ok( ret == 6, "got %d\n", ret );
3918 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3919 ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
3920 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3921 memset( data, 0xaa, sizeof(data) );
3923 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3924 ok( ret == 0, "got %d\n", ret );
3925 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3926 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3927 memset( data, 0xaa, sizeof(data) );
3929 info->bmiHeader.biHeight = 5;
3930 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3931 ok( ret == 2, "got %d\n", ret );
3932 ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
3933 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3934 memset( data, 0xaa, sizeof(data) );
3936 DeleteObject( dib );
3938 ReleaseDC( NULL, hdc );
3939 HeapFree( GetProcessHeap(), 0, info );
3943 static void test_SetDIBits(void)
3947 HDC hdc = GetDC( NULL );
3948 DWORD data[128], inverted_data[128];
3952 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
3954 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3955 info->bmiHeader.biWidth = 8;
3956 info->bmiHeader.biHeight = 8;
3957 info->bmiHeader.biPlanes = 1;
3958 info->bmiHeader.biBitCount = 32;
3959 info->bmiHeader.biCompression = BI_RGB;
3961 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3962 memset( dib_bits, 0xaa, 64 * 4 );
3964 for (i = 0; i < 128; i++)
3967 inverted_data[120 - (i & ~7) + (i & 7)] = i;
3972 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3973 ok( ret == 8, "got %d\n", ret );
3974 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
3975 memset( dib_bits, 0xaa, 64 * 4 );
3977 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3978 ok( ret == 5, "got %d\n", ret );
3979 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3980 ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
3981 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3982 memset( dib_bits, 0xaa, 64 * 4 );
3984 /* top of dst is aligned with startscans down for the top of the src.
3985 Then starting from the bottom of src, lines rows are copied across. */
3987 info->bmiHeader.biHeight = 16;
3988 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3989 ok( ret == 12, "got %d\n", ret );
3990 ok( !memcmp( dib_bits, data + 56, 40 * 4 ), "bits differ\n");
3991 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3992 memset( dib_bits, 0xaa, 64 * 4 );
3994 info->bmiHeader.biHeight = 5;
3995 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3996 ok( ret == 2, "got %d\n", ret );
3997 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3998 ok( !memcmp( dib_bits + 32, data, 16 * 4 ), "bits differ\n");
3999 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4000 memset( dib_bits, 0xaa, 64 * 4 );
4003 info->bmiHeader.biHeight = -8;
4004 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4005 ok( ret == 8, "got %d\n", ret );
4006 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4007 memset( dib_bits, 0xaa, 64 * 4 );
4009 /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
4010 we copy lines rows from the top of the src */
4012 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4013 ok( ret == 5, "got %d\n", ret );
4014 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4015 ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
4016 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4017 memset( dib_bits, 0xaa, 64 * 4 );
4019 info->bmiHeader.biHeight = -16;
4020 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4021 ok( ret == 12, "got %d\n", ret );
4022 ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
4023 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4024 memset( dib_bits, 0xaa, 64 * 4 );
4026 ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4027 ok( ret == 12, "got %d\n", ret );
4028 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4029 memset( dib_bits, 0xaa, 64 * 4 );
4031 ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4032 ok( ret == 12, "got %d\n", ret );
4033 ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
4034 memset( dib_bits, 0xaa, 64 * 4 );
4036 info->bmiHeader.biHeight = -5;
4037 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4038 ok( ret == 2, "got %d\n", ret );
4039 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4040 ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
4041 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4042 memset( dib_bits, 0xaa, 64 * 4 );
4044 DeleteObject( dib );
4046 info->bmiHeader.biHeight = -8;
4048 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4049 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4053 /* like the t-d -> b-u case. */
4055 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4056 ok( ret == 8, "got %d\n", ret );
4057 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4058 memset( dib_bits, 0xaa, 64 * 4 );
4060 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4061 ok( ret == 5, "got %d\n", ret );
4062 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4063 ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
4064 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4065 memset( dib_bits, 0xaa, 64 * 4 );
4067 info->bmiHeader.biHeight = -16;
4068 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4069 ok( ret == 12, "got %d\n", ret );
4070 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4071 ok( !memcmp( dib_bits + 24, data, 40 * 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 < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4078 ok( !memcmp( dib_bits + 16, data, 16 * 4 ), "bits differ\n");
4079 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4080 memset( dib_bits, 0xaa, 64 * 4 );
4083 /* like the b-u -> b-u case */
4085 info->bmiHeader.biHeight = 8;
4086 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4087 ok( ret == 8, "got %d\n", ret );
4088 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4089 memset( dib_bits, 0xaa, 64 * 4 );
4091 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4092 ok( ret == 5, "got %d\n", ret );
4093 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4094 ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
4095 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4096 memset( dib_bits, 0xaa, 64 * 4 );
4098 info->bmiHeader.biHeight = 16;
4099 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4100 ok( ret == 12, "got %d\n", ret );
4101 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4102 ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
4103 memset( dib_bits, 0xaa, 64 * 4 );
4105 info->bmiHeader.biHeight = 5;
4106 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4107 ok( ret == 2, "got %d\n", ret );
4108 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4109 ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
4110 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4111 memset( dib_bits, 0xaa, 64 * 4 );
4113 DeleteObject( dib );
4114 ReleaseDC( NULL, hdc );
4115 HeapFree( GetProcessHeap(), 0, info );
4118 static void test_SetDIBits_RLE4(void)
4122 HDC hdc = GetDC( NULL );
4123 BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00, /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
4124 0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
4125 0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00, /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
4126 0x00, 0x02, 0x01, 0x02, 0x05, 0x87, /* dx=1, dy=2, 8, 7, 8, 7, 8 */
4127 0x00, 0x01 }; /* <eod> */
4130 DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
4131 0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
4132 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4133 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4134 0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
4135 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4136 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4137 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4139 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4141 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4142 info->bmiHeader.biWidth = 8;
4143 info->bmiHeader.biHeight = 8;
4144 info->bmiHeader.biPlanes = 1;
4145 info->bmiHeader.biBitCount = 32;
4146 info->bmiHeader.biCompression = BI_RGB;
4148 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4149 memset( dib_bits, 0xaa, 64 * 4 );
4151 info->bmiHeader.biBitCount = 4;
4152 info->bmiHeader.biCompression = BI_RLE4;
4153 info->bmiHeader.biSizeImage = sizeof(rle4_data);
4155 for (i = 0; i < 16; i++)
4157 info->bmiColors[i].rgbRed = i;
4158 info->bmiColors[i].rgbGreen = i;
4159 info->bmiColors[i].rgbBlue = i;
4160 info->bmiColors[i].rgbReserved = 0;
4163 ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
4164 ok( ret == 8, "got %d\n", ret );
4165 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
4166 memset( dib_bits, 0xaa, 64 * 4 );
4168 DeleteObject( dib );
4169 ReleaseDC( NULL, hdc );
4170 HeapFree( GetProcessHeap(), 0, info );
4173 static void test_SetDIBits_RLE8(void)
4177 HDC hdc = GetDC( NULL );
4178 BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00, /* 2, 2, 2, f0, f0, f0, f0, <eol> */
4179 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4180 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4181 0x00, 0x01 }; /* <eod> */
4184 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4185 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4186 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4187 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4188 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4189 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4190 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4191 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4192 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4193 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4194 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4195 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4196 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4197 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4198 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4199 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4201 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4203 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4204 info->bmiHeader.biWidth = 8;
4205 info->bmiHeader.biHeight = 8;
4206 info->bmiHeader.biPlanes = 1;
4207 info->bmiHeader.biBitCount = 32;
4208 info->bmiHeader.biCompression = BI_RGB;
4210 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4211 memset( dib_bits, 0xaa, 64 * 4 );
4213 info->bmiHeader.biBitCount = 8;
4214 info->bmiHeader.biCompression = BI_RLE8;
4215 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4217 for (i = 0; i < 256; i++)
4219 info->bmiColors[i].rgbRed = i;
4220 info->bmiColors[i].rgbGreen = i;
4221 info->bmiColors[i].rgbBlue = i;
4222 info->bmiColors[i].rgbReserved = 0;
4225 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4226 ok( ret == 8, "got %d\n", ret );
4227 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4228 memset( dib_bits, 0xaa, 64 * 4 );
4230 /* startscan and lines are ignored, unless lines == 0 */
4231 ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4232 ok( ret == 8, "got %d\n", ret );
4233 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4234 memset( dib_bits, 0xaa, 64 * 4 );
4236 ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4237 ok( ret == 8, "got %d\n", ret );
4238 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4239 memset( dib_bits, 0xaa, 64 * 4 );
4241 ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4242 ok( ret == 0, "got %d\n", ret );
4243 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4244 memset( dib_bits, 0xaa, 64 * 4 );
4246 /* reduce width to 4, left-hand side of dst is touched. */
4247 info->bmiHeader.biWidth = 4;
4248 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4249 ok( ret == 8, "got %d\n", ret );
4250 for (i = 0; i < 64; i++)
4252 DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4253 ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4255 memset( dib_bits, 0xaa, 64 * 4 );
4257 /* Show that the top lines are aligned by adjusting the height of the src */
4259 /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4260 info->bmiHeader.biWidth = 8;
4261 info->bmiHeader.biHeight = 4;
4262 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4263 ok( ret == 4, "got %d\n", ret );
4264 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4265 ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4266 memset( dib_bits, 0xaa, 64 * 4 );
4268 /* increase the height to 9 -> everything moves down one row. */
4269 info->bmiHeader.biHeight = 9;
4270 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4271 ok( ret == 9, "got %d\n", ret );
4272 ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4273 for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4274 memset( dib_bits, 0xaa, 64 * 4 );
4276 /* top-down compressed dibs are invalid */
4277 info->bmiHeader.biHeight = -8;
4278 SetLastError( 0xdeadbeef );
4279 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4280 ok( ret == 0, "got %d\n", ret );
4281 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4282 DeleteObject( dib );
4286 info->bmiHeader.biHeight = -8;
4287 info->bmiHeader.biBitCount = 32;
4288 info->bmiHeader.biCompression = BI_RGB;
4289 info->bmiHeader.biSizeImage = 0;
4291 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4292 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4294 info->bmiHeader.biHeight = 8;
4295 info->bmiHeader.biBitCount = 8;
4296 info->bmiHeader.biCompression = BI_RLE8;
4297 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4299 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4300 ok( ret == 8, "got %d\n", ret );
4301 ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4302 memset( dib_bits, 0xaa, 64 * 4 );
4304 info->bmiHeader.biHeight = 4;
4305 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4306 ok( ret == 4, "got %d\n", ret );
4307 ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4308 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4309 memset( dib_bits, 0xaa, 64 * 4 );
4311 info->bmiHeader.biHeight = 9;
4312 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4313 ok( ret == 9, "got %d\n", ret );
4314 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4315 ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4316 memset( dib_bits, 0xaa, 64 * 4 );
4318 DeleteObject( dib );
4319 ReleaseDC( NULL, hdc );
4320 HeapFree( GetProcessHeap(), 0, info );
4323 static void test_SetDIBitsToDevice(void)
4327 HDC hdc = CreateCompatibleDC( 0 );
4328 DWORD data[128], inverted_data[128];
4332 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4334 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4335 info->bmiHeader.biWidth = 8;
4336 info->bmiHeader.biHeight = 8;
4337 info->bmiHeader.biPlanes = 1;
4338 info->bmiHeader.biBitCount = 32;
4339 info->bmiHeader.biCompression = BI_RGB;
4341 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4342 memset( dib_bits, 0xaa, 64 * 4 );
4343 SelectObject( hdc, dib );
4345 for (i = 0; i < 128; i++)
4348 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4353 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4354 ok( ret == 8, "got %d\n", ret );
4355 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4356 memset( dib_bits, 0xaa, 64 * 4 );
4358 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4359 ok( ret == 5, "got %d\n", ret );
4360 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4361 for (i = 8; i < 48; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4362 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4363 memset( dib_bits, 0xaa, 64 * 4 );
4365 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 3, 1, 5, data, info, DIB_RGB_COLORS );
4366 ok( ret == 5, "got %d\n", ret );
4367 for (i = 0; i < 24; i++) ok( dib_bits[i] == data[i + 16], "%d: got %08x\n", i, dib_bits[i] );
4368 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4369 memset( dib_bits, 0xaa, 64 * 4 );
4371 info->bmiHeader.biHeight = 16;
4372 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4373 ok( ret == 7, "got %d\n", ret );
4374 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4375 for (i = 8; i < 64; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4376 memset( dib_bits, 0xaa, 64 * 4 );
4378 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 8, 0, 6, 1, 12, data, info, DIB_RGB_COLORS );
4379 ok( ret == 12, "got %d\n", ret );
4380 for (i = 0; i < 40; i++) ok( dib_bits[i] == data[i + 56], "%d: got %08x\n", i, dib_bits[i] );
4381 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4382 memset( dib_bits, 0xaa, 64 * 4 );
4384 ret = SetDIBitsToDevice( hdc, 0, -4, 8, 8, 0, 3, 1, 12, data, info, DIB_RGB_COLORS );
4385 ok( ret == 10, "got %d\n", ret );
4386 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4387 for (i = 32; i < 64; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4388 memset( dib_bits, 0xaa, 64 * 4 );
4390 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, -3, 1, 12, data, info, DIB_RGB_COLORS );
4391 ok( ret == 4, "got %d\n", ret );
4392 for (i = 0; i < 32; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4393 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4394 memset( dib_bits, 0xaa, 64 * 4 );
4396 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 5, 0, -2, 1, 12, data, info, DIB_RGB_COLORS );
4397 ok( ret == 2, "got %d\n", ret );
4398 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4399 for (i = 32; i < 48; i++) ok( dib_bits[i] == data[i - 32], "%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 info->bmiHeader.biHeight = 5;
4404 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 2, 2, data, info, DIB_RGB_COLORS );
4405 ok( ret == 2, "got %d\n", ret );
4406 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4407 for (i = 16; i < 32; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4408 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4409 memset( dib_bits, 0xaa, 64 * 4 );
4411 ret = SetDIBitsToDevice( hdc, 3, 3, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4412 ok( ret == 3, "got %d\n", ret );
4413 for (i = 0; i < 64; i++)
4414 if (i == 27 || i == 28 || i == 35 || i == 36)
4415 ok( dib_bits[i] == data[i - 18], "%d: got %08x\n", i, dib_bits[i] );
4417 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4418 memset( dib_bits, 0xaa, 64 * 4 );
4420 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4421 ok( ret == 5, "got %d\n", ret );
4422 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4423 memset( dib_bits, 0xaa, 64 * 4 );
4425 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4426 ok( ret == 0, "got %d\n", ret );
4427 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4428 memset( dib_bits, 0xaa, 64 * 4 );
4430 SetMapMode( hdc, MM_ANISOTROPIC );
4431 SetWindowExtEx( hdc, 3, 3, NULL );
4432 ret = SetDIBitsToDevice( hdc, 2, 2, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4433 ok( ret == 3, "got %d\n", ret );
4434 for (i = 0; i < 64; i++)
4435 if (i == 41 || i == 42 || i == 49 || i == 50)
4436 ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4438 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4439 memset( dib_bits, 0xaa, 64 * 4 );
4441 SetWindowExtEx( hdc, -1, -1, NULL );
4442 ret = SetDIBitsToDevice( hdc, 2, 2, 4, 4, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4443 ok( ret == 4, "got %d\n", ret );
4444 for (i = 0; i < 64; i++)
4445 if (i == 48 || i == 49 || i == 56 || i == 57)
4446 ok( dib_bits[i] == data[i - 37], "%d: got %08x\n", i, dib_bits[i] );
4448 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4449 memset( dib_bits, 0xaa, 64 * 4 );
4450 SetMapMode( hdc, MM_TEXT );
4454 pSetLayout( hdc, LAYOUT_RTL );
4455 ret = SetDIBitsToDevice( hdc, 1, 2, 3, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4456 ok( ret == 3, "got %d\n", ret );
4457 for (i = 0; i < 64; i++)
4458 if (i == 36 || i == 37 || i == 38 || i == 44 || i == 45 || i == 46)
4459 ok( dib_bits[i] == data[i - 27], "%d: got %08x\n", i, dib_bits[i] );
4461 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4462 memset( dib_bits, 0xaa, 64 * 4 );
4463 pSetLayout( hdc, LAYOUT_LTR );
4467 info->bmiHeader.biHeight = -8;
4468 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4469 ok( ret == 8, "got %d\n", ret );
4470 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4471 memset( dib_bits, 0xaa, 64 * 4 );
4473 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4474 ok( ret == 5, "got %d\n", ret );
4475 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4476 for (i = 8; i < 48; i++) ok( dib_bits[i] == inverted_data[i + 80], "%d: got %08x\n", i, dib_bits[i] );
4477 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4478 memset( dib_bits, 0xaa, 64 * 4 );
4480 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 4, 1, 5, data, info, DIB_RGB_COLORS );
4481 ok( ret == 5, "got %d\n", ret );
4482 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4483 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4484 memset( dib_bits, 0xaa, 64 * 4 );
4486 info->bmiHeader.biHeight = -16;
4487 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4488 ok( ret == 12, "got %d\n", ret );
4489 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4490 for (i = 8; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4491 memset( dib_bits, 0xaa, 64 * 4 );
4493 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, 7, 1, 12, data, info, DIB_RGB_COLORS );
4494 ok( ret == 12, "got %d\n", ret );
4495 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4496 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4497 memset( dib_bits, 0xaa, 64 * 4 );
4499 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 4, 12, data, info, DIB_RGB_COLORS );
4500 ok( ret == 12, "got %d\n", ret );
4501 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4502 for (i = 32; i < 64; i++) ok( dib_bits[i] == inverted_data[i], "%d: got %08x\n", i, dib_bits[i] );
4503 memset( dib_bits, 0xaa, 64 * 4 );
4505 ret = SetDIBitsToDevice( hdc, 0, -3, 8, 8, 0, 2, 4, 12, data, info, DIB_RGB_COLORS );
4506 ok( ret == 12, "got %d\n", ret );
4507 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4508 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4509 memset( dib_bits, 0xaa, 64 * 4 );
4511 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, -2, 4, 12, data, info, DIB_RGB_COLORS );
4512 ok( ret == 12, "got %d\n", ret );
4513 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4514 for (i = 24; i < 40; i++) ok( dib_bits[i] == inverted_data[i + 8], "%d: got %08x\n", i, dib_bits[i] );
4515 for (i = 40; 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, 0, 5, 12, data, info, DIB_RGB_COLORS );
4519 ok( ret == 12, "got %d\n", ret );
4520 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4521 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4522 memset( dib_bits, 0xaa, 64 * 4 );
4524 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4525 ok( ret == 12, "got %d\n", ret );
4526 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4527 memset( dib_bits, 0xaa, 64 * 4 );
4529 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -2, -4, 0, 12, data, info, DIB_RGB_COLORS );
4530 ok( ret == 12, "got %d\n", ret );
4531 for (i = 0; i < 64; i++)
4532 if (i == 31 || i == 39 || i == 47 || i == 55 || i == 63)
4533 ok( dib_bits[i] == inverted_data[i + 1], "%d: got %08x\n", i, dib_bits[i] );
4535 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4536 memset( dib_bits, 0xaa, 64 * 4 );
4538 info->bmiHeader.biHeight = -5;
4539 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4540 ok( ret == 2, "got %d\n", ret );
4541 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4542 for (i = 8; i < 24; i++) ok( dib_bits[i] == inverted_data[i + 104], "%d: got %08x\n", i, dib_bits[i] );
4543 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4544 memset( dib_bits, 0xaa, 64 * 4 );
4546 ret = SetDIBitsToDevice( hdc, 5, 4, 2, 2, 6, 3, 1, 5, data, info, DIB_RGB_COLORS );
4547 ok( ret == 5, "got %d\n", ret );
4548 for (i = 0; i < 64; i++)
4549 if (i == 21 || i == 22 || i == 29 || i == 30)
4550 ok( dib_bits[i] == inverted_data[i + 89], "%d: got %08x\n", i, dib_bits[i] );
4552 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4553 memset( dib_bits, 0xaa, 64 * 4 );
4555 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4556 ok( ret == 5, "got %d\n", ret );
4557 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4558 memset( dib_bits, 0xaa, 64 * 4 );
4560 info->bmiHeader.biHeight = -8;
4562 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4563 DeleteObject( SelectObject( hdc, dib ));
4564 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4568 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4569 ok( ret == 8, "got %d\n", ret );
4570 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4571 memset( dib_bits, 0xaa, 64 * 4 );
4573 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4574 ok( ret == 5, "got %d\n", ret );
4575 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4576 for (i = 16; i < 56; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4577 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4578 memset( dib_bits, 0xaa, 64 * 4 );
4580 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 3, 0, 2, 1, 5, data, info, DIB_RGB_COLORS );
4581 ok( ret == 5, "got %d\n", ret );
4582 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4583 for (i = 24; i < 48; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4584 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4585 memset( dib_bits, 0xaa, 64 * 4 );
4587 info->bmiHeader.biHeight = -16;
4588 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4589 ok( ret == 12, "got %d\n", ret );
4590 for (i = 0; i < 56; i++) ok( dib_bits[i] == data[i + 40], "%d: got %08x\n", i, dib_bits[i] );
4591 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4592 memset( dib_bits, 0xaa, 64 * 4 );
4594 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -1, -8, 0, 12, data, info, DIB_RGB_COLORS );
4595 ok( ret == 12, "got %d\n", ret );
4596 for (i = 0; i < 64; i++)
4597 if (i == 6 || i == 7)
4598 ok( dib_bits[i] == data[i + 82], "%d: got %08x\n", i, dib_bits[i] );
4600 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4601 memset( dib_bits, 0xaa, 64 * 4 );
4603 info->bmiHeader.biHeight = -5;
4604 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4605 ok( ret == 2, "got %d\n", ret );
4606 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4607 for (i = 40; i < 56; i++) ok( dib_bits[i] == data[i - 40], "%d: got %08x\n", i, dib_bits[i] );
4608 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4609 memset( dib_bits, 0xaa, 64 * 4 );
4611 ret = SetDIBitsToDevice( hdc, 7, 2, 8, 8, 1, 0, 0, 5, data, info, DIB_RGB_COLORS );
4612 ok( ret == 5, "got %d\n", ret );
4613 for (i = 0; i < 64; i++)
4614 if (i == 47 || i == 55 || i == 63)
4615 ok( dib_bits[i] == data[i - 46], "%d: got %08x\n", i, dib_bits[i] );
4617 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4618 memset( dib_bits, 0xaa, 64 * 4 );
4620 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4621 ok( ret == 5, "got %d\n", ret );
4622 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4623 memset( dib_bits, 0xaa, 64 * 4 );
4627 info->bmiHeader.biHeight = 8;
4628 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4629 ok( ret == 8, "got %d\n", ret );
4630 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4631 memset( dib_bits, 0xaa, 64 * 4 );
4633 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4634 ok( ret == 5, "got %d\n", ret );
4635 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4636 for (i = 16; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4637 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4638 memset( dib_bits, 0xaa, 64 * 4 );
4640 info->bmiHeader.biHeight = 16;
4641 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4642 ok( ret == 7, "got %d\n", ret );
4643 for (i = 0; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4644 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4645 memset( dib_bits, 0xaa, 64 * 4 );
4647 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, 0, -4, 1, 12, data, info, DIB_RGB_COLORS );
4648 ok( ret == 3, "got %d\n", ret );
4649 for (i = 0; i < 64; i++)
4650 if ((i >= 36 && i <= 39) || (i >= 44 && i <= 47) || (i >= 52 && i <= 55))
4651 ok( dib_bits[i] == inverted_data[i + 68], "%d: got %08x\n", i, dib_bits[i] );
4653 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4654 memset( dib_bits, 0xaa, 64 * 4 );
4656 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, -30, -30, 1, 12, data, info, DIB_RGB_COLORS );
4657 ok( ret == 0, "got %d\n", ret );
4658 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4659 memset( dib_bits, 0xaa, 64 * 4 );
4661 ret = SetDIBitsToDevice( hdc, 5, -5, 8, 16, -2, -4, 4, 12, data, info, DIB_RGB_COLORS );
4662 ok( ret == 8, "got %d\n", ret );
4663 for (i = 0; i < 64; i++)
4664 if (i == 7 || i == 15 || i == 23)
4665 ok( dib_bits[i] == inverted_data[i + 97], "%d: got %08x\n", i, dib_bits[i] );
4667 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4668 memset( dib_bits, 0xaa, 64 * 4 );
4670 info->bmiHeader.biHeight = 5;
4671 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4672 ok( ret == 2, "got %d\n", ret );
4673 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4674 for (i = 40; 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 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4679 ok( ret == 5, "got %d\n", ret );
4680 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4681 memset( dib_bits, 0xaa, 64 * 4 );
4684 DeleteObject( dib );
4685 HeapFree( GetProcessHeap(), 0, info );
4688 static void test_SetDIBitsToDevice_RLE8(void)
4692 HDC hdc = CreateCompatibleDC( 0 );
4693 BYTE rle8_data[20] = { 0x04, 0x02, 0x03, 0xf0, 0x00, 0x00, /* 2, 2, 2, 2, f0, f0, f0, <eol> */
4694 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4695 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4696 0x00, 0x01 }; /* <eod> */
4699 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4700 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4701 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4702 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4703 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4704 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4705 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4706 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4707 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4708 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4709 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4710 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4711 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4712 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4713 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4714 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4716 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4718 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4719 info->bmiHeader.biWidth = 8;
4720 info->bmiHeader.biHeight = 8;
4721 info->bmiHeader.biPlanes = 1;
4722 info->bmiHeader.biBitCount = 32;
4723 info->bmiHeader.biCompression = BI_RGB;
4725 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4726 memset( dib_bits, 0xaa, 64 * 4 );
4727 SelectObject( hdc, dib );
4729 info->bmiHeader.biBitCount = 8;
4730 info->bmiHeader.biCompression = BI_RLE8;
4731 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4733 for (i = 0; i < 256; i++)
4735 info->bmiColors[i].rgbRed = i;
4736 info->bmiColors[i].rgbGreen = i;
4737 info->bmiColors[i].rgbBlue = i;
4738 info->bmiColors[i].rgbReserved = 0;
4741 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4742 ok( ret == 8, "got %d\n", ret );
4743 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4744 memset( dib_bits, 0xaa, 64 * 4 );
4746 /* startscan and lines are ignored, unless lines == 0 */
4747 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4748 ok( ret == 8, "got %d\n", ret );
4749 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4750 memset( dib_bits, 0xaa, 64 * 4 );
4752 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4753 ok( ret == 8, "got %d\n", ret );
4754 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4755 memset( dib_bits, 0xaa, 64 * 4 );
4757 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4758 ok( ret == 0, "got %d\n", ret );
4759 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4760 memset( dib_bits, 0xaa, 64 * 4 );
4762 info->bmiHeader.biWidth = 2;
4763 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4764 ok( ret == 8, "got %d\n", ret );
4765 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4766 memset( dib_bits, 0xaa, 64 * 4 );
4768 info->bmiHeader.biWidth = 8;
4769 info->bmiHeader.biHeight = 2;
4770 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4771 ok( ret == 2, "got %d\n", ret );
4772 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4773 memset( dib_bits, 0xaa, 64 * 4 );
4775 info->bmiHeader.biHeight = 9;
4776 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4777 ok( ret == 9, "got %d\n", ret );
4778 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4779 memset( dib_bits, 0xaa, 64 * 4 );
4781 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4782 ok( ret == 9, "got %d\n", ret );
4783 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4784 memset( dib_bits, 0xaa, 64 * 4 );
4786 info->bmiHeader.biHeight = 8;
4787 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 9, rle8_data, info, DIB_RGB_COLORS );
4788 ok( ret == 8, "got %d\n", ret );
4789 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4790 memset( dib_bits, 0xaa, 64 * 4 );
4792 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4793 ok( ret == 8, "got %d\n", ret );
4794 for (i = 0; i < 40; i++) ok( dib_bits[i] == bottom_up[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4795 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4796 memset( dib_bits, 0xaa, 64 * 4 );
4798 ret = SetDIBitsToDevice( hdc, 0, 3, 4, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4799 ok( ret == 8, "got %d\n", ret );
4800 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4801 for (i = 8; i < 40; i++)
4802 if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4803 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4804 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4805 memset( dib_bits, 0xaa, 64 * 4 );
4807 ret = SetDIBitsToDevice( hdc, 3, 3, 8, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4808 ok( ret == 8, "got %d\n", ret );
4809 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4810 for (i = 8; i < 40; i++)
4811 if ((i & 7) < 3) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4812 else ok( dib_bits[i] == bottom_up[i - 11], "%d: got %08x\n", i, dib_bits[i] );
4813 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4814 memset( dib_bits, 0xaa, 64 * 4 );
4816 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 4, 2, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4817 ok( ret == 8, "got %d\n", ret );
4818 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4819 for (i = 8; i < 40; i++)
4820 if ((i & 7) < 2) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4821 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4822 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4823 memset( dib_bits, 0xaa, 64 * 4 );
4825 info->bmiHeader.biWidth = 37;
4826 info->bmiHeader.biHeight = 37;
4827 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
4828 ok( ret == 37, "got %d\n", ret );
4829 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4830 for (i = 24; i < 64; i++)
4831 if (i == 52) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
4832 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4833 else ok( dib_bits[i] == bottom_up[i - 20], "%d: got %08x\n", i, dib_bits[i] );
4834 memset( dib_bits, 0xaa, 64 * 4 );
4836 /* top-down compressed dibs are invalid */
4837 info->bmiHeader.biWidth = 8;
4838 info->bmiHeader.biHeight = -8;
4839 SetLastError( 0xdeadbeef );
4840 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4841 ok( ret == 0, "got %d\n", ret );
4842 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4846 info->bmiHeader.biHeight = -8;
4847 info->bmiHeader.biBitCount = 32;
4848 info->bmiHeader.biCompression = BI_RGB;
4849 info->bmiHeader.biSizeImage = 0;
4851 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4852 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4853 DeleteObject( SelectObject( hdc, dib ));
4855 info->bmiHeader.biHeight = 8;
4856 info->bmiHeader.biBitCount = 8;
4857 info->bmiHeader.biCompression = BI_RLE8;
4858 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4860 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4861 ok( ret == 8, "got %d\n", ret );
4862 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4863 memset( dib_bits, 0xaa, 64 * 4 );
4865 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4866 ok( ret == 8, "got %d\n", ret );
4867 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4868 memset( dib_bits, 0xaa, 64 * 4 );
4870 info->bmiHeader.biHeight = 4;
4871 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4872 ok( ret == 4, "got %d\n", ret );
4873 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4874 memset( dib_bits, 0xaa, 64 * 4 );
4876 info->bmiHeader.biHeight = 9;
4877 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4878 ok( ret == 9, "got %d\n", ret );
4879 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4880 memset( dib_bits, 0xaa, 64 * 4 );
4882 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4883 ok( ret == 9, "got %d\n", ret );
4884 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4885 memset( dib_bits, 0xaa, 64 * 4 );
4887 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 6, 2, 2, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4888 ok( ret == 9, "got %d\n", ret );
4889 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4890 for (i = 24; i < 64; i++) ok( dib_bits[i] == top_down[i - 24], "%d: got %08x\n", i, dib_bits[i] );
4891 memset( dib_bits, 0xaa, 64 * 4 );
4893 info->bmiHeader.biWidth = 37;
4894 info->bmiHeader.biHeight = 37;
4895 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
4896 ok( ret == 37, "got %d\n", ret );
4897 for (i = 0; i < 40; i++)
4898 if (i == 12) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
4899 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4900 else ok( dib_bits[i] == top_down[i + 28], "%d: got %08x\n", i, dib_bits[i] );
4901 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4902 memset( dib_bits, 0xaa, 64 * 4 );
4905 DeleteObject( dib );
4906 HeapFree( GetProcessHeap(), 0, info );
4913 hdll = GetModuleHandle("gdi32.dll");
4914 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
4915 pSetLayout = (void*)GetProcAddress(hdll, "SetLayout");
4917 test_createdibitmap();
4920 test_mono_dibsection();
4923 test_GetDIBits_selected_DIB(1);
4924 test_GetDIBits_selected_DIB(4);
4925 test_GetDIBits_selected_DIB(8);
4926 test_GetDIBits_selected_DDB(TRUE);
4927 test_GetDIBits_selected_DDB(FALSE);
4929 test_GetDIBits_BI_BITFIELDS();
4930 test_select_object();
4931 test_CreateBitmap();
4934 test_StretchDIBits();
4935 test_GdiAlphaBlend();
4936 test_32bit_bitmap_blt();
4937 test_bitmapinfoheadersize();
4940 test_GetDIBits_top_down(16);
4941 test_GetDIBits_top_down(24);
4942 test_GetDIBits_top_down(32);
4943 test_GetSetDIBits_rtl();
4944 test_GetDIBits_scanlines();
4946 test_SetDIBits_RLE4();
4947 test_SetDIBits_RLE8();
4948 test_SetDIBitsToDevice();
4949 test_SetDIBitsToDevice_RLE8();