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 BOOL (WINAPI *pGdiGradientFill)(HDC,TRIVERTEX*,ULONG,void*,ULONG,ULONG);
37 static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
39 static inline int get_bitmap_stride( int width, int bpp )
41 return ((width * bpp + 15) >> 3) & ~1;
44 static inline int get_dib_stride( int width, int bpp )
46 return ((width * bpp + 31) >> 3) & ~3;
49 static inline int get_dib_image_size( const BITMAPINFO *info )
51 return get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount )
52 * abs( info->bmiHeader.biHeight );
55 static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHEADER *bmih)
60 BYTE buf[512], buf_cmp[512];
62 ret = GetObject(hbm, sizeof(bm), &bm);
63 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
65 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
66 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
67 ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
68 width_bytes = get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel);
69 ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
70 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
71 ok(bm.bmBitsPixel == expected_depth, "wrong bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, expected_depth);
72 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
74 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
75 assert(sizeof(buf) == sizeof(buf_cmp));
77 SetLastError(0xdeadbeef);
78 ret = GetBitmapBits(hbm, 0, NULL);
79 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
81 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
82 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
84 memset(buf, 0xAA, sizeof(buf));
85 ret = GetBitmapBits(hbm, sizeof(buf), buf);
86 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
87 ok(!memcmp(buf, buf_cmp, sizeof(buf)),
88 "buffers do not match, depth %d\n", bmih->biBitCount);
90 /* test various buffer sizes for GetObject */
91 ret = GetObject(hbm, sizeof(*bma) * 2, bma);
92 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
94 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
95 ok(ret == 0, "%d != 0\n", ret);
97 ret = GetObject(hbm, 0, &bm);
98 ok(ret == 0, "%d != 0\n", ret);
100 ret = GetObject(hbm, 1, &bm);
101 ok(ret == 0, "%d != 0\n", ret);
103 ret = GetObject(hbm, 0, NULL);
104 ok(ret == sizeof(bm), "wrong size %d\n", ret);
107 static void test_createdibitmap(void)
110 BITMAPINFOHEADER bmih;
112 HBITMAP hbm, hbm_colour, hbm_old;
117 screen_depth = GetDeviceCaps(hdc, BITSPIXEL);
118 memset(&bmih, 0, sizeof(bmih));
119 bmih.biSize = sizeof(bmih);
123 bmih.biBitCount = 32;
124 bmih.biCompression = BI_RGB;
126 hbm = CreateDIBitmap(hdc, NULL, CBM_INIT, NULL, NULL, 0);
127 ok(hbm == NULL, "CreateDIBitmap should fail\n");
128 hbm = CreateDIBitmap(hdc, NULL, 0, NULL, NULL, 0);
129 ok(hbm == NULL, "CreateDIBitmap should fail\n");
131 /* First create an un-initialised bitmap. The depth of the bitmap
132 should match that of the hdc and not that supplied in bmih.
135 /* First try 32 bits */
136 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
137 ok(hbm != NULL, "CreateDIBitmap failed\n");
138 test_bitmap_info(hbm, screen_depth, &bmih);
142 bmih.biBitCount = 16;
143 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
144 ok(hbm != NULL, "CreateDIBitmap failed\n");
145 test_bitmap_info(hbm, screen_depth, &bmih);
150 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
151 ok(hbm != NULL, "CreateDIBitmap failed\n");
152 test_bitmap_info(hbm, screen_depth, &bmih);
155 /* Now with a monochrome dc we expect a monochrome bitmap */
156 hdcmem = CreateCompatibleDC(hdc);
158 /* First try 32 bits */
159 bmih.biBitCount = 32;
160 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
161 ok(hbm != NULL, "CreateDIBitmap failed\n");
162 test_bitmap_info(hbm, 1, &bmih);
166 bmih.biBitCount = 16;
167 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
168 ok(hbm != NULL, "CreateDIBitmap failed\n");
169 test_bitmap_info(hbm, 1, &bmih);
174 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
175 ok(hbm != NULL, "CreateDIBitmap failed\n");
176 test_bitmap_info(hbm, 1, &bmih);
179 /* Now select a polychrome bitmap into the dc and we expect
180 screen_depth bitmaps again */
181 hbm_colour = CreateCompatibleBitmap(hdc, bmih.biWidth, bmih.biHeight);
182 test_bitmap_info(hbm_colour, screen_depth, &bmih);
183 hbm_old = SelectObject(hdcmem, hbm_colour);
185 /* First try 32 bits */
186 bmih.biBitCount = 32;
187 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
188 ok(hbm != NULL, "CreateDIBitmap failed\n");
189 test_bitmap_info(hbm, screen_depth, &bmih);
193 bmih.biBitCount = 16;
194 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
195 ok(hbm != NULL, "CreateDIBitmap failed\n");
196 test_bitmap_info(hbm, screen_depth, &bmih);
201 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
202 ok(hbm != NULL, "CreateDIBitmap failed\n");
203 test_bitmap_info(hbm, screen_depth, &bmih);
206 SelectObject(hdcmem, hbm_old);
207 DeleteObject(hbm_colour);
210 bmih.biBitCount = 32;
211 hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0);
212 ok(hbm != NULL, "CreateDIBitmap failed\n");
213 test_bitmap_info(hbm, 1, &bmih);
216 /* Test how formats are converted */
222 memset(&bm, 0, sizeof(bm));
223 bm.bmiHeader.biSize = sizeof(bm.bmiHeader);
224 bm.bmiHeader.biWidth = 1;
225 bm.bmiHeader.biHeight = 1;
226 bm.bmiHeader.biPlanes = 1;
227 bm.bmiHeader.biBitCount= 24;
228 bm.bmiHeader.biCompression= BI_RGB;
229 bm.bmiHeader.biSizeImage = 0;
230 hbm = CreateDIBitmap(hdc, &bmih, CBM_INIT, &pixel, &bm, DIB_RGB_COLORS);
231 ok(hbm != NULL, "CreateDIBitmap failed\n");
234 bm.bmiHeader.biBitCount= 32;
235 GetDIBits(hdc, hbm, 0, 1, &pixel, &bm, DIB_RGB_COLORS);
236 ok(pixel == 0x00ffffff, "Reading a 32 bit pixel from a DDB returned %08x\n", pixel);
242 static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
248 INT ret, bm_width_bytes, dib_width_bytes;
251 ret = GetObject(hbm, sizeof(bm), &bm);
252 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
254 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
255 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
256 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
257 dib_width_bytes = get_dib_stride(bm.bmWidth, bm.bmBitsPixel);
258 bm_width_bytes = get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel);
259 if (bm.bmWidthBytes != dib_width_bytes) /* Win2k bug */
260 ok(bm.bmWidthBytes == bm_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, bm_width_bytes);
262 ok(bm.bmWidthBytes == dib_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, dib_width_bytes);
263 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
264 ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount);
265 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
267 buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);
269 /* GetBitmapBits returns not 32-bit aligned data */
270 SetLastError(0xdeadbeef);
271 ret = GetBitmapBits(hbm, 0, NULL);
272 ok(ret == bm_width_bytes * bm.bmHeight,
273 "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
275 memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
276 ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
277 ok(ret == bm_width_bytes * bm.bmHeight, "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
279 HeapFree(GetProcessHeap(), 0, buf);
281 /* test various buffer sizes for GetObject */
282 memset(&ds, 0xAA, sizeof(ds));
283 ret = GetObject(hbm, sizeof(*bma) * 2, bma);
284 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
285 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
286 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
287 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
289 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
290 ok(ret == 0, "%d != 0\n", ret);
292 ret = GetObject(hbm, 0, &bm);
293 ok(ret == 0, "%d != 0\n", ret);
295 ret = GetObject(hbm, 1, &bm);
296 ok(ret == 0, "%d != 0\n", ret);
298 /* test various buffer sizes for GetObject */
299 ret = GetObject(hbm, 0, NULL);
300 ok(ret == sizeof(bm), "wrong size %d\n", ret);
302 ret = GetObject(hbm, sizeof(*dsa) * 2, dsa);
303 ok(ret == sizeof(*dsa), "wrong size %d\n", ret);
305 memset(&ds, 0xAA, sizeof(ds));
306 ret = GetObject(hbm, sizeof(ds), &ds);
307 ok(ret == sizeof(ds), "wrong size %d\n", ret);
309 ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
310 if (ds.dsBm.bmWidthBytes != bm_width_bytes) /* Win2k bug */
311 ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%u != %u\n",
312 ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
313 ok(bmih->biSizeImage == 0, "%u != 0\n", bmih->biSizeImage);
314 ds.dsBmih.biSizeImage = 0;
316 ok(ds.dsBmih.biSize == bmih->biSize, "%u != %u\n", ds.dsBmih.biSize, bmih->biSize);
317 ok(ds.dsBmih.biWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
318 ok(ds.dsBmih.biHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
319 ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes);
320 ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount);
321 ok(ds.dsBmih.biCompression == bmih->biCompression ||
322 ((bmih->biBitCount == 32) && broken(ds.dsBmih.biCompression == BI_BITFIELDS)), /* nt4 sp1 and 2 */
323 "%u != %u\n", ds.dsBmih.biCompression, bmih->biCompression);
324 ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%u != %u\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
325 ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%d != %d\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
326 ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%d != %d\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);
328 memset(&ds, 0xAA, sizeof(ds));
329 ret = GetObject(hbm, sizeof(ds) - 4, &ds);
330 ok(ret == sizeof(ds.dsBm), "wrong size %d\n", ret);
331 ok(ds.dsBm.bmWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
332 ok(ds.dsBm.bmHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
333 ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);
335 ret = GetObject(hbm, 0, &ds);
336 ok(ret == 0, "%d != 0\n", ret);
338 ret = GetObject(hbm, 1, &ds);
339 ok(ret == 0, "%d != 0\n", ret);
342 #define test_color(hdc, color, exp) \
345 c = SetPixel(hdc, 0, 0, color); \
346 ok(c == exp, "SetPixel failed: got 0x%06x expected 0x%06x\n", c, (UINT)exp); \
347 c = GetPixel(hdc, 0, 0); \
348 ok(c == exp, "GetPixel failed: got 0x%06x expected 0x%06x\n", c, (UINT)exp); \
351 static void test_dib_bits_access( HBITMAP hdib, void *bits )
353 MEMORY_BASIC_INFORMATION info;
354 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
356 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
358 char filename[MAX_PATH];
363 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
364 "VirtualQuery failed\n");
365 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
366 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
367 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
368 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
369 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
370 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
372 memset( pbmi, 0, sizeof(bmibuf) );
373 memset( data, 0xcc, sizeof(data) );
374 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
375 pbmi->bmiHeader.biHeight = 16;
376 pbmi->bmiHeader.biWidth = 16;
377 pbmi->bmiHeader.biBitCount = 32;
378 pbmi->bmiHeader.biPlanes = 1;
379 pbmi->bmiHeader.biCompression = BI_RGB;
383 ret = SetDIBits( hdc, hdib, 0, 16, data, pbmi, DIB_RGB_COLORS );
384 ok(ret == 16, "SetDIBits failed: expected 16 got %d\n", ret);
388 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
389 "VirtualQuery failed\n");
390 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
391 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
392 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
393 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
394 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
395 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
397 /* try writing protected bits to a file */
399 GetTempFileNameA( ".", "dib", 0, filename );
400 file = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
401 CREATE_ALWAYS, 0, 0 );
402 ok( file != INVALID_HANDLE_VALUE, "failed to open %s error %u\n", filename, GetLastError() );
403 ret = WriteFile( file, bits, 8192, &written, NULL );
404 ok( ret, "WriteFile failed error %u\n", GetLastError() );
405 if (ret) ok( written == 8192, "only wrote %u bytes\n", written );
407 DeleteFileA( filename );
410 static void test_dibsections(void)
412 HDC hdc, hdcmem, hdcmem2;
413 HBITMAP hdib, oldbm, hdib2, oldbm2;
414 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
415 char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
416 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
417 BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
418 RGBQUAD *colors = pbmi->bmiColors;
419 RGBTRIPLE *ccolors = pbci->bmciColors;
425 char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
426 LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
427 PALETTEENTRY *palent = plogpal->palPalEntry;
430 HPALETTE hpal, oldpal;
434 MEMORY_BASIC_INFORMATION info;
438 memset(pbmi, 0, sizeof(bmibuf));
439 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
440 pbmi->bmiHeader.biHeight = 100;
441 pbmi->bmiHeader.biWidth = 512;
442 pbmi->bmiHeader.biBitCount = 24;
443 pbmi->bmiHeader.biPlanes = 1;
444 pbmi->bmiHeader.biCompression = BI_RGB;
446 SetLastError(0xdeadbeef);
448 /* invalid pointer for BITMAPINFO
449 (*bits should be NULL on error) */
450 bits = (BYTE*)0xdeadbeef;
451 hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
452 ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n");
454 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
455 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
456 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
457 ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
459 /* test the DIB memory */
460 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
461 "VirtualQuery failed\n");
462 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
463 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
464 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
465 ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
466 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
467 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
468 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
470 test_dib_bits_access( hdib, bits );
472 test_dib_info(hdib, bits, &pbmi->bmiHeader);
475 /* Test a top-down DIB. */
476 pbmi->bmiHeader.biHeight = -100;
477 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
478 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
479 test_dib_info(hdib, bits, &pbmi->bmiHeader);
482 pbmi->bmiHeader.biHeight = 100;
483 pbmi->bmiHeader.biBitCount = 8;
484 pbmi->bmiHeader.biCompression = BI_RLE8;
485 SetLastError(0xdeadbeef);
486 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
487 ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
488 ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
490 pbmi->bmiHeader.biBitCount = 16;
491 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
492 ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
493 ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
494 ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
495 SetLastError(0xdeadbeef);
496 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
497 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
499 /* test the DIB memory */
500 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
501 "VirtualQuery failed\n");
502 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
503 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
504 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
505 ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
506 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
507 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
508 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
510 test_dib_info(hdib, bits, &pbmi->bmiHeader);
513 memset(pbmi, 0, sizeof(bmibuf));
514 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
515 pbmi->bmiHeader.biHeight = 16;
516 pbmi->bmiHeader.biWidth = 16;
517 pbmi->bmiHeader.biBitCount = 1;
518 pbmi->bmiHeader.biPlanes = 1;
519 pbmi->bmiHeader.biCompression = BI_RGB;
520 colors[0].rgbRed = 0xff;
521 colors[0].rgbGreen = 0;
522 colors[0].rgbBlue = 0;
523 colors[1].rgbRed = 0;
524 colors[1].rgbGreen = 0;
525 colors[1].rgbBlue = 0xff;
527 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
528 ok(hdib != NULL, "CreateDIBSection failed\n");
529 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
530 ok(dibsec.dsBmih.biClrUsed == 2,
531 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
533 /* Test if the old BITMAPCOREINFO structure is supported */
535 pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
536 pbci->bmciHeader.bcBitCount = 0;
538 ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
539 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
540 ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
541 && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
542 "GetDIBits didn't fill in the BITMAPCOREHEADER structure properly\n");
544 ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
545 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
546 ok((ccolors[0].rgbtRed == 0xff) && (ccolors[0].rgbtGreen == 0) &&
547 (ccolors[0].rgbtBlue == 0) && (ccolors[1].rgbtRed == 0) &&
548 (ccolors[1].rgbtGreen == 0) && (ccolors[1].rgbtBlue == 0xff),
549 "The color table has not been translated to the old BITMAPCOREINFO format\n");
551 hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
552 ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
554 ZeroMemory(ccolors, 256 * sizeof(RGBTRIPLE));
555 ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
556 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
557 ok((ccolors[0].rgbtRed == 0xff) && (ccolors[0].rgbtGreen == 0) &&
558 (ccolors[0].rgbtBlue == 0) && (ccolors[1].rgbtRed == 0) &&
559 (ccolors[1].rgbtGreen == 0) && (ccolors[1].rgbtBlue == 0xff),
560 "The color table has not been translated to the old BITMAPCOREINFO format\n");
562 DeleteObject(hcoredib);
564 hdcmem = CreateCompatibleDC(hdc);
565 oldbm = SelectObject(hdcmem, hdib);
567 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
568 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
569 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
570 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
571 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
572 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
574 c0 = RGB(colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue);
575 c1 = RGB(colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue);
577 test_color(hdcmem, DIBINDEX(0), c0);
578 test_color(hdcmem, DIBINDEX(1), c1);
579 test_color(hdcmem, DIBINDEX(2), c0);
580 test_color(hdcmem, PALETTEINDEX(0), c0);
581 test_color(hdcmem, PALETTEINDEX(1), c0);
582 test_color(hdcmem, PALETTEINDEX(2), c0);
583 test_color(hdcmem, PALETTERGB(colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue), c0);
584 test_color(hdcmem, PALETTERGB(colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue), c1);
585 test_color(hdcmem, PALETTERGB(0, 0, 0), c0);
586 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0);
587 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1);
589 SelectObject(hdcmem, oldbm);
592 colors[0].rgbRed = 0xff;
593 colors[0].rgbGreen = 0xff;
594 colors[0].rgbBlue = 0xff;
595 colors[1].rgbRed = 0;
596 colors[1].rgbGreen = 0;
597 colors[1].rgbBlue = 0;
599 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
600 ok(hdib != NULL, "CreateDIBSection failed\n");
602 test_dib_info(hdib, bits, &pbmi->bmiHeader);
604 oldbm = SelectObject(hdcmem, hdib);
606 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
607 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
608 ok(!memcmp(rgb, colors, 2 * sizeof(RGBQUAD)),
609 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
610 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
611 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
613 SelectObject(hdcmem, oldbm);
614 test_dib_info(hdib, bits, &pbmi->bmiHeader);
617 pbmi->bmiHeader.biBitCount = 4;
618 for (i = 0; i < 16; i++) {
619 colors[i].rgbRed = i;
620 colors[i].rgbGreen = 16-i;
621 colors[i].rgbBlue = 0;
623 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
624 ok(hdib != NULL, "CreateDIBSection failed\n");
625 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
626 ok(dibsec.dsBmih.biClrUsed == 16,
627 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
628 test_dib_info(hdib, bits, &pbmi->bmiHeader);
631 pbmi->bmiHeader.biBitCount = 8;
633 for (i = 0; i < 128; i++) {
634 colors[i].rgbRed = 255 - i * 2;
635 colors[i].rgbGreen = i * 2;
636 colors[i].rgbBlue = 0;
637 colors[255 - i].rgbRed = 0;
638 colors[255 - i].rgbGreen = i * 2;
639 colors[255 - i].rgbBlue = 255 - i * 2;
641 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
642 ok(hdib != NULL, "CreateDIBSection failed\n");
643 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
644 ok(dibsec.dsBmih.biClrUsed == 256,
645 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
647 oldbm = SelectObject(hdcmem, hdib);
649 for (i = 0; i < 256; i++) {
650 test_color(hdcmem, DIBINDEX(i), RGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue));
651 test_color(hdcmem, PALETTERGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue),
652 RGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue));
655 SelectObject(hdcmem, oldbm);
656 test_dib_info(hdib, bits, &pbmi->bmiHeader);
659 pbmi->bmiHeader.biBitCount = 1;
661 /* Now create a palette and a palette indexed dib section */
662 memset(plogpal, 0, sizeof(logpalbuf));
663 plogpal->palVersion = 0x300;
664 plogpal->palNumEntries = 2;
665 palent[0].peRed = 0xff;
666 palent[0].peBlue = 0xff;
667 palent[1].peGreen = 0xff;
669 index = (WORD*)pbmi->bmiColors;
672 hpal = CreatePalette(plogpal);
673 ok(hpal != NULL, "CreatePalette failed\n");
674 oldpal = SelectPalette(hdc, hpal, TRUE);
675 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
676 ok(hdib != NULL, "CreateDIBSection failed\n");
677 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
678 ok(dibsec.dsBmih.biClrUsed == 2, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
680 /* The colour table has already been grabbed from the dc, so we select back the
683 SelectPalette(hdc, oldpal, TRUE);
684 oldbm = SelectObject(hdcmem, hdib);
685 oldpal = SelectPalette(hdcmem, hpal, TRUE);
687 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
688 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
689 ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
690 rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
691 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
692 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
693 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
695 c0 = RGB(palent[0].peRed, palent[0].peGreen, palent[0].peBlue);
696 c1 = RGB(palent[1].peRed, palent[1].peGreen, palent[1].peBlue);
698 test_color(hdcmem, DIBINDEX(0), c0);
699 test_color(hdcmem, DIBINDEX(1), c1);
700 test_color(hdcmem, DIBINDEX(2), c0);
701 test_color(hdcmem, PALETTEINDEX(0), c0);
702 test_color(hdcmem, PALETTEINDEX(1), c1);
703 test_color(hdcmem, PALETTEINDEX(2), c0);
704 test_color(hdcmem, PALETTERGB(palent[0].peRed, palent[0].peGreen, palent[0].peBlue), c0);
705 test_color(hdcmem, PALETTERGB(palent[1].peRed, palent[1].peGreen, palent[1].peBlue), c1);
706 test_color(hdcmem, PALETTERGB(0, 0, 0), c1);
707 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0);
708 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0);
709 test_color(hdcmem, PALETTERGB(0, 1, 0), c1);
710 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1);
711 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0);
713 /* Bottom and 2nd row from top green, everything else magenta */
714 bits[0] = bits[1] = 0xff;
715 bits[13 * 4] = bits[13*4 + 1] = 0xff;
717 test_dib_info(hdib, bits, &pbmi->bmiHeader);
719 pbmi->bmiHeader.biBitCount = 32;
721 hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
722 ok(hdib2 != NULL, "CreateDIBSection failed\n");
723 hdcmem2 = CreateCompatibleDC(hdc);
724 oldbm2 = SelectObject(hdcmem2, hdib2);
726 BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
728 ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
729 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
731 SelectObject(hdcmem2, oldbm2);
732 test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
735 SelectObject(hdcmem, oldbm);
736 SelectPalette(hdcmem, oldpal, TRUE);
741 pbmi->bmiHeader.biBitCount = 8;
743 memset(plogpal, 0, sizeof(logpalbuf));
744 plogpal->palVersion = 0x300;
745 plogpal->palNumEntries = 256;
747 for (i = 0; i < 128; i++) {
748 palent[i].peRed = 255 - i * 2;
749 palent[i].peBlue = i * 2;
750 palent[i].peGreen = 0;
751 palent[255 - i].peRed = 0;
752 palent[255 - i].peGreen = i * 2;
753 palent[255 - i].peBlue = 255 - i * 2;
756 index = (WORD*)pbmi->bmiColors;
757 for (i = 0; i < 256; i++) {
761 hpal = CreatePalette(plogpal);
762 ok(hpal != NULL, "CreatePalette failed\n");
763 oldpal = SelectPalette(hdc, hpal, TRUE);
764 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
765 ok(hdib != NULL, "CreateDIBSection failed\n");
766 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
767 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
769 test_dib_info(hdib, bits, &pbmi->bmiHeader);
771 SelectPalette(hdc, oldpal, TRUE);
772 oldbm = SelectObject(hdcmem, hdib);
773 oldpal = SelectPalette(hdcmem, hpal, TRUE);
775 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
776 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
777 for (i = 0; i < 256; i++) {
778 ok(rgb[i].rgbRed == palent[i].peRed &&
779 rgb[i].rgbBlue == palent[i].peBlue &&
780 rgb[i].rgbGreen == palent[i].peGreen,
781 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
782 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
785 for (i = 0; i < 256; i++) {
786 test_color(hdcmem, DIBINDEX(i), RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
787 test_color(hdcmem, PALETTEINDEX(i), RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
788 test_color(hdcmem, PALETTERGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue),
789 RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
792 SelectPalette(hdcmem, oldpal, TRUE);
793 SelectObject(hdcmem, oldbm);
802 static void test_dib_formats(void)
807 int planes, bpp, compr;
813 bi = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
815 memdc = CreateCompatibleDC( 0 );
816 hbmp = CreateCompatibleBitmap( hdc, 10, 10 );
818 memset( data, 0xaa, sizeof(data) );
820 for (bpp = 0; bpp <= 64; bpp++)
822 for (planes = 0; planes <= 64; planes++)
824 for (compr = 0; compr < 8; compr++)
831 case 24: expect_ok = (compr == BI_RGB); break;
833 case 32: expect_ok = (compr == BI_RGB || compr == BI_BITFIELDS); break;
834 default: expect_ok = FALSE; break;
837 memset( bi, 0, sizeof(bi->bmiHeader) );
838 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
839 bi->bmiHeader.biWidth = 2;
840 bi->bmiHeader.biHeight = 2;
841 bi->bmiHeader.biPlanes = planes;
842 bi->bmiHeader.biBitCount = bpp;
843 bi->bmiHeader.biCompression = compr;
844 bi->bmiHeader.biSizeImage = 0;
845 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
846 ret = GetDIBits(hdc, hbmp, 0, 0, data, bi, DIB_RGB_COLORS);
847 if (expect_ok || (!bpp && compr != BI_JPEG && compr != BI_PNG) ||
848 (bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8))
849 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
851 ok( !ret || broken(!bpp && (compr == BI_JPEG || compr == BI_PNG)), /* nt4 */
852 "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
854 /* all functions check planes except GetDIBits with 0 lines */
855 if (!planes) expect_ok = FALSE;
856 memset( bi, 0, sizeof(bi->bmiHeader) );
857 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
858 bi->bmiHeader.biWidth = 2;
859 bi->bmiHeader.biHeight = 2;
860 bi->bmiHeader.biPlanes = planes;
861 bi->bmiHeader.biBitCount = bpp;
862 bi->bmiHeader.biCompression = compr;
863 bi->bmiHeader.biSizeImage = 0;
864 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
866 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
867 if (expect_ok && (planes == 1 || planes * bpp <= 16))
868 ok( hdib != NULL, "CreateDIBSection failed for %u/%u/%u\n", bpp, planes, compr );
870 ok( hdib == NULL, "CreateDIBSection succeeded for %u/%u/%u\n", bpp, planes, compr );
871 if (hdib) DeleteObject( hdib );
873 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, data, bi, DIB_RGB_COLORS );
874 /* no sanity checks in CreateDIBitmap except compression */
875 if (compr == BI_JPEG || compr == BI_PNG)
876 ok( hdib == NULL || broken(hdib != NULL), /* nt4 */
877 "CreateDIBitmap succeeded for %u/%u/%u\n", bpp, planes, compr );
879 ok( hdib != NULL, "CreateDIBitmap failed for %u/%u/%u\n", bpp, planes, compr );
880 if (hdib) DeleteObject( hdib );
882 /* RLE needs a size */
883 bi->bmiHeader.biSizeImage = 0;
884 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
886 ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
889 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
890 "SetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
891 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
893 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
896 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
897 "SetDIBitsToDevice succeeded for %u/%u/%u\n", bpp, planes, compr );
898 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
900 ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
903 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
904 "StretchDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
906 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
908 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
910 ok( !ret, "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
911 ok( bi->bmiHeader.biBitCount == bpp, "GetDIBits modified bpp %u/%u\n",
912 bpp, bi->bmiHeader.biBitCount );
914 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
915 bi->bmiHeader.biWidth = 2;
916 bi->bmiHeader.biHeight = 2;
917 bi->bmiHeader.biPlanes = planes;
918 bi->bmiHeader.biBitCount = bpp;
919 bi->bmiHeader.biCompression = compr;
920 bi->bmiHeader.biSizeImage = 1;
921 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
922 /* RLE allowed with valid biSizeImage */
923 if ((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)) expect_ok = TRUE;
925 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
927 ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
929 ok( !ret, "SetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
930 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
932 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
934 ok( !ret, "SetDIBitsToDevice succeeded for %u/%u/%u\n", bpp, planes, compr );
935 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
937 ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
939 ok( !ret, "StretchDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
941 bi->bmiHeader.biSizeImage = 0;
942 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
943 if (expect_ok || !bpp)
944 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
946 ok( !ret, "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
951 memset( bi, 0, sizeof(bi->bmiHeader) );
952 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
953 bi->bmiHeader.biWidth = 2;
954 bi->bmiHeader.biHeight = 2;
955 bi->bmiHeader.biPlanes = 1;
956 bi->bmiHeader.biBitCount = 16;
957 bi->bmiHeader.biCompression = BI_BITFIELDS;
958 bi->bmiHeader.biSizeImage = 0;
959 *(DWORD *)&bi->bmiColors[0] = 0;
960 *(DWORD *)&bi->bmiColors[1] = 0;
961 *(DWORD *)&bi->bmiColors[2] = 0;
963 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
964 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
965 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
966 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
967 /* other functions don't check */
968 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
969 ok( hdib != NULL, "CreateDIBitmap failed with null bitfields\n" );
970 DeleteObject( hdib );
971 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
972 ok( ret, "SetDIBitsToDevice failed with null bitfields\n" );
973 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
974 ok( ret, "StretchDIBits failed with null bitfields\n" );
975 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
976 ok( ret, "GetDIBits failed with null bitfields\n" );
977 bi->bmiHeader.biPlanes = 1;
978 bi->bmiHeader.biBitCount = 16;
979 bi->bmiHeader.biCompression = BI_BITFIELDS;
980 bi->bmiHeader.biSizeImage = 0;
981 *(DWORD *)&bi->bmiColors[0] = 0;
982 *(DWORD *)&bi->bmiColors[1] = 0;
983 *(DWORD *)&bi->bmiColors[2] = 0;
984 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
985 ok( ret, "GetDIBits failed with null bitfields\n" );
987 /* all fields must be non-zero */
988 *(DWORD *)&bi->bmiColors[0] = 3;
989 *(DWORD *)&bi->bmiColors[1] = 0;
990 *(DWORD *)&bi->bmiColors[2] = 7;
991 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
992 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
993 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
994 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
996 /* garbage is ok though */
997 *(DWORD *)&bi->bmiColors[0] = 0x55;
998 *(DWORD *)&bi->bmiColors[1] = 0x44;
999 *(DWORD *)&bi->bmiColors[2] = 0x33;
1000 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1001 ok( hdib != NULL, "CreateDIBSection failed with bad bitfields\n" );
1002 if (hdib) DeleteObject( hdib );
1003 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1004 ok( ret, "SetDIBits failed with bad bitfields\n" );
1006 bi->bmiHeader.biWidth = -2;
1007 bi->bmiHeader.biHeight = 2;
1008 bi->bmiHeader.biBitCount = 32;
1009 bi->bmiHeader.biCompression = BI_RGB;
1010 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1011 ok( hdib == NULL, "CreateDIBSection succeeded with negative width\n" );
1012 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1013 ok( hdib == NULL, "CreateDIBitmap succeeded with negative width\n" );
1014 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1015 ok( !ret, "SetDIBits succeeded with negative width\n" );
1016 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1017 ok( !ret, "SetDIBitsToDevice succeeded with negative width\n" );
1018 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1019 ok( !ret, "StretchDIBits succeeded with negative width\n" );
1020 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1021 ok( !ret, "GetDIBits succeeded with negative width\n" );
1022 bi->bmiHeader.biWidth = -2;
1023 bi->bmiHeader.biHeight = 2;
1024 bi->bmiHeader.biBitCount = 32;
1025 bi->bmiHeader.biCompression = BI_RGB;
1026 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1027 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with negative width\n" );
1029 bi->bmiHeader.biWidth = 0;
1030 bi->bmiHeader.biHeight = 2;
1031 bi->bmiHeader.biBitCount = 32;
1032 bi->bmiHeader.biCompression = BI_RGB;
1033 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1034 ok( hdib == NULL, "CreateDIBSection succeeded with zero width\n" );
1035 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1036 ok( hdib != NULL, "CreateDIBitmap failed with zero width\n" );
1037 DeleteObject( hdib );
1038 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1039 ok( !ret || broken(ret), /* nt4 */ "SetDIBits succeeded with zero width\n" );
1040 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1041 ok( !ret || broken(ret), /* nt4 */ "SetDIBitsToDevice succeeded with zero width\n" );
1042 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1043 ok( !ret || broken(ret), /* nt4 */ "StretchDIBits succeeded with zero width\n" );
1044 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1045 ok( !ret, "GetDIBits succeeded with zero width\n" );
1046 bi->bmiHeader.biWidth = 0;
1047 bi->bmiHeader.biHeight = 2;
1048 bi->bmiHeader.biBitCount = 32;
1049 bi->bmiHeader.biCompression = BI_RGB;
1050 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1051 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero width\n" );
1053 bi->bmiHeader.biWidth = 2;
1054 bi->bmiHeader.biHeight = 0;
1055 bi->bmiHeader.biBitCount = 32;
1056 bi->bmiHeader.biCompression = BI_RGB;
1057 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1058 ok( hdib == NULL, "CreateDIBSection succeeded with zero height\n" );
1059 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1060 ok( hdib != NULL, "CreateDIBitmap failed with zero height\n" );
1061 DeleteObject( hdib );
1062 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1063 ok( !ret, "SetDIBits succeeded with zero height\n" );
1064 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1065 ok( !ret, "SetDIBitsToDevice succeeded with zero height\n" );
1066 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1067 ok( !ret, "StretchDIBits succeeded with zero height\n" );
1068 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1069 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1070 bi->bmiHeader.biWidth = 2;
1071 bi->bmiHeader.biHeight = 0;
1072 bi->bmiHeader.biBitCount = 32;
1073 bi->bmiHeader.biCompression = BI_RGB;
1074 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1075 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1078 DeleteObject( hbmp );
1079 ReleaseDC( 0, hdc );
1080 HeapFree( GetProcessHeap(), 0, bi );
1083 static void test_mono_dibsection(void)
1086 HBITMAP old_bm, mono_ds;
1087 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
1088 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
1089 RGBQUAD *colors = pbmi->bmiColors;
1096 memdc = CreateCompatibleDC(hdc);
1098 memset(pbmi, 0, sizeof(bmibuf));
1099 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
1100 pbmi->bmiHeader.biHeight = 10;
1101 pbmi->bmiHeader.biWidth = 10;
1102 pbmi->bmiHeader.biBitCount = 1;
1103 pbmi->bmiHeader.biPlanes = 1;
1104 pbmi->bmiHeader.biCompression = BI_RGB;
1105 colors[0].rgbRed = 0xff;
1106 colors[0].rgbGreen = 0xff;
1107 colors[0].rgbBlue = 0xff;
1108 colors[1].rgbRed = 0x0;
1109 colors[1].rgbGreen = 0x0;
1110 colors[1].rgbBlue = 0x0;
1113 * First dib section is 'inverted' ie color[0] is white, color[1] is black
1116 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1117 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1118 old_bm = SelectObject(memdc, mono_ds);
1120 /* black border, white interior */
1121 Rectangle(memdc, 0, 0, 10, 10);
1122 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1123 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1125 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1127 memset(bits, 0, sizeof(bits));
1130 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1131 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1133 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1135 colors[0].rgbRed = 0x0;
1136 colors[0].rgbGreen = 0x0;
1137 colors[0].rgbBlue = 0x0;
1138 colors[1].rgbRed = 0xff;
1139 colors[1].rgbGreen = 0xff;
1140 colors[1].rgbBlue = 0xff;
1142 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1143 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1145 SelectObject(memdc, old_bm);
1146 DeleteObject(mono_ds);
1149 * Next dib section is 'normal' ie color[0] is black, color[1] is white
1152 colors[0].rgbRed = 0x0;
1153 colors[0].rgbGreen = 0x0;
1154 colors[0].rgbBlue = 0x0;
1155 colors[1].rgbRed = 0xff;
1156 colors[1].rgbGreen = 0xff;
1157 colors[1].rgbBlue = 0xff;
1159 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1160 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1161 old_bm = SelectObject(memdc, mono_ds);
1163 /* black border, white interior */
1164 Rectangle(memdc, 0, 0, 10, 10);
1165 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
1166 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
1168 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
1170 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1171 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1173 /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
1175 colors[0].rgbRed = 0xff;
1176 colors[0].rgbGreen = 0xff;
1177 colors[0].rgbBlue = 0xff;
1178 colors[1].rgbRed = 0x0;
1179 colors[1].rgbGreen = 0x0;
1180 colors[1].rgbBlue = 0x0;
1182 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1183 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1186 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
1189 colors[0].rgbRed = 0xff;
1190 colors[0].rgbGreen = 0xff;
1191 colors[0].rgbBlue = 0xff;
1192 colors[1].rgbRed = 0x0;
1193 colors[1].rgbGreen = 0x0;
1194 colors[1].rgbBlue = 0x0;
1195 num = SetDIBColorTable(memdc, 0, 2, colors);
1196 ok(num == 2, "num = %d\n", num);
1198 /* black border, white interior */
1199 Rectangle(memdc, 0, 0, 10, 10);
1200 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1201 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1203 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1205 memset(bits, 0, sizeof(bits));
1208 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1209 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1211 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1213 colors[0].rgbRed = 0x0;
1214 colors[0].rgbGreen = 0x0;
1215 colors[0].rgbBlue = 0x0;
1216 colors[1].rgbRed = 0xff;
1217 colors[1].rgbGreen = 0xff;
1218 colors[1].rgbBlue = 0xff;
1220 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1221 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1223 SelectObject(memdc, old_bm);
1224 DeleteObject(mono_ds);
1227 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
1230 colors[0].rgbRed = 0xff;
1231 colors[0].rgbGreen = 0x0;
1232 colors[0].rgbBlue = 0x0;
1233 colors[1].rgbRed = 0xfe;
1234 colors[1].rgbGreen = 0x0;
1235 colors[1].rgbBlue = 0x0;
1237 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1238 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1239 old_bm = SelectObject(memdc, mono_ds);
1241 /* black border, white interior */
1242 Rectangle(memdc, 0, 0, 10, 10);
1243 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1244 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1246 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1248 colors[0].rgbRed = 0x0;
1249 colors[0].rgbGreen = 0x0;
1250 colors[0].rgbBlue = 0x0;
1251 colors[1].rgbRed = 0xff;
1252 colors[1].rgbGreen = 0xff;
1253 colors[1].rgbBlue = 0xff;
1255 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1256 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1258 /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
1260 colors[0].rgbRed = 0xff;
1261 colors[0].rgbGreen = 0xff;
1262 colors[0].rgbBlue = 0xff;
1263 colors[1].rgbRed = 0x0;
1264 colors[1].rgbGreen = 0x0;
1265 colors[1].rgbBlue = 0x0;
1267 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1268 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1270 SelectObject(memdc, old_bm);
1271 DeleteObject(mono_ds);
1277 static void test_bitmap(void)
1279 char buf[256], buf_cmp[256];
1280 HBITMAP hbmp, hbmp_old;
1286 hdc = CreateCompatibleDC(0);
1289 SetLastError(0xdeadbeef);
1290 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1293 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1294 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1295 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1300 SetLastError(0xdeadbeef);
1301 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1304 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1305 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1306 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1311 SetLastError(0xdeadbeef);
1312 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1313 ok(!hbmp, "CreateBitmap should fail\n");
1315 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1316 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1320 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1321 assert(hbmp != NULL);
1323 ret = GetObject(hbmp, sizeof(bm), &bm);
1324 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1326 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1327 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1328 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1329 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1330 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1331 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1332 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1334 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1335 assert(sizeof(buf) == sizeof(buf_cmp));
1337 ret = GetBitmapBits(hbmp, 0, NULL);
1338 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1340 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1341 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1343 memset(buf, 0xAA, sizeof(buf));
1344 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1345 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1346 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1348 hbmp_old = SelectObject(hdc, hbmp);
1350 ret = GetObject(hbmp, sizeof(bm), &bm);
1351 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1353 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1354 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1355 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1356 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1357 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1358 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1359 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1361 memset(buf, 0xAA, sizeof(buf));
1362 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1363 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1364 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1366 hbmp_old = SelectObject(hdc, hbmp_old);
1367 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1369 /* test various buffer sizes for GetObject */
1370 ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
1371 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1373 ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1374 ok(ret == 0, "%d != 0\n", ret);
1376 ret = GetObject(hbmp, 0, &bm);
1377 ok(ret == 0, "%d != 0\n", ret);
1379 ret = GetObject(hbmp, 1, &bm);
1380 ok(ret == 0, "%d != 0\n", ret);
1386 static void test_bmBits(void)
1392 memset(bits, 0, sizeof(bits));
1393 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1394 ok(hbmp != NULL, "CreateBitmap failed\n");
1396 memset(&bmp, 0xFF, sizeof(bmp));
1397 ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1398 "GetObject failed or returned a wrong structure size\n");
1399 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1404 static void test_GetDIBits_selected_DIB(UINT bpp)
1411 UINT dib_size, dib32_size;
1418 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1419 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1421 /* Create a DIB section with a color table */
1423 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1424 info->bmiHeader.biWidth = 32;
1425 info->bmiHeader.biHeight = 32;
1426 info->bmiHeader.biPlanes = 1;
1427 info->bmiHeader.biBitCount = bpp;
1428 info->bmiHeader.biCompression = BI_RGB;
1429 info->bmiHeader.biXPelsPerMeter = 0;
1430 info->bmiHeader.biYPelsPerMeter = 0;
1431 info->bmiHeader.biClrUsed = 0;
1432 info->bmiHeader.biClrImportant = 0;
1434 for (i=0; i < (1u << bpp); i++)
1436 BYTE c = i * (1 << (8 - bpp));
1437 info->bmiColors[i].rgbRed = c;
1438 info->bmiColors[i].rgbGreen = c;
1439 info->bmiColors[i].rgbBlue = c;
1440 info->bmiColors[i].rgbReserved = 0;
1443 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1444 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1445 dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1447 /* Set the bits of the DIB section */
1448 for (i=0; i < dib_size; i++)
1450 ((BYTE *)bits)[i] = i % 256;
1453 /* Select the DIB into a DC */
1454 dib_dc = CreateCompatibleDC(NULL);
1455 old_bmp = SelectObject(dib_dc, dib);
1456 dc = CreateCompatibleDC(NULL);
1457 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
1459 /* Copy the DIB attributes but not the color table */
1460 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1462 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1463 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1465 /* Compare the color table and the bits */
1466 for (i=0; i < (1u << bpp); i++)
1467 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1468 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1469 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1470 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1471 "color table entry %d differs (bpp %d)\n", i, bpp );
1473 ok( !memcmp( bits, bits2, dib_size ), "bit mismatch (bpp %d)\n", bpp );
1475 /* Test various combinations of lines = 0 and bits2 = NULL */
1476 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1477 res = GetDIBits( dc, dib, 0, 0, bits2, info2, DIB_RGB_COLORS );
1478 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1479 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1480 "color table mismatch (bpp %d)\n", bpp );
1482 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1483 res = GetDIBits( dc, dib, 0, 0, NULL, info2, DIB_RGB_COLORS );
1484 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1485 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1486 "color table mismatch (bpp %d)\n", bpp );
1488 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1489 res = GetDIBits( dc, dib, 0, info->bmiHeader.biHeight, NULL, info2, DIB_RGB_COLORS );
1490 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1491 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1492 "color table mismatch (bpp %d)\n", bpp );
1494 /* Map into a 32bit-DIB */
1495 info2->bmiHeader.biBitCount = 32;
1496 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1497 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1499 /* Check if last pixel was set */
1500 pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
1501 ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
1503 HeapFree(GetProcessHeap(), 0, bits2);
1506 SelectObject(dib_dc, old_bmp);
1509 HeapFree(GetProcessHeap(), 0, info2);
1510 HeapFree(GetProcessHeap(), 0, info);
1513 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1527 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1528 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1530 width = height = 16;
1532 /* Create a DDB (device-dependent bitmap) */
1536 ddb = CreateBitmap(width, height, 1, 1, NULL);
1540 HDC screen_dc = GetDC(NULL);
1541 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1542 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1543 ReleaseDC(NULL, screen_dc);
1546 /* Set the pixels */
1547 ddb_dc = CreateCompatibleDC(NULL);
1548 old_bmp = SelectObject(ddb_dc, ddb);
1549 for (i = 0; i < width; i++)
1551 for (j=0; j < height; j++)
1553 BYTE c = (i * width + j) % 256;
1554 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1557 SelectObject(ddb_dc, old_bmp);
1559 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1560 info->bmiHeader.biWidth = width;
1561 info->bmiHeader.biHeight = height;
1562 info->bmiHeader.biPlanes = 1;
1563 info->bmiHeader.biBitCount = bpp;
1564 info->bmiHeader.biCompression = BI_RGB;
1566 dc = CreateCompatibleDC(NULL);
1568 /* Fill in biSizeImage */
1569 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1570 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1572 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1573 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1576 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1577 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1579 /* Copy the DIB attributes but not the color table */
1580 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1582 /* Select the DDB into another DC */
1583 old_bmp = SelectObject(ddb_dc, ddb);
1586 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1587 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1589 /* Compare the color table and the bits */
1592 for (i=0; i < (1u << bpp); i++)
1593 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1594 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1595 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1596 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1597 "color table entry %d differs (bpp %d)\n", i, bpp );
1600 ok( !memcmp( bits, bits2, info->bmiHeader.biSizeImage ), "bit mismatch (bpp %d)\n", bpp );
1602 /* Test the palette */
1603 if (info2->bmiHeader.biBitCount <= 8)
1605 WORD *colors = (WORD*)info2->bmiColors;
1607 /* Get the palette indices */
1608 res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1609 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1611 for (i = 0; i < (1 << info->bmiHeader.biBitCount); i++)
1612 ok( colors[i] == i, "%d: got %d (bpp %d)\n", i, colors[i], bpp );
1615 HeapFree(GetProcessHeap(), 0, bits2);
1616 HeapFree(GetProcessHeap(), 0, bits);
1619 SelectObject(ddb_dc, old_bmp);
1622 HeapFree(GetProcessHeap(), 0, info2);
1623 HeapFree(GetProcessHeap(), 0, info);
1626 static void test_GetDIBits(void)
1628 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1629 static const BYTE bmp_bits_1[16 * 2] =
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,
1634 0xff,0xff, 0,0, 0xff,0xff, 0,0
1636 /* 4-bytes aligned 1-bit DIB data: 16x16 */
1637 static const BYTE dib_bits_1[16 * 4] =
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,
1642 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1644 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1645 static const BYTE bmp_bits_24[16 * 16*3] =
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1659 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1660 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1661 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1662 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1663 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1664 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1665 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1666 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1667 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1668 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1669 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1670 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1671 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1672 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1673 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1674 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1675 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1676 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1677 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1678 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1680 /* 4-bytes aligned 24-bit DIB data: 16x16 */
1681 static const BYTE dib_bits_24[16 * 16*3] =
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1685 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1686 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1687 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1688 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1689 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1690 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1691 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1692 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1693 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1694 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1695 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1696 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1697 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1698 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1699 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1700 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1701 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1702 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1703 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1704 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1705 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1706 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1707 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1708 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1709 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1710 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1711 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1712 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1713 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1714 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1719 int i, bytes, lines;
1721 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1722 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1723 RGBQUAD *colors = bi->bmiColors;
1724 PALETTEENTRY pal_ents[20];
1728 /* 1-bit source bitmap data */
1729 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1730 ok(hbmp != 0, "CreateBitmap failed\n");
1732 memset(&bm, 0xAA, sizeof(bm));
1733 bytes = GetObject(hbmp, sizeof(bm), &bm);
1734 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1735 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1736 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1737 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1738 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1739 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1740 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1741 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1743 bytes = GetBitmapBits(hbmp, 0, NULL);
1744 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1745 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1746 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1747 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1749 /* retrieve 1-bit DIB data */
1750 memset(bi, 0, sizeof(*bi));
1751 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1752 bi->bmiHeader.biWidth = bm.bmWidth;
1753 bi->bmiHeader.biHeight = bm.bmHeight;
1754 bi->bmiHeader.biPlanes = 1;
1755 bi->bmiHeader.biBitCount = 1;
1756 bi->bmiHeader.biCompression = BI_RGB;
1757 bi->bmiHeader.biSizeImage = 0;
1758 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1759 SetLastError(0xdeadbeef);
1760 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1761 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1762 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1763 broken(GetLastError() == 0xdeadbeef), /* winnt */
1764 "wrong error %u\n", GetLastError());
1765 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1767 memset(buf, 0xAA, sizeof(buf));
1768 SetLastError(0xdeadbeef);
1769 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1770 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1771 lines, bm.bmHeight, GetLastError());
1772 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1774 /* the color table consists of black and white */
1775 ok(colors[0].rgbRed == 0 && colors[0].rgbGreen == 0 &&
1776 colors[0].rgbBlue == 0 && colors[0].rgbReserved == 0,
1777 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1778 colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue, colors[0].rgbReserved);
1779 ok(colors[1].rgbRed == 0xff && colors[1].rgbGreen == 0xff &&
1780 colors[1].rgbBlue == 0xff && colors[1].rgbReserved == 0,
1781 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1782 colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue, colors[1].rgbReserved);
1783 for (i = 2; i < 256; i++)
1785 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
1786 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
1787 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1788 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
1791 /* returned bits are DWORD aligned and upside down */
1792 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1794 /* Test the palette indices */
1795 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1796 SetLastError(0xdeadbeef);
1797 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1798 ok(((WORD*)colors)[0] == 0, "Color 0 is %d\n", ((WORD*)colors)[0]);
1799 ok(((WORD*)colors)[1] == 1, "Color 1 is %d\n", ((WORD*)colors)[1]);
1800 for (i = 2; i < 256; i++)
1801 ok(((WORD*)colors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)colors)[1]);
1803 /* retrieve 24-bit DIB data */
1804 memset(bi, 0, sizeof(*bi));
1805 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1806 bi->bmiHeader.biWidth = bm.bmWidth;
1807 bi->bmiHeader.biHeight = bm.bmHeight;
1808 bi->bmiHeader.biPlanes = 1;
1809 bi->bmiHeader.biBitCount = 24;
1810 bi->bmiHeader.biCompression = BI_RGB;
1811 bi->bmiHeader.biSizeImage = 0;
1812 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1813 memset(buf, 0xAA, sizeof(buf));
1814 SetLastError(0xdeadbeef);
1815 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1816 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1817 lines, bm.bmHeight, GetLastError());
1818 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1820 /* the color table doesn't exist for 24-bit images */
1821 for (i = 0; i < 256; i++)
1823 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
1824 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
1825 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1826 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
1829 /* returned bits are DWORD aligned and upside down */
1830 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1833 /* 24-bit source bitmap data */
1834 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1835 ok(hbmp != 0, "CreateBitmap failed\n");
1836 SetLastError(0xdeadbeef);
1837 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1838 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1839 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1840 lines, bm.bmHeight, GetLastError());
1842 memset(&bm, 0xAA, sizeof(bm));
1843 bytes = GetObject(hbmp, sizeof(bm), &bm);
1844 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1845 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1846 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1847 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1848 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1849 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1850 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1851 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1853 bytes = GetBitmapBits(hbmp, 0, NULL);
1854 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
1855 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1856 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1857 bm.bmWidthBytes * bm.bmHeight, bytes);
1859 /* retrieve 1-bit DIB data */
1860 memset(bi, 0, sizeof(*bi));
1861 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1862 bi->bmiHeader.biWidth = bm.bmWidth;
1863 bi->bmiHeader.biHeight = bm.bmHeight;
1864 bi->bmiHeader.biPlanes = 1;
1865 bi->bmiHeader.biBitCount = 1;
1866 bi->bmiHeader.biCompression = BI_RGB;
1867 bi->bmiHeader.biSizeImage = 0;
1868 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1869 memset(buf, 0xAA, sizeof(buf));
1870 SetLastError(0xdeadbeef);
1871 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1872 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1873 lines, bm.bmHeight, GetLastError());
1874 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1876 /* the color table consists of black and white */
1877 ok(colors[0].rgbRed == 0 && colors[0].rgbGreen == 0 &&
1878 colors[0].rgbBlue == 0 && colors[0].rgbReserved == 0,
1879 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1880 colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue, colors[0].rgbReserved);
1881 ok(colors[1].rgbRed == 0xff && colors[1].rgbGreen == 0xff &&
1882 colors[1].rgbBlue == 0xff && colors[1].rgbReserved == 0,
1883 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1884 colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue, colors[1].rgbReserved);
1885 for (i = 2; i < 256; i++)
1887 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
1888 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
1889 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1890 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
1893 /* returned bits are DWORD aligned and upside down */
1894 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1896 /* Test the palette indices */
1897 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1898 SetLastError(0xdeadbeef);
1899 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1900 ok(((WORD*)colors)[0] == 0, "Color 0 is %d\n", ((WORD*)colors)[0]);
1901 ok(((WORD*)colors)[1] == 1, "Color 1 is %d\n", ((WORD*)colors)[1]);
1902 for (i = 2; i < 256; i++)
1903 ok(((WORD*)colors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)colors)[i]);
1905 /* retrieve 4-bit DIB data */
1906 memset(bi, 0, sizeof(*bi));
1907 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1908 bi->bmiHeader.biWidth = bm.bmWidth;
1909 bi->bmiHeader.biHeight = bm.bmHeight;
1910 bi->bmiHeader.biPlanes = 1;
1911 bi->bmiHeader.biBitCount = 4;
1912 bi->bmiHeader.biCompression = BI_RGB;
1913 bi->bmiHeader.biSizeImage = 0;
1914 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1915 memset(buf, 0xAA, sizeof(buf));
1916 SetLastError(0xdeadbeef);
1917 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1918 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1919 lines, bm.bmHeight, GetLastError());
1921 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
1923 for (i = 0; i < 16; i++)
1926 int entry = i < 8 ? i : i + 4;
1928 if(entry == 7) entry = 12;
1929 else if(entry == 12) entry = 7;
1931 expect.rgbRed = pal_ents[entry].peRed;
1932 expect.rgbGreen = pal_ents[entry].peGreen;
1933 expect.rgbBlue = pal_ents[entry].peBlue;
1934 expect.rgbReserved = 0;
1936 ok(!memcmp(colors + i, &expect, sizeof(expect)),
1937 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
1938 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
1939 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
1942 /* retrieve 8-bit DIB data */
1943 memset(bi, 0, sizeof(*bi));
1944 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1945 bi->bmiHeader.biWidth = bm.bmWidth;
1946 bi->bmiHeader.biHeight = bm.bmHeight;
1947 bi->bmiHeader.biPlanes = 1;
1948 bi->bmiHeader.biBitCount = 8;
1949 bi->bmiHeader.biCompression = BI_RGB;
1950 bi->bmiHeader.biSizeImage = 0;
1951 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1952 memset(buf, 0xAA, sizeof(buf));
1953 SetLastError(0xdeadbeef);
1954 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1955 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1956 lines, bm.bmHeight, GetLastError());
1958 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
1960 for (i = 0; i < 256; i++)
1964 if (i < 10 || i >= 246)
1966 int entry = i < 10 ? i : i - 236;
1967 expect.rgbRed = pal_ents[entry].peRed;
1968 expect.rgbGreen = pal_ents[entry].peGreen;
1969 expect.rgbBlue = pal_ents[entry].peBlue;
1973 expect.rgbRed = (i & 0x07) << 5;
1974 expect.rgbGreen = (i & 0x38) << 2;
1975 expect.rgbBlue = i & 0xc0;
1977 expect.rgbReserved = 0;
1979 ok(!memcmp(colors + i, &expect, sizeof(expect)),
1980 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
1981 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
1982 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
1985 /* retrieve 24-bit DIB data */
1986 memset(bi, 0, sizeof(*bi));
1987 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1988 bi->bmiHeader.biWidth = bm.bmWidth;
1989 bi->bmiHeader.biHeight = bm.bmHeight;
1990 bi->bmiHeader.biPlanes = 1;
1991 bi->bmiHeader.biBitCount = 24;
1992 bi->bmiHeader.biCompression = BI_RGB;
1993 bi->bmiHeader.biSizeImage = 0;
1994 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1995 memset(buf, 0xAA, sizeof(buf));
1996 SetLastError(0xdeadbeef);
1997 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1998 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1999 lines, bm.bmHeight, GetLastError());
2000 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2002 /* the color table doesn't exist for 24-bit images */
2003 for (i = 0; i < 256; i++)
2005 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2006 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2007 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2008 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2011 /* returned bits are DWORD aligned and upside down */
2012 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2018 static void test_GetDIBits_BI_BITFIELDS(void)
2020 /* Try a screen resolution detection technique
2021 * from the September 1999 issue of Windows Developer's Journal
2022 * which seems to be in widespread use.
2023 * http://www.lesher.ws/highcolor.html
2024 * http://www.lesher.ws/vidfmt.c
2025 * It hinges on being able to retrieve the bitmaps
2026 * for the three primary colors in non-paletted 16 bit mode.
2028 char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
2030 LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
2031 DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
2037 memset(dibinfo, 0, sizeof(dibinfo_buf));
2038 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2041 ok(hdc != NULL, "GetDC failed?\n");
2042 hbm = CreateCompatibleBitmap(hdc, 1, 1);
2043 ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
2045 /* Call GetDIBits to fill in bmiHeader. */
2046 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2047 ok(ret == 1, "GetDIBits failed\n");
2048 if (dibinfo->bmiHeader.biBitCount > 8)
2050 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2051 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2052 "compression is %u (%d bpp)\n", dibinfo->bmiHeader.biCompression, dibinfo->bmiHeader.biBitCount );
2054 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2056 ok( !bitmasks[0], "red mask is set\n" );
2057 ok( !bitmasks[1], "green mask is set\n" );
2058 ok( !bitmasks[2], "blue mask is set\n" );
2060 /* test with NULL bits pointer and correct bpp */
2061 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2062 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2063 ok(ret == 1, "GetDIBits failed\n");
2065 ok( bitmasks[0] != 0, "red mask is not set\n" );
2066 ok( bitmasks[1] != 0, "green mask is not set\n" );
2067 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2068 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2070 /* test with valid bits pointer */
2071 memset(dibinfo, 0, sizeof(dibinfo_buf));
2072 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2073 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2074 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2075 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2076 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2077 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2079 ok( bitmasks[0] != 0, "red mask is not set\n" );
2080 ok( bitmasks[1] != 0, "green mask is not set\n" );
2081 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2082 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2084 /* now with bits and 0 lines */
2085 memset(dibinfo, 0, sizeof(dibinfo_buf));
2086 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2087 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2088 SetLastError(0xdeadbeef);
2089 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2090 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2092 ok( !bitmasks[0], "red mask is set\n" );
2093 ok( !bitmasks[1], "green mask is set\n" );
2094 ok( !bitmasks[2], "blue mask is set\n" );
2095 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2097 memset(bitmasks, 0, 3*sizeof(DWORD));
2098 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2099 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2100 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2102 ok( bitmasks[0] != 0, "red mask is not set\n" );
2103 ok( bitmasks[1] != 0, "green mask is not set\n" );
2104 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2105 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2108 else skip("bitmap in colortable mode, skipping BI_BITFIELDS tests\n");
2112 /* same thing now with a 32-bpp DIB section */
2114 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2115 dibinfo->bmiHeader.biWidth = 1;
2116 dibinfo->bmiHeader.biHeight = 1;
2117 dibinfo->bmiHeader.biPlanes = 1;
2118 dibinfo->bmiHeader.biBitCount = 32;
2119 dibinfo->bmiHeader.biCompression = BI_RGB;
2120 dibinfo->bmiHeader.biSizeImage = 0;
2121 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2122 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2123 dibinfo->bmiHeader.biClrUsed = 0;
2124 dibinfo->bmiHeader.biClrImportant = 0;
2125 bitmasks[0] = 0x0000ff;
2126 bitmasks[1] = 0x00ff00;
2127 bitmasks[2] = 0xff0000;
2128 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2129 ok( hbm != 0, "failed to create bitmap\n" );
2131 memset(dibinfo, 0, sizeof(dibinfo_buf));
2132 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2133 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2134 ok(ret == 1, "GetDIBits failed\n");
2135 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2137 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2138 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2139 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2140 ok( !bitmasks[0], "red mask is set\n" );
2141 ok( !bitmasks[1], "green mask is set\n" );
2142 ok( !bitmasks[2], "blue mask is set\n" );
2144 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2145 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2146 ok(ret == 1, "GetDIBits failed\n");
2147 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2148 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2149 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2150 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2151 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2153 ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
2154 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2155 ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
2157 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2161 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2162 dibinfo->bmiHeader.biWidth = 1;
2163 dibinfo->bmiHeader.biHeight = 1;
2164 dibinfo->bmiHeader.biPlanes = 1;
2165 dibinfo->bmiHeader.biBitCount = 32;
2166 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2167 dibinfo->bmiHeader.biSizeImage = 0;
2168 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2169 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2170 dibinfo->bmiHeader.biClrUsed = 0;
2171 dibinfo->bmiHeader.biClrImportant = 0;
2172 bitmasks[0] = 0x0000ff;
2173 bitmasks[1] = 0x00ff00;
2174 bitmasks[2] = 0xff0000;
2175 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2176 ok( hbm != 0, "failed to create bitmap\n" );
2180 memset(dibinfo, 0, sizeof(dibinfo_buf));
2181 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2182 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2183 ok(ret == 1, "GetDIBits failed\n");
2185 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
2186 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2187 ok( !bitmasks[0], "red mask is set\n" );
2188 ok( !bitmasks[1], "green mask is set\n" );
2189 ok( !bitmasks[2], "blue mask is set\n" );
2191 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2192 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2193 ok(ret == 1, "GetDIBits failed\n");
2194 ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
2195 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2196 ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
2197 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2202 /* 24-bpp DIB sections don't have bitfields */
2204 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2205 dibinfo->bmiHeader.biWidth = 1;
2206 dibinfo->bmiHeader.biHeight = 1;
2207 dibinfo->bmiHeader.biPlanes = 1;
2208 dibinfo->bmiHeader.biBitCount = 24;
2209 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2210 dibinfo->bmiHeader.biSizeImage = 0;
2211 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2212 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2213 dibinfo->bmiHeader.biClrUsed = 0;
2214 dibinfo->bmiHeader.biClrImportant = 0;
2215 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2216 ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
2217 dibinfo->bmiHeader.biCompression = BI_RGB;
2218 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2219 ok( hbm != 0, "failed to create bitmap\n" );
2221 memset(dibinfo, 0, sizeof(dibinfo_buf));
2222 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2223 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2224 ok(ret == 1, "GetDIBits failed\n");
2225 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2227 ok( dibinfo->bmiHeader.biCompression == BI_RGB,
2228 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2229 ok( !bitmasks[0], "red mask is set\n" );
2230 ok( !bitmasks[1], "green mask is set\n" );
2231 ok( !bitmasks[2], "blue mask is set\n" );
2233 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2234 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2235 ok(ret == 1, "GetDIBits failed\n");
2236 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2237 ok( !bitmasks[0], "red mask is set\n" );
2238 ok( !bitmasks[1], "green mask is set\n" );
2239 ok( !bitmasks[2], "blue mask is set\n" );
2240 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2243 ReleaseDC(NULL, hdc);
2246 static void test_select_object(void)
2249 HBITMAP hbm, hbm_old;
2251 DWORD depths[] = {8, 15, 16, 24, 32};
2256 ok(hdc != 0, "GetDC(0) failed\n");
2257 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2258 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2260 hbm_old = SelectObject(hdc, hbm);
2261 ok(hbm_old == 0, "SelectObject should fail\n");
2266 hdc = CreateCompatibleDC(0);
2267 ok(hdc != 0, "GetDC(0) failed\n");
2268 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2269 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2271 hbm_old = SelectObject(hdc, hbm);
2272 ok(hbm_old != 0, "SelectObject failed\n");
2273 hbm_old = SelectObject(hdc, hbm_old);
2274 ok(hbm_old == hbm, "SelectObject failed\n");
2278 /* test an 1-bpp bitmap */
2279 planes = GetDeviceCaps(hdc, PLANES);
2282 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
2283 ok(hbm != 0, "CreateBitmap failed\n");
2285 hbm_old = SelectObject(hdc, hbm);
2286 ok(hbm_old != 0, "SelectObject failed\n");
2287 hbm_old = SelectObject(hdc, hbm_old);
2288 ok(hbm_old == hbm, "SelectObject failed\n");
2292 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
2293 /* test a color bitmap to dc bpp matching */
2294 planes = GetDeviceCaps(hdc, PLANES);
2295 bpp = GetDeviceCaps(hdc, BITSPIXEL);
2297 hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
2298 ok(hbm != 0, "CreateBitmap failed\n");
2300 hbm_old = SelectObject(hdc, hbm);
2301 if(depths[i] == bpp ||
2302 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
2304 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
2305 SelectObject(hdc, hbm_old);
2307 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
2310 memset(&bm, 0xAA, sizeof(bm));
2311 bytes = GetObject(hbm, sizeof(bm), &bm);
2312 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2313 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2314 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
2315 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
2316 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2317 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
2318 if(depths[i] == 15) {
2319 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
2321 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2323 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2331 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
2336 ret = GetObjectType(hbmp);
2337 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
2339 ret = GetObject(hbmp, 0, 0);
2340 ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
2342 memset(&bm, 0xDA, sizeof(bm));
2343 SetLastError(0xdeadbeef);
2344 ret = GetObject(hbmp, sizeof(bm), &bm);
2345 if (!ret) /* XP, only for curObj2 */ return;
2346 ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
2347 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2348 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2349 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2350 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2351 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2352 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2353 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2356 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2358 static void test_CreateBitmap(void)
2361 HDC screenDC = GetDC(0);
2362 HDC hdc = CreateCompatibleDC(screenDC);
2365 /* all of these are the stock monochrome bitmap */
2366 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2367 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2368 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2369 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2370 HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2371 HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2373 /* these 2 are not the stock monochrome bitmap */
2374 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2375 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2377 HBITMAP old1 = SelectObject(hdc, bm2);
2378 HBITMAP old2 = SelectObject(screenDC, bm3);
2379 SelectObject(hdc, old1);
2380 SelectObject(screenDC, old2);
2382 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2383 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2384 bm, bm1, bm4, bm5, curObj1, old1);
2385 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2387 ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
2388 ok(old2 == 0, "old2 %p\n", old2);
2390 test_mono_1x1_bmp(bm);
2391 test_mono_1x1_bmp(bm1);
2392 test_mono_1x1_bmp(bm2);
2393 test_mono_1x1_bmp(bm3);
2394 test_mono_1x1_bmp(bm4);
2395 test_mono_1x1_bmp(bm5);
2396 test_mono_1x1_bmp(old1);
2397 test_mono_1x1_bmp(curObj1);
2407 ReleaseDC(0, screenDC);
2409 /* show that Windows ignores the provided bm.bmWidthBytes */
2413 bmp.bmWidthBytes = 28;
2415 bmp.bmBitsPixel = 1;
2417 bm = CreateBitmapIndirect(&bmp);
2418 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2419 test_mono_1x1_bmp(bm);
2422 /* Test how the bmBitsPixel field is treated */
2423 for(i = 1; i <= 33; i++) {
2427 bmp.bmWidthBytes = 28;
2429 bmp.bmBitsPixel = i;
2431 SetLastError(0xdeadbeef);
2432 bm = CreateBitmapIndirect(&bmp);
2434 DWORD error = GetLastError();
2435 ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
2436 ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2440 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2441 GetObject(bm, sizeof(bmp), &bmp);
2448 } else if(i <= 16) {
2450 } else if(i <= 24) {
2452 } else if(i <= 32) {
2455 ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2456 i, bmp.bmBitsPixel, expect);
2461 static void test_bitmapinfoheadersize(void)
2468 memset(&bmi, 0, sizeof(BITMAPINFO));
2469 bmi.bmiHeader.biHeight = 100;
2470 bmi.bmiHeader.biWidth = 512;
2471 bmi.bmiHeader.biBitCount = 24;
2472 bmi.bmiHeader.biPlanes = 1;
2474 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2476 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2477 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2479 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2481 SetLastError(0xdeadbeef);
2482 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2483 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2486 bmi.bmiHeader.biSize++;
2488 SetLastError(0xdeadbeef);
2489 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2491 broken(!hdib), /* Win98, WinMe */
2492 "CreateDIBSection error %d\n", GetLastError());
2495 bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2497 SetLastError(0xdeadbeef);
2498 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2500 broken(!hdib), /* Win98, WinMe */
2501 "CreateDIBSection error %d\n", GetLastError());
2504 bmi.bmiHeader.biSize++;
2506 SetLastError(0xdeadbeef);
2507 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2509 broken(!hdib), /* Win98, WinMe */
2510 "CreateDIBSection error %d\n", GetLastError());
2513 bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2515 SetLastError(0xdeadbeef);
2516 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2517 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2520 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2522 SetLastError(0xdeadbeef);
2523 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2525 broken(!hdib), /* Win95 */
2526 "CreateDIBSection error %d\n", GetLastError());
2529 memset(&bci, 0, sizeof(BITMAPCOREINFO));
2530 bci.bmciHeader.bcHeight = 100;
2531 bci.bmciHeader.bcWidth = 512;
2532 bci.bmciHeader.bcBitCount = 24;
2533 bci.bmciHeader.bcPlanes = 1;
2535 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2537 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2538 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2540 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2542 SetLastError(0xdeadbeef);
2543 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2544 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2547 bci.bmciHeader.bcSize++;
2549 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2550 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2552 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2554 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2555 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2560 static void test_get16dibits(void)
2562 BYTE bits[4 * (16 / sizeof(BYTE))];
2564 HDC screen_dc = GetDC(NULL);
2567 int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2569 int overwritten_bytes = 0;
2571 memset(bits, 0, sizeof(bits));
2572 hbmp = CreateBitmap(2, 2, 1, 16, bits);
2573 ok(hbmp != NULL, "CreateBitmap failed\n");
2575 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2578 memset(info, '!', info_len);
2579 memset(info, 0, sizeof(info->bmiHeader));
2581 info->bmiHeader.biSize = sizeof(info->bmiHeader);
2582 info->bmiHeader.biWidth = 2;
2583 info->bmiHeader.biHeight = 2;
2584 info->bmiHeader.biPlanes = 1;
2585 info->bmiHeader.biCompression = BI_RGB;
2587 ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2588 ok(ret != 0, "GetDIBits failed got %d\n", ret);
2590 for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2592 overwritten_bytes++;
2593 ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2595 HeapFree(GetProcessHeap(), 0, info);
2597 ReleaseDC(NULL, screen_dc);
2600 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2601 DWORD dwRop, UINT32 expected, int line)
2603 *srcBuffer = 0xFEDCBA98;
2604 *dstBuffer = 0x89ABCDEF;
2605 Rectangle(hdcSrc, 0, 0, 1, 1); /* A null operation to ensure dibs are coerced to X11 */
2606 BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
2607 ok(expected == *dstBuffer,
2608 "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2609 dwRop, expected, *dstBuffer, line);
2612 static void test_BitBlt(void)
2614 HBITMAP bmpDst, bmpSrc;
2615 HBITMAP oldDst, oldSrc;
2616 HDC hdcScreen, hdcDst, hdcSrc;
2617 UINT32 *dstBuffer, *srcBuffer;
2618 HBRUSH hBrush, hOldBrush;
2619 BITMAPINFO bitmapInfo;
2621 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2622 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2623 bitmapInfo.bmiHeader.biWidth = 1;
2624 bitmapInfo.bmiHeader.biHeight = 1;
2625 bitmapInfo.bmiHeader.biPlanes = 1;
2626 bitmapInfo.bmiHeader.biBitCount = 32;
2627 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2628 bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2630 hdcScreen = CreateCompatibleDC(0);
2631 hdcDst = CreateCompatibleDC(hdcScreen);
2632 hdcSrc = CreateCompatibleDC(hdcDst);
2634 /* Setup the destination dib section */
2635 bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
2637 oldDst = SelectObject(hdcDst, bmpDst);
2639 hBrush = CreateSolidBrush(0x012345678);
2640 hOldBrush = SelectObject(hdcDst, hBrush);
2642 /* Setup the source dib section */
2643 bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
2645 oldSrc = SelectObject(hdcSrc, bmpSrc);
2647 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2648 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2649 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2650 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2651 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2652 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2653 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2654 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2655 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2656 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2657 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2658 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2659 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2660 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2661 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2664 SelectObject(hdcSrc, oldSrc);
2665 DeleteObject(bmpSrc);
2668 SelectObject(hdcDst, hOldBrush);
2669 DeleteObject(hBrush);
2670 SelectObject(hdcDst, oldDst);
2671 DeleteObject(bmpDst);
2675 DeleteDC(hdcScreen);
2678 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2679 DWORD dwRop, UINT32 expected, int line)
2681 *srcBuffer = 0xFEDCBA98;
2682 *dstBuffer = 0x89ABCDEF;
2683 StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
2684 ok(expected == *dstBuffer,
2685 "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2686 dwRop, expected, *dstBuffer, line);
2689 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, BITMAPINFO *dst_info, UINT32 *dstBuffer, UINT32 *srcBuffer,
2690 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2691 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2692 UINT32 *expected, int line)
2694 int dst_size = get_dib_image_size( dst_info );
2696 memset(dstBuffer, 0, dst_size);
2697 StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2698 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
2699 ok(memcmp(dstBuffer, expected, dst_size) == 0,
2700 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2701 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2702 expected[0], expected[1], expected[2], expected[3],
2703 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2704 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2705 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2708 static void test_StretchBlt(void)
2710 HBITMAP bmpDst, bmpSrc;
2711 HBITMAP oldDst, oldSrc;
2712 HDC hdcScreen, hdcDst, hdcSrc;
2713 UINT32 *dstBuffer, *srcBuffer;
2714 HBRUSH hBrush, hOldBrush;
2715 BITMAPINFO biDst, biSrc;
2716 UINT32 expected[256];
2719 memset(&biDst, 0, sizeof(BITMAPINFO));
2720 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2721 biDst.bmiHeader.biWidth = 16;
2722 biDst.bmiHeader.biHeight = -16;
2723 biDst.bmiHeader.biPlanes = 1;
2724 biDst.bmiHeader.biBitCount = 32;
2725 biDst.bmiHeader.biCompression = BI_RGB;
2726 memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
2728 hdcScreen = CreateCompatibleDC(0);
2729 hdcDst = CreateCompatibleDC(hdcScreen);
2730 hdcSrc = CreateCompatibleDC(hdcDst);
2733 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2735 oldDst = SelectObject(hdcDst, bmpDst);
2737 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2739 oldSrc = SelectObject(hdcSrc, bmpSrc);
2741 hBrush = CreateSolidBrush(0x012345678);
2742 hOldBrush = SelectObject(hdcDst, hBrush);
2744 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2745 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2746 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2747 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2748 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2749 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2750 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2751 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2752 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2753 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2754 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2755 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2756 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2757 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2758 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2760 SelectObject(hdcDst, hOldBrush);
2761 DeleteObject(hBrush);
2763 /* Top-down to top-down tests */
2764 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2765 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2767 memset( expected, 0, get_dib_image_size( &biDst ) );
2768 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2769 expected[16] = 0xFEDCBA98, expected[17] = 0x76543210;
2770 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2771 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2773 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2774 expected[16] = 0x00000000, expected[17] = 0x00000000;
2775 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2776 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
2778 expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
2779 expected[16] = 0xCAFED00D, expected[17] = 0xCAFED00D;
2780 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2781 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
2783 /* This is an example of the dst width (height) == 1 exception, explored below */
2784 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2785 expected[16] = 0x00000000, expected[17] = 0x00000000;
2786 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2787 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
2789 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2790 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
2791 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2792 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2794 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2795 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
2796 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2797 1, 1, -2, -2, 0, 0, 2, 2, expected, __LINE__);
2799 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2800 expected[16] = 0x00000000, expected[17] = 0x00000000;
2801 todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2802 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
2804 expected[0] = 0x00000000, expected[1] = 0x00000000;
2805 expected[16] = 0x00000000, expected[17] = 0xCAFED00D, expected[18] = 0xFEEDFACE;
2806 expected[32] = 0x00000000, expected[33] = 0xFEDCBA98, expected[34] = 0x76543210;
2808 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2809 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2811 /* when dst width is 1 merge src width - 1 pixels */
2812 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
2813 srcBuffer[0] = 0x0000ff00, srcBuffer[1] = 0x0000f0f0, srcBuffer[2] = 0x0000cccc, srcBuffer[3] = 0x0000aaaa;
2814 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2816 memset( expected, 0, get_dib_image_size( &biDst ) );
2817 expected[0] = srcBuffer[0];
2818 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2819 0, 0, 1, 1, 0, 0, 2, 1, expected, __LINE__);
2821 expected[0] = srcBuffer[0] & srcBuffer[1];
2822 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2823 0, 0, 1, 1, 0, 0, 3, 1, expected, __LINE__);
2825 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
2826 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2827 0, 0, 1, 1, 0, 0, 4, 1, expected, __LINE__);
2829 /* this doesn't happen if the src width is -ve */
2830 expected[0] = srcBuffer[1] & srcBuffer[2];
2831 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2832 0, 0, 1, 1, 2, 0, -2, 1, expected, __LINE__);
2834 /* when dst width > 1 behaviour reverts to what one would expect */
2835 expected[0] = srcBuffer[0] & srcBuffer[1], expected[1] = srcBuffer[2] & srcBuffer[3];
2836 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2837 0, 0, 2, 1, 0, 0, 4, 1, expected, __LINE__);
2839 /* similarly in the vertical direction */
2840 memset( expected, 0, get_dib_image_size( &biDst ) );
2841 expected[0] = srcBuffer[0];
2842 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2843 0, 0, 1, 1, 0, 0, 1, 2, expected, __LINE__);
2845 /* check that it's the dst size in device units that needs to be 1 */
2846 SetMapMode( hdcDst, MM_ISOTROPIC );
2847 SetWindowExtEx( hdcDst, 200, 200, NULL );
2848 SetViewportExtEx( hdcDst, 100, 100, NULL );
2850 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
2851 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2852 0, 0, 2, 2, 0, 0, 4, 1, expected, __LINE__);
2853 SetMapMode( hdcDst, MM_TEXT );
2855 SelectObject(hdcDst, oldDst);
2856 DeleteObject(bmpDst);
2858 /* Top-down to bottom-up tests */
2859 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
2860 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2861 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2863 biDst.bmiHeader.biHeight = 16;
2864 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2866 oldDst = SelectObject(hdcDst, bmpDst);
2868 memset( expected, 0, get_dib_image_size( &biDst ) );
2870 expected[224] = 0xFEDCBA98, expected[225] = 0x76543210;
2871 expected[240] = 0xCAFED00D, expected[241] = 0xFEEDFACE;
2872 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2873 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2875 expected[224] = 0xFEEDFACE, expected[225] = 0xCAFED00D;
2876 expected[240] = 0x76543210, expected[241] = 0xFEDCBA98;
2877 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2878 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2880 SelectObject(hdcSrc, oldSrc);
2881 DeleteObject(bmpSrc);
2883 /* Bottom-up to bottom-up tests */
2884 biSrc.bmiHeader.biHeight = 16;
2885 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2887 srcBuffer[224] = 0xCAFED00D, srcBuffer[225] = 0xFEEDFACE;
2888 srcBuffer[240] = 0xFEDCBA98, srcBuffer[241] = 0x76543210;
2889 oldSrc = SelectObject(hdcSrc, bmpSrc);
2891 memset( expected, 0, get_dib_image_size( &biDst ) );
2893 expected[224] = 0xCAFED00D, expected[225] = 0xFEEDFACE;
2894 expected[240] = 0xFEDCBA98, expected[241] = 0x76543210;
2895 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2896 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2898 expected[224] = 0x76543210, expected[225] = 0xFEDCBA98;
2899 expected[240] = 0xFEEDFACE, expected[241] = 0xCAFED00D;
2900 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2901 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2903 SelectObject(hdcDst, oldDst);
2904 DeleteObject(bmpDst);
2906 /* Bottom-up to top-down tests */
2907 biDst.bmiHeader.biHeight = -16;
2908 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2910 oldDst = SelectObject(hdcDst, bmpDst);
2912 memset( expected, 0, get_dib_image_size( &biDst ) );
2913 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2914 expected[16] = 0xCAFED00D, expected[17] = 0xFEEDFACE;
2915 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2916 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2918 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2919 expected[16] = 0x76543210, expected[17] = 0xFEDCBA98;
2920 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2921 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2923 SelectObject(hdcSrc, oldSrc);
2924 DeleteObject(bmpSrc);
2926 biSrc.bmiHeader.biHeight = -2;
2927 biSrc.bmiHeader.biBitCount = 24;
2928 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
2929 oldSrc = SelectObject(hdcSrc, bmpSrc);
2931 memset( expected, 0, get_dib_image_size( &biDst ) );
2932 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2933 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2934 memcpy(dstBuffer, expected, 4 * sizeof(*dstBuffer));
2935 StretchBlt(hdcSrc, 0, 0, 4, 1, hdcDst, 0, 0, 4, 1, SRCCOPY );
2936 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
2937 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
2938 expected[0] = 0x00EDFACE, expected[1] = 0x00FED00D;
2939 expected[2] = 0x00543210, expected[3] = 0x00DCBA98;
2940 ok(!memcmp(dstBuffer, expected, 16),
2941 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
2942 expected[0], expected[1], expected[2], expected[3],
2943 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
2945 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2946 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2947 memcpy(srcBuffer, expected, 4 * sizeof(*dstBuffer));
2948 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
2949 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
2950 expected[0] = 0x00EDFACE, expected[1] = 0x00D00DFE;
2951 expected[2] = 0x0010CAFE, expected[3] = 0x00765432;
2952 ok(!memcmp(dstBuffer, expected, 16),
2953 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
2954 expected[0], expected[1], expected[2], expected[3],
2955 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
2957 SelectObject(hdcSrc, oldSrc);
2958 DeleteObject(bmpSrc);
2960 biSrc.bmiHeader.biBitCount = 1;
2961 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
2962 oldSrc = SelectObject(hdcSrc, bmpSrc);
2963 *((DWORD *)colors + 0) = 0x123456;
2964 *((DWORD *)colors + 1) = 0x335577;
2965 SetDIBColorTable( hdcSrc, 0, 2, colors );
2966 srcBuffer[0] = 0x55555555;
2967 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
2968 SetTextColor( hdcDst, 0 );
2969 SetBkColor( hdcDst, 0 );
2970 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
2971 expected[0] = expected[2] = 0x00123456;
2972 expected[1] = expected[3] = 0x00335577;
2973 ok(!memcmp(dstBuffer, expected, 16),
2974 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
2975 expected[0], expected[1], expected[2], expected[3],
2976 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
2978 SelectObject(hdcSrc, oldSrc);
2979 DeleteObject(bmpSrc);
2981 bmpSrc = CreateBitmap( 16, 16, 1, 1, 0 );
2982 oldSrc = SelectObject(hdcSrc, bmpSrc);
2983 SetPixel( hdcSrc, 0, 0, 0 );
2984 SetPixel( hdcSrc, 1, 0, 0xffffff );
2985 SetPixel( hdcSrc, 2, 0, 0xffffff );
2986 SetPixel( hdcSrc, 3, 0, 0 );
2987 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
2988 SetTextColor( hdcDst, RGB(0x22,0x44,0x66) );
2989 SetBkColor( hdcDst, RGB(0x65,0x43,0x21) );
2990 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
2991 expected[0] = expected[3] = 0x00224466;
2992 expected[1] = expected[2] = 0x00654321;
2993 ok(!memcmp(dstBuffer, expected, 16),
2994 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
2995 expected[0], expected[1], expected[2], expected[3],
2996 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
2998 SelectObject(hdcSrc, oldSrc);
2999 DeleteObject(bmpSrc);
3003 SelectObject(hdcDst, oldDst);
3004 DeleteObject(bmpDst);
3007 DeleteDC(hdcScreen);
3010 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3011 DWORD dwRop, UINT32 expected, int line)
3013 const UINT32 buffer[2] = { 0xFEDCBA98, 0 };
3014 BITMAPINFO bitmapInfo;
3016 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3017 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3018 bitmapInfo.bmiHeader.biWidth = 2;
3019 bitmapInfo.bmiHeader.biHeight = 1;
3020 bitmapInfo.bmiHeader.biPlanes = 1;
3021 bitmapInfo.bmiHeader.biBitCount = 32;
3022 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3023 bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer);
3025 *dstBuffer = 0x89ABCDEF;
3027 StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop);
3028 ok(expected == *dstBuffer,
3029 "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
3030 dwRop, expected, *dstBuffer, line);
3033 static void check_StretchDIBits_stretch(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3034 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
3035 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
3036 UINT32 expected[4], int line)
3038 BITMAPINFO bitmapInfo;
3040 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3041 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3042 bitmapInfo.bmiHeader.biWidth = 2;
3043 bitmapInfo.bmiHeader.biHeight = -2;
3044 bitmapInfo.bmiHeader.biPlanes = 1;
3045 bitmapInfo.bmiHeader.biBitCount = 32;
3046 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3048 memset(dstBuffer, 0, 16);
3049 StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
3050 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3051 srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
3052 ok(memcmp(dstBuffer, expected, 16) == 0,
3053 "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
3054 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
3055 expected[0], expected[1], expected[2], expected[3],
3056 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
3057 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3058 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
3061 static void test_StretchDIBits(void)
3065 HDC hdcScreen, hdcDst;
3066 UINT32 *dstBuffer, srcBuffer[4];
3067 HBRUSH hBrush, hOldBrush;
3071 memset(&biDst, 0, sizeof(BITMAPINFO));
3072 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3073 biDst.bmiHeader.biWidth = 2;
3074 biDst.bmiHeader.biHeight = -2;
3075 biDst.bmiHeader.biPlanes = 1;
3076 biDst.bmiHeader.biBitCount = 32;
3077 biDst.bmiHeader.biCompression = BI_RGB;
3079 hdcScreen = CreateCompatibleDC(0);
3080 hdcDst = CreateCompatibleDC(hdcScreen);
3083 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3085 oldDst = SelectObject(hdcDst, bmpDst);
3087 hBrush = CreateSolidBrush(0x012345678);
3088 hOldBrush = SelectObject(hdcDst, hBrush);
3090 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3091 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3092 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3093 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3094 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3095 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3096 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3097 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3098 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3099 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3100 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3101 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3102 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3103 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3104 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3106 SelectObject(hdcDst, hOldBrush);
3107 DeleteObject(hBrush);
3109 /* Top-down destination tests */
3110 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3111 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
3113 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
3114 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
3115 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3116 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3118 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3119 expected[2] = 0x00000000, expected[3] = 0x00000000;
3120 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3121 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
3123 expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
3124 expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
3125 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3126 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
3128 expected[0] = 0x42441000, expected[1] = 0x00000000;
3129 expected[2] = 0x00000000, expected[3] = 0x00000000;
3130 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3131 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
3133 expected[0] = 0x00000000, expected[1] = 0x00000000;
3134 expected[2] = 0x00000000, expected[3] = 0x00000000;
3135 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3136 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3138 expected[0] = 0x00000000, expected[1] = 0x00000000;
3139 expected[2] = 0x00000000, expected[3] = 0x00000000;
3140 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3141 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3143 expected[0] = 0x00000000, expected[1] = 0x00000000;
3144 expected[2] = 0x00000000, expected[3] = 0x00000000;
3145 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3146 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
3148 expected[0] = 0x00000000, expected[1] = 0x00000000;
3149 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
3150 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3151 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3153 SelectObject(hdcDst, oldDst);
3154 DeleteObject(bmpDst);
3156 /* Bottom up destination tests */
3157 biDst.bmiHeader.biHeight = 2;
3158 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3160 oldDst = SelectObject(hdcDst, bmpDst);
3162 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3163 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
3164 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3165 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3168 SelectObject(hdcDst, oldDst);
3169 DeleteObject(bmpDst);
3172 DeleteDC(hdcScreen);
3175 static void test_GdiAlphaBlend(void)
3187 BLENDFUNCTION blend;
3189 if (!pGdiAlphaBlend)
3191 win_skip("GdiAlphaBlend() is not implemented\n");
3195 hdcNull = GetDC(NULL);
3196 hdcDst = CreateCompatibleDC(hdcNull);
3197 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
3198 hdcSrc = CreateCompatibleDC(hdcNull);
3200 bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3201 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3202 bmi->bmiHeader.biHeight = 20;
3203 bmi->bmiHeader.biWidth = 20;
3204 bmi->bmiHeader.biBitCount = 32;
3205 bmi->bmiHeader.biPlanes = 1;
3206 bmi->bmiHeader.biCompression = BI_RGB;
3207 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3208 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3210 oldDst = SelectObject(hdcDst, bmpDst);
3211 oldSrc = SelectObject(hdcSrc, bmpSrc);
3213 blend.BlendOp = AC_SRC_OVER;
3214 blend.BlendFlags = 0;
3215 blend.SourceConstantAlpha = 128;
3216 blend.AlphaFormat = 0;
3218 SetLastError(0xdeadbeef);
3219 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3220 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3222 SetLastError(0xdeadbeef);
3223 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3224 ok( !ret, "GdiAlphaBlend succeeded\n" );
3225 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3227 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3228 ok( !ret, "GdiAlphaBlend succeeded\n" );
3229 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend);
3230 ok( !ret, "GdiAlphaBlend succeeded\n" );
3231 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3232 ok( !ret, "GdiAlphaBlend succeeded\n" );
3233 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3234 ok( !ret, "GdiAlphaBlend succeeded\n" );
3236 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
3237 SetLastError(0xdeadbeef);
3238 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3239 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3240 SetLastError(0xdeadbeef);
3241 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3242 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3243 SetMapMode(hdcSrc, MM_ANISOTROPIC);
3244 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
3245 SetLastError(0xdeadbeef);
3246 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend);
3247 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3248 SetLastError(0xdeadbeef);
3249 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend);
3250 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3252 SetLastError(0xdeadbeef);
3253 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend);
3254 ok( !ret, "GdiAlphaBlend succeeded\n" );
3255 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3257 /* overlapping source and dest not allowed */
3259 SetLastError(0xdeadbeef);
3260 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 19, 19, 20, 20, blend);
3261 ok( !ret, "GdiAlphaBlend succeeded\n" );
3262 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3264 SetLastError(0xdeadbeef);
3265 ret = pGdiAlphaBlend(hdcDst, 20, 20, 20, 20, hdcDst, 1, 1, 20, 20, blend);
3266 ok( !ret, "GdiAlphaBlend succeeded\n" );
3267 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3269 SetLastError(0xdeadbeef);
3270 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 20, 10, 20, 20, blend);
3271 ok( ret, "GdiAlphaBlend succeeded\n" );
3272 SetLastError(0xdeadbeef);
3273 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 10, 20, 20, 20, blend);
3274 ok( ret, "GdiAlphaBlend succeeded\n" );
3276 /* AC_SRC_ALPHA requires 32-bpp BI_RGB format */
3278 blend.AlphaFormat = AC_SRC_ALPHA;
3279 SetLastError(0xdeadbeef);
3280 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3281 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3283 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3284 ((DWORD *)bmi->bmiColors)[0] = 0xff0000;
3285 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3286 ((DWORD *)bmi->bmiColors)[2] = 0x0000ff;
3287 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3288 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3289 oldSrc = SelectObject(hdcSrc, bmpSrc);
3290 DeleteObject( oldSrc );
3292 SetLastError(0xdeadbeef);
3293 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3294 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3296 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3297 ((DWORD *)bmi->bmiColors)[0] = 0x0000ff;
3298 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3299 ((DWORD *)bmi->bmiColors)[2] = 0xff0000;
3300 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3301 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3302 oldSrc = SelectObject(hdcSrc, bmpSrc);
3303 DeleteObject( oldSrc );
3305 SetLastError(0xdeadbeef);
3306 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3307 ok( !ret, "GdiAlphaBlend succeeded\n" );
3308 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3310 bmi->bmiHeader.biBitCount = 24;
3311 bmi->bmiHeader.biCompression = BI_RGB;
3312 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3313 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3314 oldSrc = SelectObject(hdcSrc, bmpSrc);
3315 DeleteObject( oldSrc );
3317 SetLastError(0xdeadbeef);
3318 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3319 ok( !ret, "GdiAlphaBlend succeeded\n" );
3320 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3322 bmi->bmiHeader.biBitCount = 1;
3323 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3324 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3325 oldSrc = SelectObject(hdcSrc, bmpSrc);
3326 DeleteObject( oldSrc );
3328 SetLastError(0xdeadbeef);
3329 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3330 ok( !ret, "GdiAlphaBlend succeeded\n" );
3331 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3333 bmpSrc = CreateBitmap( 100, 100, 1, 1, NULL );
3334 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3335 oldSrc = SelectObject(hdcSrc, bmpSrc);
3336 DeleteObject( oldSrc );
3338 SetLastError(0xdeadbeef);
3339 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3340 ok( !ret, "GdiAlphaBlend succeeded\n" );
3341 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3343 SelectObject(hdcDst, oldDst);
3344 SelectObject(hdcSrc, oldSrc);
3345 DeleteObject(bmpSrc);
3346 DeleteObject(bmpDst);
3350 ReleaseDC(NULL, hdcNull);
3354 static void test_GdiGradientFill(void)
3361 GRADIENT_RECT rect[] = { { 0, 0 }, { 0, 1 }, { 2, 3 } };
3362 GRADIENT_TRIANGLE tri[] = { { 0, 0, 0 }, { 0, 1, 2 }, { 0, 2, 1 }, { 0, 1, 3 } };
3363 TRIVERTEX vt[3] = { { 2, 2, 0xff00, 0x0000, 0x0000, 0x8000 },
3364 { 10, 10, 0x0000, 0xff00, 0x0000, 0x8000 },
3365 { 20, 10, 0x0000, 0x0000, 0xff00, 0xff00 } };
3367 if (!pGdiGradientFill)
3369 win_skip( "GdiGradientFill is not implemented\n" );
3373 hdc = CreateCompatibleDC( NULL );
3374 bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3375 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3376 bmi->bmiHeader.biHeight = 20;
3377 bmi->bmiHeader.biWidth = 20;
3378 bmi->bmiHeader.biBitCount = 32;
3379 bmi->bmiHeader.biPlanes = 1;
3380 bmi->bmiHeader.biCompression = BI_RGB;
3381 bmp = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3382 ok( bmp != NULL, "couldn't create bitmap\n" );
3383 SelectObject( hdc, bmp );
3385 SetLastError( 0xdeadbeef );
3386 ret = pGdiGradientFill( hdc, vt, 3, rect, 1, GRADIENT_FILL_RECT_H );
3387 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3388 SetLastError( 0xdeadbeef );
3389 ret = pGdiGradientFill( hdc, vt, 3, rect, 1, 3 );
3390 ok( !ret, "GdiGradientFill succeeded\n" );
3391 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3392 SetLastError( 0xdeadbeef );
3393 ret = pGdiGradientFill( (HDC)0xdead, vt, 3, rect, 1, GRADIENT_FILL_RECT_H );
3394 ok( !ret, "GdiGradientFill succeeded\n" );
3395 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3396 SetLastError( 0xdeadbeef );
3397 ret = pGdiGradientFill( NULL, NULL, 0, rect, 1, GRADIENT_FILL_RECT_H );
3398 ok( !ret, "GdiGradientFill succeeded\n" );
3399 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3400 ret = pGdiGradientFill( hdc, NULL, 0, rect, 1, GRADIENT_FILL_RECT_H );
3401 ok( !ret, "GdiGradientFill succeeded\n" );
3402 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3403 SetLastError( 0xdeadbeef );
3404 ret = pGdiGradientFill( hdc, NULL, 3, rect, 1, GRADIENT_FILL_RECT_H );
3405 ok( !ret, "GdiGradientFill succeeded\n" );
3406 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3407 SetLastError( 0xdeadbeef );
3408 ret = pGdiGradientFill( hdc, vt, 3, NULL, 0, GRADIENT_FILL_RECT_H );
3409 ok( !ret, "GdiGradientFill succeeded\n" );
3410 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3411 SetLastError( 0xdeadbeef );
3412 ret = pGdiGradientFill( hdc, vt, 3, NULL, 1, GRADIENT_FILL_RECT_H );
3413 ok( !ret, "GdiGradientFill succeeded\n" );
3414 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3415 SetLastError( 0xdeadbeef );
3416 ret = pGdiGradientFill( hdc, vt, 3, rect, 0, GRADIENT_FILL_RECT_H );
3417 ok( !ret, "GdiGradientFill succeeded\n" );
3418 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3419 SetLastError( 0xdeadbeef );
3420 ret = pGdiGradientFill( hdc, vt, 3, rect, 3, GRADIENT_FILL_RECT_H );
3421 ok( !ret, "GdiGradientFill succeeded\n" );
3422 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3423 rect[2].UpperLeft = rect[2].LowerRight = 1;
3424 SetLastError( 0xdeadbeef );
3425 ret = pGdiGradientFill( hdc, vt, 3, rect, 3, GRADIENT_FILL_RECT_H );
3426 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3427 SetLastError( 0xdeadbeef );
3428 ret = pGdiGradientFill( hdc, vt, 1, rect, 1, GRADIENT_FILL_RECT_H );
3429 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3430 SetLastError( 0xdeadbeef );
3431 ret = pGdiGradientFill( hdc, vt, 1, tri, 0, GRADIENT_FILL_TRIANGLE );
3432 ok( !ret, "GdiGradientFill succeeded\n" );
3433 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3434 SetLastError( 0xdeadbeef );
3435 ret = pGdiGradientFill( hdc, vt, 1, tri, 1, GRADIENT_FILL_TRIANGLE );
3436 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3437 SetLastError( 0xdeadbeef );
3438 ret = pGdiGradientFill( hdc, vt, 3, tri, 2, GRADIENT_FILL_TRIANGLE );
3439 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3440 SetLastError( 0xdeadbeef );
3441 ret = pGdiGradientFill( hdc, vt, 3, tri, 3, GRADIENT_FILL_TRIANGLE );
3442 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3443 SetLastError( 0xdeadbeef );
3444 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3445 ok( !ret, "GdiGradientFill succeeded\n" );
3446 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3448 SetLastError( 0xdeadbeef );
3449 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3450 ok( !ret, "GdiGradientFill succeeded\n" );
3451 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3453 SetLastError( 0xdeadbeef );
3454 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3455 ok( !ret, "GdiGradientFill succeeded\n" );
3456 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3457 tri[3].Vertex1 = tri[3].Vertex2 = tri[3].Vertex3 = 1;
3458 SetLastError( 0xdeadbeef );
3459 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3460 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3463 DeleteObject( bmp );
3466 static void test_clipping(void)
3474 HDC hdcDst = CreateCompatibleDC( NULL );
3475 HDC hdcSrc = CreateCompatibleDC( NULL );
3477 BITMAPINFO bmpinfo={{0}};
3478 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3479 bmpinfo.bmiHeader.biWidth = 100;
3480 bmpinfo.bmiHeader.biHeight = 100;
3481 bmpinfo.bmiHeader.biPlanes = 1;
3482 bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3483 bmpinfo.bmiHeader.biCompression = BI_RGB;
3485 bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3486 ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3487 SelectObject( hdcDst, bmpDst );
3489 bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3490 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3491 SelectObject( hdcSrc, bmpSrc );
3493 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3494 ok(result, "BitBlt failed\n");
3496 hRgn = CreateRectRgn( 0,0,0,0 );
3497 SelectClipRgn( hdcDst, hRgn );
3499 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3500 ok(result, "BitBlt failed\n");
3502 DeleteObject( bmpDst );
3503 DeleteObject( bmpSrc );
3504 DeleteObject( hRgn );
3509 static void test_32bit_bitmap_blt(void)
3512 HBITMAP bmpSrc, bmpDst;
3513 HBITMAP oldSrc, oldDst;
3514 HDC hdcSrc, hdcDst, hdcScreen;
3516 DWORD colorSrc = 0x11223344;
3518 memset(&biDst, 0, sizeof(BITMAPINFO));
3519 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3520 biDst.bmiHeader.biWidth = 2;
3521 biDst.bmiHeader.biHeight = -2;
3522 biDst.bmiHeader.biPlanes = 1;
3523 biDst.bmiHeader.biBitCount = 32;
3524 biDst.bmiHeader.biCompression = BI_RGB;
3526 hdcScreen = CreateCompatibleDC(0);
3527 if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3529 DeleteDC(hdcScreen);
3530 trace("Skipping 32-bit DDB test\n");
3534 hdcSrc = CreateCompatibleDC(hdcScreen);
3535 bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3536 oldSrc = SelectObject(hdcSrc, bmpSrc);
3538 hdcDst = CreateCompatibleDC(hdcScreen);
3539 bmpDst = CreateDIBSection(hdcDst, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3540 oldDst = SelectObject(hdcDst, bmpDst);
3542 StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3543 ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3546 SelectObject(hdcDst, oldDst);
3547 DeleteObject(bmpDst);
3550 SelectObject(hdcSrc, oldSrc);
3551 DeleteObject(bmpSrc);
3554 DeleteDC(hdcScreen);
3558 * Used by test_GetDIBits_top_down to create the bitmap to test against.
3560 static void setup_picture(char *picture, int bpp)
3568 /*Set the first byte in each pixel to the index of that pixel.*/
3569 for (i = 0; i < 4; i++)
3570 picture[i * (bpp / 8)] = i;
3575 /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
3582 static void test_GetDIBits_top_down(int bpp)
3585 HBITMAP bmptb, bmpbt;
3591 memset( &bi, 0, sizeof(bi) );
3592 bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
3593 bi.bmiHeader.biWidth=2;
3594 bi.bmiHeader.biHeight=2;
3595 bi.bmiHeader.biPlanes=1;
3596 bi.bmiHeader.biBitCount=bpp;
3597 bi.bmiHeader.biCompression=BI_RGB;
3599 /*Get the device context for the screen.*/
3601 ok(hdc != NULL, "Could not get a handle to a device context.\n");
3603 /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
3604 bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3605 ok(bmpbt != NULL, "Could not create a DIB section.\n");
3606 /*Now that we have a pointer to the pixels, we write to them.*/
3607 setup_picture((char*)picture, bpp);
3608 /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
3609 bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
3610 bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3611 ok(bmptb != NULL, "Could not create a DIB section.\n");
3612 /*Write to this top to bottom bitmap.*/
3613 setup_picture((char*)picture, bpp);
3615 bi.bmiHeader.biWidth = 1;
3617 bi.bmiHeader.biHeight = 2;
3618 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3619 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3620 /*Check the first byte of the pixel.*/
3621 ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3622 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3623 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3624 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3625 /*Check second scanline.*/
3626 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3627 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3628 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3629 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3630 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3631 ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3632 /*Check both scanlines.*/
3633 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3634 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3635 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3636 ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3637 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3638 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3639 ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3640 ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3642 /*Make destination bitmap top-down.*/
3643 bi.bmiHeader.biHeight = -2;
3644 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3645 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3646 ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3647 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3648 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3649 ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3650 /*Check second scanline.*/
3651 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3652 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3653 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3654 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3655 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3656 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3657 /*Check both scanlines.*/
3658 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3659 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3660 ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3661 ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3662 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3663 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3664 ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3665 ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3667 DeleteObject(bmpbt);
3668 DeleteObject(bmptb);
3671 static void test_GetSetDIBits_rtl(void)
3674 HBITMAP bitmap, orig_bitmap;
3677 DWORD bits_1[8 * 8], bits_2[8 * 8];
3681 win_skip("Don't have SetLayout\n");
3685 hdc = GetDC( NULL );
3686 hdc_mem = CreateCompatibleDC( hdc );
3687 pSetLayout( hdc_mem, LAYOUT_LTR );
3689 bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
3690 orig_bitmap = SelectObject( hdc_mem, bitmap );
3691 SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
3692 SelectObject( hdc_mem, orig_bitmap );
3694 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3695 info.bmiHeader.biWidth = 8;
3696 info.bmiHeader.biHeight = 8;
3697 info.bmiHeader.biPlanes = 1;
3698 info.bmiHeader.biBitCount = 32;
3699 info.bmiHeader.biCompression = BI_RGB;
3701 /* First show that GetDIBits ignores the layout mode. */
3703 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3704 ok(ret == 8, "got %d\n", ret);
3705 ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
3707 pSetLayout( hdc_mem, LAYOUT_RTL );
3709 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3710 ok(ret == 8, "got %d\n", ret);
3712 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3714 /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
3715 followed by a GetDIBits and show that the bits remain unchanged. */
3717 pSetLayout( hdc_mem, LAYOUT_LTR );
3719 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3720 ok(ret == 8, "got %d\n", ret);
3721 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3722 ok(ret == 8, "got %d\n", ret);
3723 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3725 pSetLayout( hdc_mem, LAYOUT_RTL );
3727 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3728 ok(ret == 8, "got %d\n", ret);
3729 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3730 ok(ret == 8, "got %d\n", ret);
3731 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3733 DeleteObject( bitmap );
3734 DeleteDC( hdc_mem );
3735 ReleaseDC( NULL, hdc );
3738 static void test_GetDIBits_scanlines(void)
3742 HDC hdc = GetDC( NULL );
3744 DWORD data[128], inverted_bits[64];
3747 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
3749 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3750 info->bmiHeader.biWidth = 8;
3751 info->bmiHeader.biHeight = 8;
3752 info->bmiHeader.biPlanes = 1;
3753 info->bmiHeader.biBitCount = 32;
3754 info->bmiHeader.biCompression = BI_RGB;
3756 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3758 for (i = 0; i < 64; i++)
3761 inverted_bits[56 - (i & ~7) + (i & 7)] = i;
3766 memset( data, 0xaa, sizeof(data) );
3768 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3769 ok( ret == 8, "got %d\n", ret );
3770 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3771 memset( data, 0xaa, sizeof(data) );
3773 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3774 ok( ret == 5, "got %d\n", ret );
3775 ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
3776 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3777 memset( data, 0xaa, sizeof(data) );
3779 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3780 ok( ret == 7, "got %d\n", ret );
3781 ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
3782 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3783 memset( data, 0xaa, sizeof(data) );
3785 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3786 ok( ret == 1, "got %d\n", ret );
3787 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3788 memset( data, 0xaa, sizeof(data) );
3790 info->bmiHeader.biHeight = 16;
3791 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3792 ok( ret == 5, "got %d\n", ret );
3793 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3794 ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
3795 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3796 memset( data, 0xaa, sizeof(data) );
3798 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3799 ok( ret == 6, "got %d\n", ret );
3800 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3801 ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
3802 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3803 memset( data, 0xaa, sizeof(data) );
3805 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3806 ok( ret == 0, "got %d\n", ret );
3807 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3808 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3809 memset( data, 0xaa, sizeof(data) );
3811 info->bmiHeader.biHeight = 5;
3812 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3813 ok( ret == 2, "got %d\n", ret );
3814 ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
3815 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3816 memset( data, 0xaa, sizeof(data) );
3820 info->bmiHeader.biHeight = -8;
3821 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3822 ok( ret == 8, "got %d\n", ret );
3823 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3824 memset( data, 0xaa, sizeof(data) );
3826 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3827 ok( ret == 5, "got %d\n", ret );
3828 ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
3829 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3830 memset( data, 0xaa, sizeof(data) );
3832 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3833 ok( ret == 7, "got %d\n", ret );
3834 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3835 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3836 memset( data, 0xaa, sizeof(data) );
3838 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3839 ok( ret == 4, "got %d\n", ret );
3840 ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
3841 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3842 memset( data, 0xaa, sizeof(data) );
3844 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3845 ok( ret == 5, "got %d\n", ret );
3846 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3847 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3848 memset( data, 0xaa, sizeof(data) );
3850 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3851 ok( ret == 5, "got %d\n", ret );
3852 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3853 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3854 memset( data, 0xaa, sizeof(data) );
3856 info->bmiHeader.biHeight = -16;
3857 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3858 ok( ret == 8, "got %d\n", ret );
3859 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3860 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3861 memset( data, 0xaa, sizeof(data) );
3863 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3864 ok( ret == 5, "got %d\n", ret );
3865 ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
3866 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3867 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3868 memset( data, 0xaa, sizeof(data) );
3870 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3871 ok( ret == 8, "got %d\n", ret );
3872 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3873 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3874 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3875 memset( data, 0xaa, sizeof(data) );
3877 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3878 ok( ret == 8, "got %d\n", ret );
3879 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3880 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3881 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3882 memset( data, 0xaa, sizeof(data) );
3884 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3885 ok( ret == 7, "got %d\n", ret );
3886 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3887 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3888 memset( data, 0xaa, sizeof(data) );
3890 ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
3891 ok( ret == 1, "got %d\n", ret );
3892 for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3893 memset( data, 0xaa, sizeof(data) );
3895 info->bmiHeader.biHeight = -5;
3896 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3897 ok( ret == 2, "got %d\n", ret );
3898 ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
3899 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3900 memset( data, 0xaa, sizeof(data) );
3902 DeleteObject( dib );
3904 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3905 info->bmiHeader.biWidth = 8;
3906 info->bmiHeader.biHeight = -8;
3907 info->bmiHeader.biPlanes = 1;
3908 info->bmiHeader.biBitCount = 32;
3909 info->bmiHeader.biCompression = BI_RGB;
3911 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3913 for (i = 0; i < 64; i++) dib_bits[i] = i;
3917 info->bmiHeader.biHeight = -8;
3918 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3919 ok( ret == 8, "got %d\n", ret );
3920 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3921 memset( data, 0xaa, sizeof(data) );
3923 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3924 ok( ret == 5, "got %d\n", ret );
3925 ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
3926 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3927 memset( data, 0xaa, sizeof(data) );
3929 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3930 ok( ret == 7, "got %d\n", ret );
3931 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3932 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3933 memset( data, 0xaa, sizeof(data) );
3935 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3936 ok( ret == 4, "got %d\n", ret );
3937 ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
3938 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3939 memset( data, 0xaa, sizeof(data) );
3941 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3942 ok( ret == 5, "got %d\n", ret );
3943 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3944 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3945 memset( data, 0xaa, sizeof(data) );
3947 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3948 ok( ret == 5, "got %d\n", ret );
3949 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3950 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3951 memset( data, 0xaa, sizeof(data) );
3953 info->bmiHeader.biHeight = -16;
3954 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3955 ok( ret == 8, "got %d\n", ret );
3956 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3957 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3958 memset( data, 0xaa, sizeof(data) );
3960 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3961 ok( ret == 5, "got %d\n", ret );
3962 ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
3963 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3964 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3965 memset( data, 0xaa, sizeof(data) );
3967 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3968 ok( ret == 8, "got %d\n", ret );
3969 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3970 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3971 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3972 memset( data, 0xaa, sizeof(data) );
3974 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3975 ok( ret == 8, "got %d\n", ret );
3976 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3977 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3978 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3979 memset( data, 0xaa, sizeof(data) );
3981 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3982 ok( ret == 7, "got %d\n", ret );
3983 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3984 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3985 memset( data, 0xaa, sizeof(data) );
3987 info->bmiHeader.biHeight = -5;
3988 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3989 ok( ret == 2, "got %d\n", ret );
3990 ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
3991 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3992 memset( data, 0xaa, sizeof(data) );
3997 info->bmiHeader.biHeight = 8;
3999 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4000 ok( ret == 8, "got %d\n", ret );
4001 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4002 memset( data, 0xaa, sizeof(data) );
4004 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4005 ok( ret == 5, "got %d\n", ret );
4006 ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
4007 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4008 memset( data, 0xaa, sizeof(data) );
4010 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4011 ok( ret == 7, "got %d\n", ret );
4012 ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
4013 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4014 memset( data, 0xaa, sizeof(data) );
4016 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4017 ok( ret == 1, "got %d\n", ret );
4018 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4019 memset( data, 0xaa, sizeof(data) );
4021 info->bmiHeader.biHeight = 16;
4022 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4023 ok( ret == 5, "got %d\n", ret );
4024 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4025 ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
4026 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4027 memset( data, 0xaa, sizeof(data) );
4029 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
4030 ok( ret == 6, "got %d\n", ret );
4031 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4032 ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
4033 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4034 memset( data, 0xaa, sizeof(data) );
4036 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
4037 ok( ret == 0, "got %d\n", ret );
4038 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4039 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4040 memset( data, 0xaa, sizeof(data) );
4042 info->bmiHeader.biHeight = 5;
4043 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4044 ok( ret == 2, "got %d\n", ret );
4045 ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
4046 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4047 memset( data, 0xaa, sizeof(data) );
4049 DeleteObject( dib );
4051 ReleaseDC( NULL, hdc );
4052 HeapFree( GetProcessHeap(), 0, info );
4056 static void test_SetDIBits(void)
4060 HDC hdc = GetDC( NULL );
4061 DWORD data[128], inverted_data[128];
4065 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4067 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4068 info->bmiHeader.biWidth = 8;
4069 info->bmiHeader.biHeight = 8;
4070 info->bmiHeader.biPlanes = 1;
4071 info->bmiHeader.biBitCount = 32;
4072 info->bmiHeader.biCompression = BI_RGB;
4074 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4075 memset( dib_bits, 0xaa, 64 * 4 );
4077 for (i = 0; i < 128; i++)
4080 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4085 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4086 ok( ret == 8, "got %d\n", ret );
4087 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4088 memset( dib_bits, 0xaa, 64 * 4 );
4090 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4091 ok( ret == 5, "got %d\n", ret );
4092 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4093 ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
4094 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4095 memset( dib_bits, 0xaa, 64 * 4 );
4097 /* top of dst is aligned with startscans down for the top of the src.
4098 Then starting from the bottom of src, lines rows are copied across. */
4100 info->bmiHeader.biHeight = 16;
4101 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4102 ok( ret == 12, "got %d\n", ret );
4103 ok( !memcmp( dib_bits, data + 56, 40 * 4 ), "bits differ\n");
4104 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4105 memset( dib_bits, 0xaa, 64 * 4 );
4107 info->bmiHeader.biHeight = 5;
4108 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4109 ok( ret == 2, "got %d\n", ret );
4110 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4111 ok( !memcmp( dib_bits + 32, data, 16 * 4 ), "bits differ\n");
4112 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4113 memset( dib_bits, 0xaa, 64 * 4 );
4116 info->bmiHeader.biHeight = -8;
4117 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4118 ok( ret == 8, "got %d\n", ret );
4119 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4120 memset( dib_bits, 0xaa, 64 * 4 );
4122 /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
4123 we copy lines rows from the top of the src */
4125 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4126 ok( ret == 5, "got %d\n", ret );
4127 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4128 ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
4129 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4130 memset( dib_bits, 0xaa, 64 * 4 );
4132 info->bmiHeader.biHeight = -16;
4133 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4134 ok( ret == 12, "got %d\n", ret );
4135 ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
4136 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4137 memset( dib_bits, 0xaa, 64 * 4 );
4139 ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4140 ok( ret == 12, "got %d\n", ret );
4141 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4142 memset( dib_bits, 0xaa, 64 * 4 );
4144 ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4145 ok( ret == 12, "got %d\n", ret );
4146 ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
4147 memset( dib_bits, 0xaa, 64 * 4 );
4149 info->bmiHeader.biHeight = -5;
4150 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4151 ok( ret == 2, "got %d\n", ret );
4152 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4153 ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
4154 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4155 memset( dib_bits, 0xaa, 64 * 4 );
4157 DeleteObject( dib );
4159 info->bmiHeader.biHeight = -8;
4161 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4162 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4166 /* like the t-d -> b-u case. */
4168 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4169 ok( ret == 8, "got %d\n", ret );
4170 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4171 memset( dib_bits, 0xaa, 64 * 4 );
4173 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4174 ok( ret == 5, "got %d\n", ret );
4175 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4176 ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
4177 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4178 memset( dib_bits, 0xaa, 64 * 4 );
4180 info->bmiHeader.biHeight = -16;
4181 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4182 ok( ret == 12, "got %d\n", ret );
4183 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4184 ok( !memcmp( dib_bits + 24, data, 40 * 4 ), "bits differ\n");
4185 memset( dib_bits, 0xaa, 64 * 4 );
4187 info->bmiHeader.biHeight = -5;
4188 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4189 ok( ret == 2, "got %d\n", ret );
4190 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4191 ok( !memcmp( dib_bits + 16, data, 16 * 4 ), "bits differ\n");
4192 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4193 memset( dib_bits, 0xaa, 64 * 4 );
4196 /* like the b-u -> b-u case */
4198 info->bmiHeader.biHeight = 8;
4199 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4200 ok( ret == 8, "got %d\n", ret );
4201 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4202 memset( dib_bits, 0xaa, 64 * 4 );
4204 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4205 ok( ret == 5, "got %d\n", ret );
4206 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4207 ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
4208 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4209 memset( dib_bits, 0xaa, 64 * 4 );
4211 info->bmiHeader.biHeight = 16;
4212 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4213 ok( ret == 12, "got %d\n", ret );
4214 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4215 ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
4216 memset( dib_bits, 0xaa, 64 * 4 );
4218 info->bmiHeader.biHeight = 5;
4219 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4220 ok( ret == 2, "got %d\n", ret );
4221 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4222 ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
4223 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4224 memset( dib_bits, 0xaa, 64 * 4 );
4226 DeleteObject( dib );
4227 ReleaseDC( NULL, hdc );
4228 HeapFree( GetProcessHeap(), 0, info );
4231 static void test_SetDIBits_RLE4(void)
4235 HDC hdc = GetDC( NULL );
4236 BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00, /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
4237 0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
4238 0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00, /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
4239 0x00, 0x02, 0x01, 0x02, 0x05, 0x87, /* dx=1, dy=2, 8, 7, 8, 7, 8 */
4240 0x00, 0x01 }; /* <eod> */
4243 DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
4244 0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
4245 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4246 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4247 0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
4248 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4249 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4250 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4252 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4254 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4255 info->bmiHeader.biWidth = 8;
4256 info->bmiHeader.biHeight = 8;
4257 info->bmiHeader.biPlanes = 1;
4258 info->bmiHeader.biBitCount = 32;
4259 info->bmiHeader.biCompression = BI_RGB;
4261 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4262 memset( dib_bits, 0xaa, 64 * 4 );
4264 info->bmiHeader.biBitCount = 4;
4265 info->bmiHeader.biCompression = BI_RLE4;
4266 info->bmiHeader.biSizeImage = sizeof(rle4_data);
4268 for (i = 0; i < 16; i++)
4270 info->bmiColors[i].rgbRed = i;
4271 info->bmiColors[i].rgbGreen = i;
4272 info->bmiColors[i].rgbBlue = i;
4273 info->bmiColors[i].rgbReserved = 0;
4276 ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
4277 ok( ret == 8, "got %d\n", ret );
4278 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
4279 memset( dib_bits, 0xaa, 64 * 4 );
4281 DeleteObject( dib );
4282 ReleaseDC( NULL, hdc );
4283 HeapFree( GetProcessHeap(), 0, info );
4286 static void test_SetDIBits_RLE8(void)
4290 HDC hdc = GetDC( NULL );
4291 BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00, /* 2, 2, 2, f0, f0, f0, f0, <eol> */
4292 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4293 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4294 0x00, 0x01 }; /* <eod> */
4297 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4298 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4299 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4300 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4301 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4302 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4303 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4304 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4305 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4306 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4307 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4308 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4309 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4310 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4311 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4312 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4314 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4316 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4317 info->bmiHeader.biWidth = 8;
4318 info->bmiHeader.biHeight = 8;
4319 info->bmiHeader.biPlanes = 1;
4320 info->bmiHeader.biBitCount = 32;
4321 info->bmiHeader.biCompression = BI_RGB;
4323 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4324 memset( dib_bits, 0xaa, 64 * 4 );
4326 info->bmiHeader.biBitCount = 8;
4327 info->bmiHeader.biCompression = BI_RLE8;
4328 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4330 for (i = 0; i < 256; i++)
4332 info->bmiColors[i].rgbRed = i;
4333 info->bmiColors[i].rgbGreen = i;
4334 info->bmiColors[i].rgbBlue = i;
4335 info->bmiColors[i].rgbReserved = 0;
4338 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4339 ok( ret == 8, "got %d\n", ret );
4340 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4341 memset( dib_bits, 0xaa, 64 * 4 );
4343 /* startscan and lines are ignored, unless lines == 0 */
4344 ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4345 ok( ret == 8, "got %d\n", ret );
4346 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4347 memset( dib_bits, 0xaa, 64 * 4 );
4349 ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4350 ok( ret == 8, "got %d\n", ret );
4351 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4352 memset( dib_bits, 0xaa, 64 * 4 );
4354 ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4355 ok( ret == 0, "got %d\n", ret );
4356 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4357 memset( dib_bits, 0xaa, 64 * 4 );
4359 /* reduce width to 4, left-hand side of dst is touched. */
4360 info->bmiHeader.biWidth = 4;
4361 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4362 ok( ret == 8, "got %d\n", ret );
4363 for (i = 0; i < 64; i++)
4365 DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4366 ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4368 memset( dib_bits, 0xaa, 64 * 4 );
4370 /* Show that the top lines are aligned by adjusting the height of the src */
4372 /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4373 info->bmiHeader.biWidth = 8;
4374 info->bmiHeader.biHeight = 4;
4375 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4376 ok( ret == 4, "got %d\n", ret );
4377 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4378 ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4379 memset( dib_bits, 0xaa, 64 * 4 );
4381 /* increase the height to 9 -> everything moves down one row. */
4382 info->bmiHeader.biHeight = 9;
4383 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4384 ok( ret == 9, "got %d\n", ret );
4385 ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4386 for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4387 memset( dib_bits, 0xaa, 64 * 4 );
4389 /* top-down compressed dibs are invalid */
4390 info->bmiHeader.biHeight = -8;
4391 SetLastError( 0xdeadbeef );
4392 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4393 ok( ret == 0, "got %d\n", ret );
4394 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4395 DeleteObject( dib );
4399 info->bmiHeader.biHeight = -8;
4400 info->bmiHeader.biBitCount = 32;
4401 info->bmiHeader.biCompression = BI_RGB;
4402 info->bmiHeader.biSizeImage = 0;
4404 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4405 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4407 info->bmiHeader.biHeight = 8;
4408 info->bmiHeader.biBitCount = 8;
4409 info->bmiHeader.biCompression = BI_RLE8;
4410 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4412 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4413 ok( ret == 8, "got %d\n", ret );
4414 ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4415 memset( dib_bits, 0xaa, 64 * 4 );
4417 info->bmiHeader.biHeight = 4;
4418 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4419 ok( ret == 4, "got %d\n", ret );
4420 ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4421 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4422 memset( dib_bits, 0xaa, 64 * 4 );
4424 info->bmiHeader.biHeight = 9;
4425 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4426 ok( ret == 9, "got %d\n", ret );
4427 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4428 ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4429 memset( dib_bits, 0xaa, 64 * 4 );
4431 DeleteObject( dib );
4432 ReleaseDC( NULL, hdc );
4433 HeapFree( GetProcessHeap(), 0, info );
4436 static void test_SetDIBitsToDevice(void)
4440 HDC hdc = CreateCompatibleDC( 0 );
4441 DWORD data[128], inverted_data[128];
4445 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4447 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4448 info->bmiHeader.biWidth = 8;
4449 info->bmiHeader.biHeight = 8;
4450 info->bmiHeader.biPlanes = 1;
4451 info->bmiHeader.biBitCount = 32;
4452 info->bmiHeader.biCompression = BI_RGB;
4454 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4455 memset( dib_bits, 0xaa, 64 * 4 );
4456 SelectObject( hdc, dib );
4458 for (i = 0; i < 128; i++)
4461 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4466 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4467 ok( ret == 8, "got %d\n", ret );
4468 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4469 memset( dib_bits, 0xaa, 64 * 4 );
4471 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4472 ok( ret == 5, "got %d\n", ret );
4473 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4474 for (i = 8; i < 48; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4475 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4476 memset( dib_bits, 0xaa, 64 * 4 );
4478 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 3, 1, 5, data, info, DIB_RGB_COLORS );
4479 ok( ret == 5, "got %d\n", ret );
4480 for (i = 0; i < 24; i++) ok( dib_bits[i] == data[i + 16], "%d: got %08x\n", i, dib_bits[i] );
4481 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4482 memset( dib_bits, 0xaa, 64 * 4 );
4484 info->bmiHeader.biHeight = 16;
4485 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4486 ok( ret == 7, "got %d\n", ret );
4487 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4488 for (i = 8; i < 64; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4489 memset( dib_bits, 0xaa, 64 * 4 );
4491 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 8, 0, 6, 1, 12, data, info, DIB_RGB_COLORS );
4492 ok( ret == 12, "got %d\n", ret );
4493 for (i = 0; i < 40; i++) ok( dib_bits[i] == data[i + 56], "%d: got %08x\n", i, dib_bits[i] );
4494 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4495 memset( dib_bits, 0xaa, 64 * 4 );
4497 ret = SetDIBitsToDevice( hdc, 0, -4, 8, 8, 0, 3, 1, 12, data, info, DIB_RGB_COLORS );
4498 ok( ret == 10, "got %d\n", ret );
4499 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4500 for (i = 32; i < 64; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4501 memset( dib_bits, 0xaa, 64 * 4 );
4503 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, -3, 1, 12, data, info, DIB_RGB_COLORS );
4504 ok( ret == 4, "got %d\n", ret );
4505 for (i = 0; i < 32; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4506 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4507 memset( dib_bits, 0xaa, 64 * 4 );
4509 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 5, 0, -2, 1, 12, data, info, DIB_RGB_COLORS );
4510 ok( ret == 2, "got %d\n", ret );
4511 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4512 for (i = 32; i < 48; i++) ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4513 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4514 memset( dib_bits, 0xaa, 64 * 4 );
4516 info->bmiHeader.biHeight = 5;
4517 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 2, 2, data, info, DIB_RGB_COLORS );
4518 ok( ret == 2, "got %d\n", ret );
4519 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4520 for (i = 16; i < 32; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4521 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4522 memset( dib_bits, 0xaa, 64 * 4 );
4524 ret = SetDIBitsToDevice( hdc, 3, 3, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4525 ok( ret == 3, "got %d\n", ret );
4526 for (i = 0; i < 64; i++)
4527 if (i == 27 || i == 28 || i == 35 || i == 36)
4528 ok( dib_bits[i] == data[i - 18], "%d: got %08x\n", i, dib_bits[i] );
4530 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4531 memset( dib_bits, 0xaa, 64 * 4 );
4533 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4534 ok( ret == 5, "got %d\n", ret );
4535 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4536 memset( dib_bits, 0xaa, 64 * 4 );
4538 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4539 ok( ret == 0, "got %d\n", ret );
4540 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4541 memset( dib_bits, 0xaa, 64 * 4 );
4543 SetMapMode( hdc, MM_ANISOTROPIC );
4544 SetWindowExtEx( hdc, 3, 3, NULL );
4545 ret = SetDIBitsToDevice( hdc, 2, 2, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4546 ok( ret == 3, "got %d\n", ret );
4547 for (i = 0; i < 64; i++)
4548 if (i == 41 || i == 42 || i == 49 || i == 50)
4549 ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4551 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4552 memset( dib_bits, 0xaa, 64 * 4 );
4554 SetWindowExtEx( hdc, -1, -1, NULL );
4555 ret = SetDIBitsToDevice( hdc, 2, 2, 4, 4, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4556 ok( ret == 4, "got %d\n", ret );
4557 for (i = 0; i < 64; i++)
4558 if (i == 48 || i == 49 || i == 56 || i == 57)
4559 ok( dib_bits[i] == data[i - 37], "%d: got %08x\n", i, dib_bits[i] );
4561 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4562 memset( dib_bits, 0xaa, 64 * 4 );
4563 SetMapMode( hdc, MM_TEXT );
4567 pSetLayout( hdc, LAYOUT_RTL );
4568 ret = SetDIBitsToDevice( hdc, 1, 2, 3, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4569 ok( ret == 3, "got %d\n", ret );
4570 for (i = 0; i < 64; i++)
4571 if (i == 36 || i == 37 || i == 38 || i == 44 || i == 45 || i == 46)
4572 ok( dib_bits[i] == data[i - 27], "%d: got %08x\n", i, dib_bits[i] );
4574 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4575 memset( dib_bits, 0xaa, 64 * 4 );
4576 pSetLayout( hdc, LAYOUT_LTR );
4580 info->bmiHeader.biHeight = -8;
4581 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4582 ok( ret == 8, "got %d\n", ret );
4583 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4584 memset( dib_bits, 0xaa, 64 * 4 );
4586 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4587 ok( ret == 5, "got %d\n", ret );
4588 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4589 for (i = 8; i < 48; i++) ok( dib_bits[i] == inverted_data[i + 80], "%d: got %08x\n", i, dib_bits[i] );
4590 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4591 memset( dib_bits, 0xaa, 64 * 4 );
4593 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 4, 1, 5, data, info, DIB_RGB_COLORS );
4594 ok( ret == 5, "got %d\n", ret );
4595 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4596 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4597 memset( dib_bits, 0xaa, 64 * 4 );
4599 info->bmiHeader.biHeight = -16;
4600 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4601 ok( ret == 12, "got %d\n", ret );
4602 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4603 for (i = 8; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4604 memset( dib_bits, 0xaa, 64 * 4 );
4606 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, 7, 1, 12, data, info, DIB_RGB_COLORS );
4607 ok( ret == 12, "got %d\n", ret );
4608 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4609 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4610 memset( dib_bits, 0xaa, 64 * 4 );
4612 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 4, 12, data, info, DIB_RGB_COLORS );
4613 ok( ret == 12, "got %d\n", ret );
4614 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4615 for (i = 32; i < 64; i++) ok( dib_bits[i] == inverted_data[i], "%d: got %08x\n", i, dib_bits[i] );
4616 memset( dib_bits, 0xaa, 64 * 4 );
4618 ret = SetDIBitsToDevice( hdc, 0, -3, 8, 8, 0, 2, 4, 12, data, info, DIB_RGB_COLORS );
4619 ok( ret == 12, "got %d\n", ret );
4620 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4621 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4622 memset( dib_bits, 0xaa, 64 * 4 );
4624 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, -2, 4, 12, data, info, DIB_RGB_COLORS );
4625 ok( ret == 12, "got %d\n", ret );
4626 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4627 for (i = 24; i < 40; i++) ok( dib_bits[i] == inverted_data[i + 8], "%d: got %08x\n", i, dib_bits[i] );
4628 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4629 memset( dib_bits, 0xaa, 64 * 4 );
4631 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 5, 12, data, info, DIB_RGB_COLORS );
4632 ok( ret == 12, "got %d\n", ret );
4633 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4634 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4635 memset( dib_bits, 0xaa, 64 * 4 );
4637 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4638 ok( ret == 12, "got %d\n", ret );
4639 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4640 memset( dib_bits, 0xaa, 64 * 4 );
4642 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -2, -4, 0, 12, data, info, DIB_RGB_COLORS );
4643 ok( ret == 12, "got %d\n", ret );
4644 for (i = 0; i < 64; i++)
4645 if (i == 31 || i == 39 || i == 47 || i == 55 || i == 63)
4646 ok( dib_bits[i] == inverted_data[i + 1], "%d: got %08x\n", i, dib_bits[i] );
4648 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4649 memset( dib_bits, 0xaa, 64 * 4 );
4651 info->bmiHeader.biHeight = -5;
4652 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4653 ok( ret == 2, "got %d\n", ret );
4654 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4655 for (i = 8; i < 24; i++) ok( dib_bits[i] == inverted_data[i + 104], "%d: got %08x\n", i, dib_bits[i] );
4656 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4657 memset( dib_bits, 0xaa, 64 * 4 );
4659 ret = SetDIBitsToDevice( hdc, 5, 4, 2, 2, 6, 3, 1, 5, data, info, DIB_RGB_COLORS );
4660 ok( ret == 5, "got %d\n", ret );
4661 for (i = 0; i < 64; i++)
4662 if (i == 21 || i == 22 || i == 29 || i == 30)
4663 ok( dib_bits[i] == inverted_data[i + 89], "%d: got %08x\n", i, dib_bits[i] );
4665 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4666 memset( dib_bits, 0xaa, 64 * 4 );
4668 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4669 ok( ret == 5, "got %d\n", ret );
4670 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4671 memset( dib_bits, 0xaa, 64 * 4 );
4673 info->bmiHeader.biHeight = -8;
4675 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4676 DeleteObject( SelectObject( hdc, dib ));
4677 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4681 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4682 ok( ret == 8, "got %d\n", ret );
4683 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4684 memset( dib_bits, 0xaa, 64 * 4 );
4686 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4687 ok( ret == 5, "got %d\n", ret );
4688 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4689 for (i = 16; i < 56; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4690 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4691 memset( dib_bits, 0xaa, 64 * 4 );
4693 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 3, 0, 2, 1, 5, data, info, DIB_RGB_COLORS );
4694 ok( ret == 5, "got %d\n", ret );
4695 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4696 for (i = 24; i < 48; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4697 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4698 memset( dib_bits, 0xaa, 64 * 4 );
4700 info->bmiHeader.biHeight = -16;
4701 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4702 ok( ret == 12, "got %d\n", ret );
4703 for (i = 0; i < 56; i++) ok( dib_bits[i] == data[i + 40], "%d: got %08x\n", i, dib_bits[i] );
4704 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4705 memset( dib_bits, 0xaa, 64 * 4 );
4707 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -1, -8, 0, 12, data, info, DIB_RGB_COLORS );
4708 ok( ret == 12, "got %d\n", ret );
4709 for (i = 0; i < 64; i++)
4710 if (i == 6 || i == 7)
4711 ok( dib_bits[i] == data[i + 82], "%d: got %08x\n", i, dib_bits[i] );
4713 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4714 memset( dib_bits, 0xaa, 64 * 4 );
4716 info->bmiHeader.biHeight = -5;
4717 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4718 ok( ret == 2, "got %d\n", ret );
4719 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4720 for (i = 40; i < 56; i++) ok( dib_bits[i] == data[i - 40], "%d: got %08x\n", i, dib_bits[i] );
4721 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4722 memset( dib_bits, 0xaa, 64 * 4 );
4724 ret = SetDIBitsToDevice( hdc, 7, 2, 8, 8, 1, 0, 0, 5, data, info, DIB_RGB_COLORS );
4725 ok( ret == 5, "got %d\n", ret );
4726 for (i = 0; i < 64; i++)
4727 if (i == 47 || i == 55 || i == 63)
4728 ok( dib_bits[i] == data[i - 46], "%d: got %08x\n", i, dib_bits[i] );
4730 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4731 memset( dib_bits, 0xaa, 64 * 4 );
4733 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4734 ok( ret == 5, "got %d\n", ret );
4735 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4736 memset( dib_bits, 0xaa, 64 * 4 );
4740 info->bmiHeader.biHeight = 8;
4741 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4742 ok( ret == 8, "got %d\n", ret );
4743 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4744 memset( dib_bits, 0xaa, 64 * 4 );
4746 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4747 ok( ret == 5, "got %d\n", ret );
4748 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4749 for (i = 16; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4750 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4751 memset( dib_bits, 0xaa, 64 * 4 );
4753 info->bmiHeader.biHeight = 16;
4754 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4755 ok( ret == 7, "got %d\n", ret );
4756 for (i = 0; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4757 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4758 memset( dib_bits, 0xaa, 64 * 4 );
4760 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, 0, -4, 1, 12, data, info, DIB_RGB_COLORS );
4761 ok( ret == 3, "got %d\n", ret );
4762 for (i = 0; i < 64; i++)
4763 if ((i >= 36 && i <= 39) || (i >= 44 && i <= 47) || (i >= 52 && i <= 55))
4764 ok( dib_bits[i] == inverted_data[i + 68], "%d: got %08x\n", i, dib_bits[i] );
4766 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4767 memset( dib_bits, 0xaa, 64 * 4 );
4769 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, -30, -30, 1, 12, data, info, DIB_RGB_COLORS );
4770 ok( ret == 0, "got %d\n", ret );
4771 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4772 memset( dib_bits, 0xaa, 64 * 4 );
4774 ret = SetDIBitsToDevice( hdc, 5, -5, 8, 16, -2, -4, 4, 12, data, info, DIB_RGB_COLORS );
4775 ok( ret == 8, "got %d\n", ret );
4776 for (i = 0; i < 64; i++)
4777 if (i == 7 || i == 15 || i == 23)
4778 ok( dib_bits[i] == inverted_data[i + 97], "%d: got %08x\n", i, dib_bits[i] );
4780 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4781 memset( dib_bits, 0xaa, 64 * 4 );
4783 info->bmiHeader.biHeight = 5;
4784 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4785 ok( ret == 2, "got %d\n", ret );
4786 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4787 for (i = 40; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4788 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4789 memset( dib_bits, 0xaa, 64 * 4 );
4791 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4792 ok( ret == 5, "got %d\n", ret );
4793 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4794 memset( dib_bits, 0xaa, 64 * 4 );
4797 DeleteObject( dib );
4798 HeapFree( GetProcessHeap(), 0, info );
4801 static void test_SetDIBitsToDevice_RLE8(void)
4805 HDC hdc = CreateCompatibleDC( 0 );
4806 BYTE rle8_data[20] = { 0x04, 0x02, 0x03, 0xf0, 0x00, 0x00, /* 2, 2, 2, 2, f0, f0, f0, <eol> */
4807 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4808 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4809 0x00, 0x01 }; /* <eod> */
4812 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4813 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4814 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4815 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4816 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4817 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4818 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4819 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4820 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4821 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4822 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4823 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4824 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4825 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4826 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4827 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4829 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4831 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4832 info->bmiHeader.biWidth = 8;
4833 info->bmiHeader.biHeight = 8;
4834 info->bmiHeader.biPlanes = 1;
4835 info->bmiHeader.biBitCount = 32;
4836 info->bmiHeader.biCompression = BI_RGB;
4838 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4839 memset( dib_bits, 0xaa, 64 * 4 );
4840 SelectObject( hdc, dib );
4842 info->bmiHeader.biBitCount = 8;
4843 info->bmiHeader.biCompression = BI_RLE8;
4844 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4846 for (i = 0; i < 256; i++)
4848 info->bmiColors[i].rgbRed = i;
4849 info->bmiColors[i].rgbGreen = i;
4850 info->bmiColors[i].rgbBlue = i;
4851 info->bmiColors[i].rgbReserved = 0;
4854 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4855 ok( ret == 8, "got %d\n", ret );
4856 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4857 memset( dib_bits, 0xaa, 64 * 4 );
4859 /* startscan and lines are ignored, unless lines == 0 */
4860 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 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] == bottom_up[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, 1, 1, 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] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4868 memset( dib_bits, 0xaa, 64 * 4 );
4870 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4871 ok( ret == 0, "got %d\n", ret );
4872 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4873 memset( dib_bits, 0xaa, 64 * 4 );
4875 info->bmiHeader.biWidth = 2;
4876 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4877 ok( ret == 8, "got %d\n", ret );
4878 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4879 memset( dib_bits, 0xaa, 64 * 4 );
4881 info->bmiHeader.biWidth = 8;
4882 info->bmiHeader.biHeight = 2;
4883 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4884 ok( ret == 2, "got %d\n", ret );
4885 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4886 memset( dib_bits, 0xaa, 64 * 4 );
4888 info->bmiHeader.biHeight = 9;
4889 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4890 ok( ret == 9, "got %d\n", ret );
4891 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4892 memset( dib_bits, 0xaa, 64 * 4 );
4894 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4895 ok( ret == 9, "got %d\n", ret );
4896 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4897 memset( dib_bits, 0xaa, 64 * 4 );
4899 info->bmiHeader.biHeight = 8;
4900 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 9, rle8_data, info, DIB_RGB_COLORS );
4901 ok( ret == 8, "got %d\n", ret );
4902 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4903 memset( dib_bits, 0xaa, 64 * 4 );
4905 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4906 ok( ret == 8, "got %d\n", ret );
4907 for (i = 0; i < 40; i++) ok( dib_bits[i] == bottom_up[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4908 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4909 memset( dib_bits, 0xaa, 64 * 4 );
4911 ret = SetDIBitsToDevice( hdc, 0, 3, 4, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4912 ok( ret == 8, "got %d\n", ret );
4913 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4914 for (i = 8; i < 40; i++)
4915 if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4916 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4917 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4918 memset( dib_bits, 0xaa, 64 * 4 );
4920 ret = SetDIBitsToDevice( hdc, 3, 3, 8, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4921 ok( ret == 8, "got %d\n", ret );
4922 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4923 for (i = 8; i < 40; i++)
4924 if ((i & 7) < 3) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4925 else ok( dib_bits[i] == bottom_up[i - 11], "%d: got %08x\n", i, dib_bits[i] );
4926 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4927 memset( dib_bits, 0xaa, 64 * 4 );
4929 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 4, 2, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4930 ok( ret == 8, "got %d\n", ret );
4931 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4932 for (i = 8; i < 40; i++)
4933 if ((i & 7) < 2) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4934 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4935 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4936 memset( dib_bits, 0xaa, 64 * 4 );
4938 info->bmiHeader.biWidth = 37;
4939 info->bmiHeader.biHeight = 37;
4940 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
4941 ok( ret == 37, "got %d\n", ret );
4942 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4943 for (i = 24; i < 64; i++)
4944 if (i == 52) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
4945 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4946 else ok( dib_bits[i] == bottom_up[i - 20], "%d: got %08x\n", i, dib_bits[i] );
4947 memset( dib_bits, 0xaa, 64 * 4 );
4949 /* top-down compressed dibs are invalid */
4950 info->bmiHeader.biWidth = 8;
4951 info->bmiHeader.biHeight = -8;
4952 SetLastError( 0xdeadbeef );
4953 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4954 ok( ret == 0, "got %d\n", ret );
4955 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4959 info->bmiHeader.biHeight = -8;
4960 info->bmiHeader.biBitCount = 32;
4961 info->bmiHeader.biCompression = BI_RGB;
4962 info->bmiHeader.biSizeImage = 0;
4964 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4965 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4966 DeleteObject( SelectObject( hdc, dib ));
4968 info->bmiHeader.biHeight = 8;
4969 info->bmiHeader.biBitCount = 8;
4970 info->bmiHeader.biCompression = BI_RLE8;
4971 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4973 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4974 ok( ret == 8, "got %d\n", ret );
4975 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4976 memset( dib_bits, 0xaa, 64 * 4 );
4978 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4979 ok( ret == 8, "got %d\n", ret );
4980 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4981 memset( dib_bits, 0xaa, 64 * 4 );
4983 info->bmiHeader.biHeight = 4;
4984 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4985 ok( ret == 4, "got %d\n", ret );
4986 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4987 memset( dib_bits, 0xaa, 64 * 4 );
4989 info->bmiHeader.biHeight = 9;
4990 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4991 ok( ret == 9, "got %d\n", ret );
4992 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4993 memset( dib_bits, 0xaa, 64 * 4 );
4995 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4996 ok( ret == 9, "got %d\n", ret );
4997 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4998 memset( dib_bits, 0xaa, 64 * 4 );
5000 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 6, 2, 2, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5001 ok( ret == 9, "got %d\n", ret );
5002 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5003 for (i = 24; i < 64; i++) ok( dib_bits[i] == top_down[i - 24], "%d: got %08x\n", i, dib_bits[i] );
5004 memset( dib_bits, 0xaa, 64 * 4 );
5006 info->bmiHeader.biWidth = 37;
5007 info->bmiHeader.biHeight = 37;
5008 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
5009 ok( ret == 37, "got %d\n", ret );
5010 for (i = 0; i < 40; i++)
5011 if (i == 12) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
5012 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5013 else ok( dib_bits[i] == top_down[i + 28], "%d: got %08x\n", i, dib_bits[i] );
5014 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5015 memset( dib_bits, 0xaa, 64 * 4 );
5018 DeleteObject( dib );
5019 HeapFree( GetProcessHeap(), 0, info );
5026 hdll = GetModuleHandle("gdi32.dll");
5027 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
5028 pGdiGradientFill = (void*)GetProcAddress(hdll, "GdiGradientFill");
5029 pSetLayout = (void*)GetProcAddress(hdll, "SetLayout");
5031 test_createdibitmap();
5034 test_mono_dibsection();
5037 test_GetDIBits_selected_DIB(1);
5038 test_GetDIBits_selected_DIB(4);
5039 test_GetDIBits_selected_DIB(8);
5040 test_GetDIBits_selected_DDB(TRUE);
5041 test_GetDIBits_selected_DDB(FALSE);
5043 test_GetDIBits_BI_BITFIELDS();
5044 test_select_object();
5045 test_CreateBitmap();
5048 test_StretchDIBits();
5049 test_GdiAlphaBlend();
5050 test_GdiGradientFill();
5051 test_32bit_bitmap_blt();
5052 test_bitmapinfoheadersize();
5055 test_GetDIBits_top_down(16);
5056 test_GetDIBits_top_down(24);
5057 test_GetDIBits_top_down(32);
5058 test_GetSetDIBits_rtl();
5059 test_GetDIBits_scanlines();
5061 test_SetDIBits_RLE4();
5062 test_SetDIBits_RLE8();
5063 test_SetDIBitsToDevice();
5064 test_SetDIBitsToDevice_RLE8();