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, 1, tri, 0, GRADIENT_FILL_TRIANGLE );
3421 ok( !ret, "GdiGradientFill succeeded\n" );
3422 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3423 SetLastError( 0xdeadbeef );
3424 ret = pGdiGradientFill( hdc, vt, 1, tri, 1, GRADIENT_FILL_TRIANGLE );
3425 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3426 SetLastError( 0xdeadbeef );
3427 ret = pGdiGradientFill( hdc, vt, 3, tri, 2, GRADIENT_FILL_TRIANGLE );
3428 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3429 SetLastError( 0xdeadbeef );
3430 ret = pGdiGradientFill( hdc, vt, 3, tri, 3, GRADIENT_FILL_TRIANGLE );
3431 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3434 DeleteObject( bmp );
3437 static void test_clipping(void)
3445 HDC hdcDst = CreateCompatibleDC( NULL );
3446 HDC hdcSrc = CreateCompatibleDC( NULL );
3448 BITMAPINFO bmpinfo={{0}};
3449 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3450 bmpinfo.bmiHeader.biWidth = 100;
3451 bmpinfo.bmiHeader.biHeight = 100;
3452 bmpinfo.bmiHeader.biPlanes = 1;
3453 bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3454 bmpinfo.bmiHeader.biCompression = BI_RGB;
3456 bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3457 ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3458 SelectObject( hdcDst, bmpDst );
3460 bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3461 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3462 SelectObject( hdcSrc, bmpSrc );
3464 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3465 ok(result, "BitBlt failed\n");
3467 hRgn = CreateRectRgn( 0,0,0,0 );
3468 SelectClipRgn( hdcDst, hRgn );
3470 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3471 ok(result, "BitBlt failed\n");
3473 DeleteObject( bmpDst );
3474 DeleteObject( bmpSrc );
3475 DeleteObject( hRgn );
3480 static void test_32bit_bitmap_blt(void)
3483 HBITMAP bmpSrc, bmpDst;
3484 HBITMAP oldSrc, oldDst;
3485 HDC hdcSrc, hdcDst, hdcScreen;
3487 DWORD colorSrc = 0x11223344;
3489 memset(&biDst, 0, sizeof(BITMAPINFO));
3490 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3491 biDst.bmiHeader.biWidth = 2;
3492 biDst.bmiHeader.biHeight = -2;
3493 biDst.bmiHeader.biPlanes = 1;
3494 biDst.bmiHeader.biBitCount = 32;
3495 biDst.bmiHeader.biCompression = BI_RGB;
3497 hdcScreen = CreateCompatibleDC(0);
3498 if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3500 DeleteDC(hdcScreen);
3501 trace("Skipping 32-bit DDB test\n");
3505 hdcSrc = CreateCompatibleDC(hdcScreen);
3506 bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3507 oldSrc = SelectObject(hdcSrc, bmpSrc);
3509 hdcDst = CreateCompatibleDC(hdcScreen);
3510 bmpDst = CreateDIBSection(hdcDst, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3511 oldDst = SelectObject(hdcDst, bmpDst);
3513 StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3514 ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3517 SelectObject(hdcDst, oldDst);
3518 DeleteObject(bmpDst);
3521 SelectObject(hdcSrc, oldSrc);
3522 DeleteObject(bmpSrc);
3525 DeleteDC(hdcScreen);
3529 * Used by test_GetDIBits_top_down to create the bitmap to test against.
3531 static void setup_picture(char *picture, int bpp)
3539 /*Set the first byte in each pixel to the index of that pixel.*/
3540 for (i = 0; i < 4; i++)
3541 picture[i * (bpp / 8)] = i;
3546 /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
3553 static void test_GetDIBits_top_down(int bpp)
3556 HBITMAP bmptb, bmpbt;
3562 memset( &bi, 0, sizeof(bi) );
3563 bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
3564 bi.bmiHeader.biWidth=2;
3565 bi.bmiHeader.biHeight=2;
3566 bi.bmiHeader.biPlanes=1;
3567 bi.bmiHeader.biBitCount=bpp;
3568 bi.bmiHeader.biCompression=BI_RGB;
3570 /*Get the device context for the screen.*/
3572 ok(hdc != NULL, "Could not get a handle to a device context.\n");
3574 /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
3575 bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3576 ok(bmpbt != NULL, "Could not create a DIB section.\n");
3577 /*Now that we have a pointer to the pixels, we write to them.*/
3578 setup_picture((char*)picture, bpp);
3579 /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
3580 bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
3581 bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3582 ok(bmptb != NULL, "Could not create a DIB section.\n");
3583 /*Write to this top to bottom bitmap.*/
3584 setup_picture((char*)picture, bpp);
3586 bi.bmiHeader.biWidth = 1;
3588 bi.bmiHeader.biHeight = 2;
3589 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3590 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3591 /*Check the first byte of the pixel.*/
3592 ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3593 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3594 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3595 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3596 /*Check second scanline.*/
3597 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3598 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3599 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3600 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3601 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3602 ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3603 /*Check both scanlines.*/
3604 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3605 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3606 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3607 ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3608 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3609 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3610 ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3611 ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3613 /*Make destination bitmap top-down.*/
3614 bi.bmiHeader.biHeight = -2;
3615 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3616 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3617 ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3618 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3619 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3620 ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3621 /*Check second scanline.*/
3622 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3623 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3624 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3625 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3626 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3627 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3628 /*Check both scanlines.*/
3629 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3630 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3631 ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3632 ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3633 statusCode = GetDIBits(hdc, bmpbt, 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, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3636 ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3638 DeleteObject(bmpbt);
3639 DeleteObject(bmptb);
3642 static void test_GetSetDIBits_rtl(void)
3645 HBITMAP bitmap, orig_bitmap;
3648 DWORD bits_1[8 * 8], bits_2[8 * 8];
3652 win_skip("Don't have SetLayout\n");
3656 hdc = GetDC( NULL );
3657 hdc_mem = CreateCompatibleDC( hdc );
3658 pSetLayout( hdc_mem, LAYOUT_LTR );
3660 bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
3661 orig_bitmap = SelectObject( hdc_mem, bitmap );
3662 SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
3663 SelectObject( hdc_mem, orig_bitmap );
3665 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3666 info.bmiHeader.biWidth = 8;
3667 info.bmiHeader.biHeight = 8;
3668 info.bmiHeader.biPlanes = 1;
3669 info.bmiHeader.biBitCount = 32;
3670 info.bmiHeader.biCompression = BI_RGB;
3672 /* First show that GetDIBits ignores the layout mode. */
3674 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3675 ok(ret == 8, "got %d\n", ret);
3676 ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
3678 pSetLayout( hdc_mem, LAYOUT_RTL );
3680 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3681 ok(ret == 8, "got %d\n", ret);
3683 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3685 /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
3686 followed by a GetDIBits and show that the bits remain unchanged. */
3688 pSetLayout( hdc_mem, LAYOUT_LTR );
3690 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3691 ok(ret == 8, "got %d\n", ret);
3692 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3693 ok(ret == 8, "got %d\n", ret);
3694 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3696 pSetLayout( hdc_mem, LAYOUT_RTL );
3698 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3699 ok(ret == 8, "got %d\n", ret);
3700 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3701 ok(ret == 8, "got %d\n", ret);
3702 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3704 DeleteObject( bitmap );
3705 DeleteDC( hdc_mem );
3706 ReleaseDC( NULL, hdc );
3709 static void test_GetDIBits_scanlines(void)
3713 HDC hdc = GetDC( NULL );
3715 DWORD data[128], inverted_bits[64];
3718 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
3720 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3721 info->bmiHeader.biWidth = 8;
3722 info->bmiHeader.biHeight = 8;
3723 info->bmiHeader.biPlanes = 1;
3724 info->bmiHeader.biBitCount = 32;
3725 info->bmiHeader.biCompression = BI_RGB;
3727 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3729 for (i = 0; i < 64; i++)
3732 inverted_bits[56 - (i & ~7) + (i & 7)] = i;
3737 memset( data, 0xaa, sizeof(data) );
3739 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3740 ok( ret == 8, "got %d\n", ret );
3741 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3742 memset( data, 0xaa, sizeof(data) );
3744 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3745 ok( ret == 5, "got %d\n", ret );
3746 ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
3747 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3748 memset( data, 0xaa, sizeof(data) );
3750 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3751 ok( ret == 7, "got %d\n", ret );
3752 ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
3753 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3754 memset( data, 0xaa, sizeof(data) );
3756 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3757 ok( ret == 1, "got %d\n", ret );
3758 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3759 memset( data, 0xaa, sizeof(data) );
3761 info->bmiHeader.biHeight = 16;
3762 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3763 ok( ret == 5, "got %d\n", ret );
3764 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3765 ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
3766 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3767 memset( data, 0xaa, sizeof(data) );
3769 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3770 ok( ret == 6, "got %d\n", ret );
3771 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3772 ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
3773 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3774 memset( data, 0xaa, sizeof(data) );
3776 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3777 ok( ret == 0, "got %d\n", ret );
3778 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3779 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3780 memset( data, 0xaa, sizeof(data) );
3782 info->bmiHeader.biHeight = 5;
3783 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3784 ok( ret == 2, "got %d\n", ret );
3785 ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
3786 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3787 memset( data, 0xaa, sizeof(data) );
3791 info->bmiHeader.biHeight = -8;
3792 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3793 ok( ret == 8, "got %d\n", ret );
3794 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3795 memset( data, 0xaa, sizeof(data) );
3797 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3798 ok( ret == 5, "got %d\n", ret );
3799 ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
3800 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3801 memset( data, 0xaa, sizeof(data) );
3803 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3804 ok( ret == 7, "got %d\n", ret );
3805 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3806 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3807 memset( data, 0xaa, sizeof(data) );
3809 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3810 ok( ret == 4, "got %d\n", ret );
3811 ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
3812 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3813 memset( data, 0xaa, sizeof(data) );
3815 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3816 ok( ret == 5, "got %d\n", ret );
3817 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3818 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3819 memset( data, 0xaa, sizeof(data) );
3821 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3822 ok( ret == 5, "got %d\n", ret );
3823 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3824 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3825 memset( data, 0xaa, sizeof(data) );
3827 info->bmiHeader.biHeight = -16;
3828 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3829 ok( ret == 8, "got %d\n", ret );
3830 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3831 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3832 memset( data, 0xaa, sizeof(data) );
3834 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3835 ok( ret == 5, "got %d\n", ret );
3836 ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
3837 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3838 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3839 memset( data, 0xaa, sizeof(data) );
3841 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3842 ok( ret == 8, "got %d\n", ret );
3843 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3844 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3845 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3846 memset( data, 0xaa, sizeof(data) );
3848 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3849 ok( ret == 8, "got %d\n", ret );
3850 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3851 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3852 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3853 memset( data, 0xaa, sizeof(data) );
3855 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3856 ok( ret == 7, "got %d\n", ret );
3857 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3858 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3859 memset( data, 0xaa, sizeof(data) );
3861 ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
3862 ok( ret == 1, "got %d\n", ret );
3863 for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3864 memset( data, 0xaa, sizeof(data) );
3866 info->bmiHeader.biHeight = -5;
3867 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3868 ok( ret == 2, "got %d\n", ret );
3869 ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
3870 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3871 memset( data, 0xaa, sizeof(data) );
3873 DeleteObject( dib );
3875 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3876 info->bmiHeader.biWidth = 8;
3877 info->bmiHeader.biHeight = -8;
3878 info->bmiHeader.biPlanes = 1;
3879 info->bmiHeader.biBitCount = 32;
3880 info->bmiHeader.biCompression = BI_RGB;
3882 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3884 for (i = 0; i < 64; i++) dib_bits[i] = i;
3888 info->bmiHeader.biHeight = -8;
3889 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3890 ok( ret == 8, "got %d\n", ret );
3891 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3892 memset( data, 0xaa, sizeof(data) );
3894 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3895 ok( ret == 5, "got %d\n", ret );
3896 ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
3897 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3898 memset( data, 0xaa, sizeof(data) );
3900 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3901 ok( ret == 7, "got %d\n", ret );
3902 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3903 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3904 memset( data, 0xaa, sizeof(data) );
3906 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3907 ok( ret == 4, "got %d\n", ret );
3908 ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
3909 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3910 memset( data, 0xaa, sizeof(data) );
3912 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3913 ok( ret == 5, "got %d\n", ret );
3914 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3915 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3916 memset( data, 0xaa, sizeof(data) );
3918 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3919 ok( ret == 5, "got %d\n", ret );
3920 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3921 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3922 memset( data, 0xaa, sizeof(data) );
3924 info->bmiHeader.biHeight = -16;
3925 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3926 ok( ret == 8, "got %d\n", ret );
3927 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3928 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3929 memset( data, 0xaa, sizeof(data) );
3931 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3932 ok( ret == 5, "got %d\n", ret );
3933 ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
3934 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3935 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3936 memset( data, 0xaa, sizeof(data) );
3938 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3939 ok( ret == 8, "got %d\n", ret );
3940 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3941 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3942 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3943 memset( data, 0xaa, sizeof(data) );
3945 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3946 ok( ret == 8, "got %d\n", ret );
3947 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3948 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3949 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3950 memset( data, 0xaa, sizeof(data) );
3952 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3953 ok( ret == 7, "got %d\n", ret );
3954 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3955 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3956 memset( data, 0xaa, sizeof(data) );
3958 info->bmiHeader.biHeight = -5;
3959 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3960 ok( ret == 2, "got %d\n", ret );
3961 ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
3962 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3963 memset( data, 0xaa, sizeof(data) );
3968 info->bmiHeader.biHeight = 8;
3970 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3971 ok( ret == 8, "got %d\n", ret );
3972 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3973 memset( data, 0xaa, sizeof(data) );
3975 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3976 ok( ret == 5, "got %d\n", ret );
3977 ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
3978 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3979 memset( data, 0xaa, sizeof(data) );
3981 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3982 ok( ret == 7, "got %d\n", ret );
3983 ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
3984 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3985 memset( data, 0xaa, sizeof(data) );
3987 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3988 ok( ret == 1, "got %d\n", ret );
3989 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3990 memset( data, 0xaa, sizeof(data) );
3992 info->bmiHeader.biHeight = 16;
3993 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3994 ok( ret == 5, "got %d\n", ret );
3995 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3996 ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
3997 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3998 memset( data, 0xaa, sizeof(data) );
4000 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
4001 ok( ret == 6, "got %d\n", ret );
4002 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4003 ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
4004 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4005 memset( data, 0xaa, sizeof(data) );
4007 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
4008 ok( ret == 0, "got %d\n", ret );
4009 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4010 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4011 memset( data, 0xaa, sizeof(data) );
4013 info->bmiHeader.biHeight = 5;
4014 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4015 ok( ret == 2, "got %d\n", ret );
4016 ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
4017 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4018 memset( data, 0xaa, sizeof(data) );
4020 DeleteObject( dib );
4022 ReleaseDC( NULL, hdc );
4023 HeapFree( GetProcessHeap(), 0, info );
4027 static void test_SetDIBits(void)
4031 HDC hdc = GetDC( NULL );
4032 DWORD data[128], inverted_data[128];
4036 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4038 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4039 info->bmiHeader.biWidth = 8;
4040 info->bmiHeader.biHeight = 8;
4041 info->bmiHeader.biPlanes = 1;
4042 info->bmiHeader.biBitCount = 32;
4043 info->bmiHeader.biCompression = BI_RGB;
4045 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4046 memset( dib_bits, 0xaa, 64 * 4 );
4048 for (i = 0; i < 128; i++)
4051 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4056 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4057 ok( ret == 8, "got %d\n", ret );
4058 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4059 memset( dib_bits, 0xaa, 64 * 4 );
4061 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4062 ok( ret == 5, "got %d\n", ret );
4063 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4064 ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
4065 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4066 memset( dib_bits, 0xaa, 64 * 4 );
4068 /* top of dst is aligned with startscans down for the top of the src.
4069 Then starting from the bottom of src, lines rows are copied across. */
4071 info->bmiHeader.biHeight = 16;
4072 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4073 ok( ret == 12, "got %d\n", ret );
4074 ok( !memcmp( dib_bits, data + 56, 40 * 4 ), "bits differ\n");
4075 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4076 memset( dib_bits, 0xaa, 64 * 4 );
4078 info->bmiHeader.biHeight = 5;
4079 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4080 ok( ret == 2, "got %d\n", ret );
4081 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4082 ok( !memcmp( dib_bits + 32, data, 16 * 4 ), "bits differ\n");
4083 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4084 memset( dib_bits, 0xaa, 64 * 4 );
4087 info->bmiHeader.biHeight = -8;
4088 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4089 ok( ret == 8, "got %d\n", ret );
4090 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4091 memset( dib_bits, 0xaa, 64 * 4 );
4093 /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
4094 we copy lines rows from the top of the src */
4096 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4097 ok( ret == 5, "got %d\n", ret );
4098 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4099 ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
4100 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4101 memset( dib_bits, 0xaa, 64 * 4 );
4103 info->bmiHeader.biHeight = -16;
4104 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4105 ok( ret == 12, "got %d\n", ret );
4106 ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
4107 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4108 memset( dib_bits, 0xaa, 64 * 4 );
4110 ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4111 ok( ret == 12, "got %d\n", ret );
4112 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4113 memset( dib_bits, 0xaa, 64 * 4 );
4115 ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4116 ok( ret == 12, "got %d\n", ret );
4117 ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
4118 memset( dib_bits, 0xaa, 64 * 4 );
4120 info->bmiHeader.biHeight = -5;
4121 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4122 ok( ret == 2, "got %d\n", ret );
4123 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4124 ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
4125 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4126 memset( dib_bits, 0xaa, 64 * 4 );
4128 DeleteObject( dib );
4130 info->bmiHeader.biHeight = -8;
4132 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4133 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4137 /* like the t-d -> b-u case. */
4139 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4140 ok( ret == 8, "got %d\n", ret );
4141 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4142 memset( dib_bits, 0xaa, 64 * 4 );
4144 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4145 ok( ret == 5, "got %d\n", ret );
4146 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4147 ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
4148 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4149 memset( dib_bits, 0xaa, 64 * 4 );
4151 info->bmiHeader.biHeight = -16;
4152 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4153 ok( ret == 12, "got %d\n", ret );
4154 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4155 ok( !memcmp( dib_bits + 24, data, 40 * 4 ), "bits differ\n");
4156 memset( dib_bits, 0xaa, 64 * 4 );
4158 info->bmiHeader.biHeight = -5;
4159 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4160 ok( ret == 2, "got %d\n", ret );
4161 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4162 ok( !memcmp( dib_bits + 16, data, 16 * 4 ), "bits differ\n");
4163 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4164 memset( dib_bits, 0xaa, 64 * 4 );
4167 /* like the b-u -> b-u case */
4169 info->bmiHeader.biHeight = 8;
4170 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4171 ok( ret == 8, "got %d\n", ret );
4172 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4173 memset( dib_bits, 0xaa, 64 * 4 );
4175 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4176 ok( ret == 5, "got %d\n", ret );
4177 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4178 ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
4179 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4180 memset( dib_bits, 0xaa, 64 * 4 );
4182 info->bmiHeader.biHeight = 16;
4183 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4184 ok( ret == 12, "got %d\n", ret );
4185 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4186 ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
4187 memset( dib_bits, 0xaa, 64 * 4 );
4189 info->bmiHeader.biHeight = 5;
4190 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4191 ok( ret == 2, "got %d\n", ret );
4192 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4193 ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
4194 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4195 memset( dib_bits, 0xaa, 64 * 4 );
4197 DeleteObject( dib );
4198 ReleaseDC( NULL, hdc );
4199 HeapFree( GetProcessHeap(), 0, info );
4202 static void test_SetDIBits_RLE4(void)
4206 HDC hdc = GetDC( NULL );
4207 BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00, /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
4208 0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
4209 0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00, /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
4210 0x00, 0x02, 0x01, 0x02, 0x05, 0x87, /* dx=1, dy=2, 8, 7, 8, 7, 8 */
4211 0x00, 0x01 }; /* <eod> */
4214 DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
4215 0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
4216 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4217 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4218 0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
4219 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4220 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4221 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4223 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4225 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4226 info->bmiHeader.biWidth = 8;
4227 info->bmiHeader.biHeight = 8;
4228 info->bmiHeader.biPlanes = 1;
4229 info->bmiHeader.biBitCount = 32;
4230 info->bmiHeader.biCompression = BI_RGB;
4232 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4233 memset( dib_bits, 0xaa, 64 * 4 );
4235 info->bmiHeader.biBitCount = 4;
4236 info->bmiHeader.biCompression = BI_RLE4;
4237 info->bmiHeader.biSizeImage = sizeof(rle4_data);
4239 for (i = 0; i < 16; i++)
4241 info->bmiColors[i].rgbRed = i;
4242 info->bmiColors[i].rgbGreen = i;
4243 info->bmiColors[i].rgbBlue = i;
4244 info->bmiColors[i].rgbReserved = 0;
4247 ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
4248 ok( ret == 8, "got %d\n", ret );
4249 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
4250 memset( dib_bits, 0xaa, 64 * 4 );
4252 DeleteObject( dib );
4253 ReleaseDC( NULL, hdc );
4254 HeapFree( GetProcessHeap(), 0, info );
4257 static void test_SetDIBits_RLE8(void)
4261 HDC hdc = GetDC( NULL );
4262 BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00, /* 2, 2, 2, f0, f0, f0, f0, <eol> */
4263 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4264 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4265 0x00, 0x01 }; /* <eod> */
4268 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4269 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4270 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4271 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4272 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4273 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4274 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4275 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4276 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4277 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4278 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4279 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4280 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4281 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4282 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4283 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4285 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4287 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4288 info->bmiHeader.biWidth = 8;
4289 info->bmiHeader.biHeight = 8;
4290 info->bmiHeader.biPlanes = 1;
4291 info->bmiHeader.biBitCount = 32;
4292 info->bmiHeader.biCompression = BI_RGB;
4294 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4295 memset( dib_bits, 0xaa, 64 * 4 );
4297 info->bmiHeader.biBitCount = 8;
4298 info->bmiHeader.biCompression = BI_RLE8;
4299 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4301 for (i = 0; i < 256; i++)
4303 info->bmiColors[i].rgbRed = i;
4304 info->bmiColors[i].rgbGreen = i;
4305 info->bmiColors[i].rgbBlue = i;
4306 info->bmiColors[i].rgbReserved = 0;
4309 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4310 ok( ret == 8, "got %d\n", ret );
4311 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4312 memset( dib_bits, 0xaa, 64 * 4 );
4314 /* startscan and lines are ignored, unless lines == 0 */
4315 ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4316 ok( ret == 8, "got %d\n", ret );
4317 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4318 memset( dib_bits, 0xaa, 64 * 4 );
4320 ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4321 ok( ret == 8, "got %d\n", ret );
4322 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4323 memset( dib_bits, 0xaa, 64 * 4 );
4325 ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4326 ok( ret == 0, "got %d\n", ret );
4327 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4328 memset( dib_bits, 0xaa, 64 * 4 );
4330 /* reduce width to 4, left-hand side of dst is touched. */
4331 info->bmiHeader.biWidth = 4;
4332 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4333 ok( ret == 8, "got %d\n", ret );
4334 for (i = 0; i < 64; i++)
4336 DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4337 ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4339 memset( dib_bits, 0xaa, 64 * 4 );
4341 /* Show that the top lines are aligned by adjusting the height of the src */
4343 /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4344 info->bmiHeader.biWidth = 8;
4345 info->bmiHeader.biHeight = 4;
4346 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4347 ok( ret == 4, "got %d\n", ret );
4348 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4349 ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4350 memset( dib_bits, 0xaa, 64 * 4 );
4352 /* increase the height to 9 -> everything moves down one row. */
4353 info->bmiHeader.biHeight = 9;
4354 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4355 ok( ret == 9, "got %d\n", ret );
4356 ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4357 for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4358 memset( dib_bits, 0xaa, 64 * 4 );
4360 /* top-down compressed dibs are invalid */
4361 info->bmiHeader.biHeight = -8;
4362 SetLastError( 0xdeadbeef );
4363 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4364 ok( ret == 0, "got %d\n", ret );
4365 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4366 DeleteObject( dib );
4370 info->bmiHeader.biHeight = -8;
4371 info->bmiHeader.biBitCount = 32;
4372 info->bmiHeader.biCompression = BI_RGB;
4373 info->bmiHeader.biSizeImage = 0;
4375 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4376 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4378 info->bmiHeader.biHeight = 8;
4379 info->bmiHeader.biBitCount = 8;
4380 info->bmiHeader.biCompression = BI_RLE8;
4381 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4383 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4384 ok( ret == 8, "got %d\n", ret );
4385 ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4386 memset( dib_bits, 0xaa, 64 * 4 );
4388 info->bmiHeader.biHeight = 4;
4389 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4390 ok( ret == 4, "got %d\n", ret );
4391 ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4392 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4393 memset( dib_bits, 0xaa, 64 * 4 );
4395 info->bmiHeader.biHeight = 9;
4396 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4397 ok( ret == 9, "got %d\n", ret );
4398 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4399 ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4400 memset( dib_bits, 0xaa, 64 * 4 );
4402 DeleteObject( dib );
4403 ReleaseDC( NULL, hdc );
4404 HeapFree( GetProcessHeap(), 0, info );
4407 static void test_SetDIBitsToDevice(void)
4411 HDC hdc = CreateCompatibleDC( 0 );
4412 DWORD data[128], inverted_data[128];
4416 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4418 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4419 info->bmiHeader.biWidth = 8;
4420 info->bmiHeader.biHeight = 8;
4421 info->bmiHeader.biPlanes = 1;
4422 info->bmiHeader.biBitCount = 32;
4423 info->bmiHeader.biCompression = BI_RGB;
4425 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4426 memset( dib_bits, 0xaa, 64 * 4 );
4427 SelectObject( hdc, dib );
4429 for (i = 0; i < 128; i++)
4432 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4437 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4438 ok( ret == 8, "got %d\n", ret );
4439 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4440 memset( dib_bits, 0xaa, 64 * 4 );
4442 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4443 ok( ret == 5, "got %d\n", ret );
4444 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4445 for (i = 8; i < 48; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4446 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4447 memset( dib_bits, 0xaa, 64 * 4 );
4449 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 3, 1, 5, data, info, DIB_RGB_COLORS );
4450 ok( ret == 5, "got %d\n", ret );
4451 for (i = 0; i < 24; i++) ok( dib_bits[i] == data[i + 16], "%d: got %08x\n", i, dib_bits[i] );
4452 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4453 memset( dib_bits, 0xaa, 64 * 4 );
4455 info->bmiHeader.biHeight = 16;
4456 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4457 ok( ret == 7, "got %d\n", ret );
4458 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4459 for (i = 8; i < 64; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4460 memset( dib_bits, 0xaa, 64 * 4 );
4462 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 8, 0, 6, 1, 12, data, info, DIB_RGB_COLORS );
4463 ok( ret == 12, "got %d\n", ret );
4464 for (i = 0; i < 40; i++) ok( dib_bits[i] == data[i + 56], "%d: got %08x\n", i, dib_bits[i] );
4465 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4466 memset( dib_bits, 0xaa, 64 * 4 );
4468 ret = SetDIBitsToDevice( hdc, 0, -4, 8, 8, 0, 3, 1, 12, data, info, DIB_RGB_COLORS );
4469 ok( ret == 10, "got %d\n", ret );
4470 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4471 for (i = 32; i < 64; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4472 memset( dib_bits, 0xaa, 64 * 4 );
4474 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, -3, 1, 12, data, info, DIB_RGB_COLORS );
4475 ok( ret == 4, "got %d\n", ret );
4476 for (i = 0; i < 32; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4477 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4478 memset( dib_bits, 0xaa, 64 * 4 );
4480 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 5, 0, -2, 1, 12, data, info, DIB_RGB_COLORS );
4481 ok( ret == 2, "got %d\n", ret );
4482 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4483 for (i = 32; i < 48; i++) ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4484 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4485 memset( dib_bits, 0xaa, 64 * 4 );
4487 info->bmiHeader.biHeight = 5;
4488 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 2, 2, data, info, DIB_RGB_COLORS );
4489 ok( ret == 2, "got %d\n", ret );
4490 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4491 for (i = 16; i < 32; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4492 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4493 memset( dib_bits, 0xaa, 64 * 4 );
4495 ret = SetDIBitsToDevice( hdc, 3, 3, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4496 ok( ret == 3, "got %d\n", ret );
4497 for (i = 0; i < 64; i++)
4498 if (i == 27 || i == 28 || i == 35 || i == 36)
4499 ok( dib_bits[i] == data[i - 18], "%d: got %08x\n", i, dib_bits[i] );
4501 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4502 memset( dib_bits, 0xaa, 64 * 4 );
4504 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4505 ok( ret == 5, "got %d\n", ret );
4506 for (i = 0; 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, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4510 ok( ret == 0, "got %d\n", ret );
4511 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4512 memset( dib_bits, 0xaa, 64 * 4 );
4514 SetMapMode( hdc, MM_ANISOTROPIC );
4515 SetWindowExtEx( hdc, 3, 3, NULL );
4516 ret = SetDIBitsToDevice( hdc, 2, 2, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4517 ok( ret == 3, "got %d\n", ret );
4518 for (i = 0; i < 64; i++)
4519 if (i == 41 || i == 42 || i == 49 || i == 50)
4520 ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4522 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4523 memset( dib_bits, 0xaa, 64 * 4 );
4525 SetWindowExtEx( hdc, -1, -1, NULL );
4526 ret = SetDIBitsToDevice( hdc, 2, 2, 4, 4, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4527 ok( ret == 4, "got %d\n", ret );
4528 for (i = 0; i < 64; i++)
4529 if (i == 48 || i == 49 || i == 56 || i == 57)
4530 ok( dib_bits[i] == data[i - 37], "%d: got %08x\n", i, dib_bits[i] );
4532 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4533 memset( dib_bits, 0xaa, 64 * 4 );
4534 SetMapMode( hdc, MM_TEXT );
4538 pSetLayout( hdc, LAYOUT_RTL );
4539 ret = SetDIBitsToDevice( hdc, 1, 2, 3, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4540 ok( ret == 3, "got %d\n", ret );
4541 for (i = 0; i < 64; i++)
4542 if (i == 36 || i == 37 || i == 38 || i == 44 || i == 45 || i == 46)
4543 ok( dib_bits[i] == data[i - 27], "%d: got %08x\n", i, dib_bits[i] );
4545 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4546 memset( dib_bits, 0xaa, 64 * 4 );
4547 pSetLayout( hdc, LAYOUT_LTR );
4551 info->bmiHeader.biHeight = -8;
4552 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4553 ok( ret == 8, "got %d\n", ret );
4554 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4555 memset( dib_bits, 0xaa, 64 * 4 );
4557 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4558 ok( ret == 5, "got %d\n", ret );
4559 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4560 for (i = 8; i < 48; i++) ok( dib_bits[i] == inverted_data[i + 80], "%d: got %08x\n", i, dib_bits[i] );
4561 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4562 memset( dib_bits, 0xaa, 64 * 4 );
4564 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 4, 1, 5, data, info, DIB_RGB_COLORS );
4565 ok( ret == 5, "got %d\n", ret );
4566 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4567 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4568 memset( dib_bits, 0xaa, 64 * 4 );
4570 info->bmiHeader.biHeight = -16;
4571 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4572 ok( ret == 12, "got %d\n", ret );
4573 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4574 for (i = 8; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4575 memset( dib_bits, 0xaa, 64 * 4 );
4577 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, 7, 1, 12, data, info, DIB_RGB_COLORS );
4578 ok( ret == 12, "got %d\n", ret );
4579 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4580 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4581 memset( dib_bits, 0xaa, 64 * 4 );
4583 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 4, 12, data, info, DIB_RGB_COLORS );
4584 ok( ret == 12, "got %d\n", ret );
4585 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4586 for (i = 32; i < 64; i++) ok( dib_bits[i] == inverted_data[i], "%d: got %08x\n", i, dib_bits[i] );
4587 memset( dib_bits, 0xaa, 64 * 4 );
4589 ret = SetDIBitsToDevice( hdc, 0, -3, 8, 8, 0, 2, 4, 12, data, info, DIB_RGB_COLORS );
4590 ok( ret == 12, "got %d\n", ret );
4591 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4592 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4593 memset( dib_bits, 0xaa, 64 * 4 );
4595 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, -2, 4, 12, data, info, DIB_RGB_COLORS );
4596 ok( ret == 12, "got %d\n", ret );
4597 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4598 for (i = 24; i < 40; i++) ok( dib_bits[i] == inverted_data[i + 8], "%d: got %08x\n", i, dib_bits[i] );
4599 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4600 memset( dib_bits, 0xaa, 64 * 4 );
4602 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 5, 12, data, info, DIB_RGB_COLORS );
4603 ok( ret == 12, "got %d\n", ret );
4604 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4605 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4606 memset( dib_bits, 0xaa, 64 * 4 );
4608 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4609 ok( ret == 12, "got %d\n", ret );
4610 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4611 memset( dib_bits, 0xaa, 64 * 4 );
4613 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -2, -4, 0, 12, data, info, DIB_RGB_COLORS );
4614 ok( ret == 12, "got %d\n", ret );
4615 for (i = 0; i < 64; i++)
4616 if (i == 31 || i == 39 || i == 47 || i == 55 || i == 63)
4617 ok( dib_bits[i] == inverted_data[i + 1], "%d: got %08x\n", i, dib_bits[i] );
4619 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4620 memset( dib_bits, 0xaa, 64 * 4 );
4622 info->bmiHeader.biHeight = -5;
4623 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4624 ok( ret == 2, "got %d\n", ret );
4625 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4626 for (i = 8; i < 24; i++) ok( dib_bits[i] == inverted_data[i + 104], "%d: got %08x\n", i, dib_bits[i] );
4627 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4628 memset( dib_bits, 0xaa, 64 * 4 );
4630 ret = SetDIBitsToDevice( hdc, 5, 4, 2, 2, 6, 3, 1, 5, data, info, DIB_RGB_COLORS );
4631 ok( ret == 5, "got %d\n", ret );
4632 for (i = 0; i < 64; i++)
4633 if (i == 21 || i == 22 || i == 29 || i == 30)
4634 ok( dib_bits[i] == inverted_data[i + 89], "%d: got %08x\n", i, dib_bits[i] );
4636 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4637 memset( dib_bits, 0xaa, 64 * 4 );
4639 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4640 ok( ret == 5, "got %d\n", ret );
4641 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4642 memset( dib_bits, 0xaa, 64 * 4 );
4644 info->bmiHeader.biHeight = -8;
4646 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4647 DeleteObject( SelectObject( hdc, dib ));
4648 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4652 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4653 ok( ret == 8, "got %d\n", ret );
4654 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4655 memset( dib_bits, 0xaa, 64 * 4 );
4657 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4658 ok( ret == 5, "got %d\n", ret );
4659 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4660 for (i = 16; i < 56; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4661 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4662 memset( dib_bits, 0xaa, 64 * 4 );
4664 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 3, 0, 2, 1, 5, data, info, DIB_RGB_COLORS );
4665 ok( ret == 5, "got %d\n", ret );
4666 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4667 for (i = 24; i < 48; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4668 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4669 memset( dib_bits, 0xaa, 64 * 4 );
4671 info->bmiHeader.biHeight = -16;
4672 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4673 ok( ret == 12, "got %d\n", ret );
4674 for (i = 0; i < 56; i++) ok( dib_bits[i] == data[i + 40], "%d: got %08x\n", i, dib_bits[i] );
4675 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4676 memset( dib_bits, 0xaa, 64 * 4 );
4678 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -1, -8, 0, 12, data, info, DIB_RGB_COLORS );
4679 ok( ret == 12, "got %d\n", ret );
4680 for (i = 0; i < 64; i++)
4681 if (i == 6 || i == 7)
4682 ok( dib_bits[i] == data[i + 82], "%d: got %08x\n", i, dib_bits[i] );
4684 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4685 memset( dib_bits, 0xaa, 64 * 4 );
4687 info->bmiHeader.biHeight = -5;
4688 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4689 ok( ret == 2, "got %d\n", ret );
4690 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4691 for (i = 40; i < 56; i++) ok( dib_bits[i] == data[i - 40], "%d: got %08x\n", i, dib_bits[i] );
4692 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4693 memset( dib_bits, 0xaa, 64 * 4 );
4695 ret = SetDIBitsToDevice( hdc, 7, 2, 8, 8, 1, 0, 0, 5, data, info, DIB_RGB_COLORS );
4696 ok( ret == 5, "got %d\n", ret );
4697 for (i = 0; i < 64; i++)
4698 if (i == 47 || i == 55 || i == 63)
4699 ok( dib_bits[i] == data[i - 46], "%d: got %08x\n", i, dib_bits[i] );
4701 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4702 memset( dib_bits, 0xaa, 64 * 4 );
4704 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4705 ok( ret == 5, "got %d\n", ret );
4706 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4707 memset( dib_bits, 0xaa, 64 * 4 );
4711 info->bmiHeader.biHeight = 8;
4712 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4713 ok( ret == 8, "got %d\n", ret );
4714 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4715 memset( dib_bits, 0xaa, 64 * 4 );
4717 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4718 ok( ret == 5, "got %d\n", ret );
4719 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4720 for (i = 16; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%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 info->bmiHeader.biHeight = 16;
4725 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4726 ok( ret == 7, "got %d\n", ret );
4727 for (i = 0; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4728 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4729 memset( dib_bits, 0xaa, 64 * 4 );
4731 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, 0, -4, 1, 12, data, info, DIB_RGB_COLORS );
4732 ok( ret == 3, "got %d\n", ret );
4733 for (i = 0; i < 64; i++)
4734 if ((i >= 36 && i <= 39) || (i >= 44 && i <= 47) || (i >= 52 && i <= 55))
4735 ok( dib_bits[i] == inverted_data[i + 68], "%d: got %08x\n", i, dib_bits[i] );
4737 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4738 memset( dib_bits, 0xaa, 64 * 4 );
4740 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, -30, -30, 1, 12, data, info, DIB_RGB_COLORS );
4741 ok( ret == 0, "got %d\n", ret );
4742 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4743 memset( dib_bits, 0xaa, 64 * 4 );
4745 ret = SetDIBitsToDevice( hdc, 5, -5, 8, 16, -2, -4, 4, 12, data, info, DIB_RGB_COLORS );
4746 ok( ret == 8, "got %d\n", ret );
4747 for (i = 0; i < 64; i++)
4748 if (i == 7 || i == 15 || i == 23)
4749 ok( dib_bits[i] == inverted_data[i + 97], "%d: got %08x\n", i, dib_bits[i] );
4751 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4752 memset( dib_bits, 0xaa, 64 * 4 );
4754 info->bmiHeader.biHeight = 5;
4755 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4756 ok( ret == 2, "got %d\n", ret );
4757 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4758 for (i = 40; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4759 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4760 memset( dib_bits, 0xaa, 64 * 4 );
4762 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4763 ok( ret == 5, "got %d\n", ret );
4764 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4765 memset( dib_bits, 0xaa, 64 * 4 );
4768 DeleteObject( dib );
4769 HeapFree( GetProcessHeap(), 0, info );
4772 static void test_SetDIBitsToDevice_RLE8(void)
4776 HDC hdc = CreateCompatibleDC( 0 );
4777 BYTE rle8_data[20] = { 0x04, 0x02, 0x03, 0xf0, 0x00, 0x00, /* 2, 2, 2, 2, f0, f0, f0, <eol> */
4778 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4779 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4780 0x00, 0x01 }; /* <eod> */
4783 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4784 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4785 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4786 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4787 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4788 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4789 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4790 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4791 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4792 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4793 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4794 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4795 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4796 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4797 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4798 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4800 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4802 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4803 info->bmiHeader.biWidth = 8;
4804 info->bmiHeader.biHeight = 8;
4805 info->bmiHeader.biPlanes = 1;
4806 info->bmiHeader.biBitCount = 32;
4807 info->bmiHeader.biCompression = BI_RGB;
4809 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4810 memset( dib_bits, 0xaa, 64 * 4 );
4811 SelectObject( hdc, dib );
4813 info->bmiHeader.biBitCount = 8;
4814 info->bmiHeader.biCompression = BI_RLE8;
4815 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4817 for (i = 0; i < 256; i++)
4819 info->bmiColors[i].rgbRed = i;
4820 info->bmiColors[i].rgbGreen = i;
4821 info->bmiColors[i].rgbBlue = i;
4822 info->bmiColors[i].rgbReserved = 0;
4825 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4826 ok( ret == 8, "got %d\n", ret );
4827 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4828 memset( dib_bits, 0xaa, 64 * 4 );
4830 /* startscan and lines are ignored, unless lines == 0 */
4831 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4832 ok( ret == 8, "got %d\n", ret );
4833 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4834 memset( dib_bits, 0xaa, 64 * 4 );
4836 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4837 ok( ret == 8, "got %d\n", ret );
4838 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4839 memset( dib_bits, 0xaa, 64 * 4 );
4841 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4842 ok( ret == 0, "got %d\n", ret );
4843 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4844 memset( dib_bits, 0xaa, 64 * 4 );
4846 info->bmiHeader.biWidth = 2;
4847 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4848 ok( ret == 8, "got %d\n", ret );
4849 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4850 memset( dib_bits, 0xaa, 64 * 4 );
4852 info->bmiHeader.biWidth = 8;
4853 info->bmiHeader.biHeight = 2;
4854 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4855 ok( ret == 2, "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 info->bmiHeader.biHeight = 9;
4860 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4861 ok( ret == 9, "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, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4866 ok( ret == 9, "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 info->bmiHeader.biHeight = 8;
4871 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 9, rle8_data, info, DIB_RGB_COLORS );
4872 ok( ret == 8, "got %d\n", ret );
4873 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4874 memset( dib_bits, 0xaa, 64 * 4 );
4876 ret = SetDIBitsToDevice( hdc, 0, 3, 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 < 40; i++) ok( dib_bits[i] == bottom_up[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4879 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4880 memset( dib_bits, 0xaa, 64 * 4 );
4882 ret = SetDIBitsToDevice( hdc, 0, 3, 4, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4883 ok( ret == 8, "got %d\n", ret );
4884 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4885 for (i = 8; i < 40; i++)
4886 if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4887 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4888 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4889 memset( dib_bits, 0xaa, 64 * 4 );
4891 ret = SetDIBitsToDevice( hdc, 3, 3, 8, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4892 ok( ret == 8, "got %d\n", ret );
4893 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4894 for (i = 8; i < 40; i++)
4895 if ((i & 7) < 3) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4896 else ok( dib_bits[i] == bottom_up[i - 11], "%d: got %08x\n", i, dib_bits[i] );
4897 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4898 memset( dib_bits, 0xaa, 64 * 4 );
4900 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 4, 2, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4901 ok( ret == 8, "got %d\n", ret );
4902 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4903 for (i = 8; i < 40; i++)
4904 if ((i & 7) < 2) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4905 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4906 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4907 memset( dib_bits, 0xaa, 64 * 4 );
4909 info->bmiHeader.biWidth = 37;
4910 info->bmiHeader.biHeight = 37;
4911 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
4912 ok( ret == 37, "got %d\n", ret );
4913 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4914 for (i = 24; i < 64; i++)
4915 if (i == 52) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
4916 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4917 else ok( dib_bits[i] == bottom_up[i - 20], "%d: got %08x\n", i, dib_bits[i] );
4918 memset( dib_bits, 0xaa, 64 * 4 );
4920 /* top-down compressed dibs are invalid */
4921 info->bmiHeader.biWidth = 8;
4922 info->bmiHeader.biHeight = -8;
4923 SetLastError( 0xdeadbeef );
4924 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4925 ok( ret == 0, "got %d\n", ret );
4926 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4930 info->bmiHeader.biHeight = -8;
4931 info->bmiHeader.biBitCount = 32;
4932 info->bmiHeader.biCompression = BI_RGB;
4933 info->bmiHeader.biSizeImage = 0;
4935 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4936 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4937 DeleteObject( SelectObject( hdc, dib ));
4939 info->bmiHeader.biHeight = 8;
4940 info->bmiHeader.biBitCount = 8;
4941 info->bmiHeader.biCompression = BI_RLE8;
4942 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4944 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4945 ok( ret == 8, "got %d\n", ret );
4946 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4947 memset( dib_bits, 0xaa, 64 * 4 );
4949 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4950 ok( ret == 8, "got %d\n", ret );
4951 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4952 memset( dib_bits, 0xaa, 64 * 4 );
4954 info->bmiHeader.biHeight = 4;
4955 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4956 ok( ret == 4, "got %d\n", ret );
4957 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4958 memset( dib_bits, 0xaa, 64 * 4 );
4960 info->bmiHeader.biHeight = 9;
4961 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4962 ok( ret == 9, "got %d\n", ret );
4963 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4964 memset( dib_bits, 0xaa, 64 * 4 );
4966 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4967 ok( ret == 9, "got %d\n", ret );
4968 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4969 memset( dib_bits, 0xaa, 64 * 4 );
4971 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 6, 2, 2, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4972 ok( ret == 9, "got %d\n", ret );
4973 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4974 for (i = 24; i < 64; i++) ok( dib_bits[i] == top_down[i - 24], "%d: got %08x\n", i, dib_bits[i] );
4975 memset( dib_bits, 0xaa, 64 * 4 );
4977 info->bmiHeader.biWidth = 37;
4978 info->bmiHeader.biHeight = 37;
4979 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
4980 ok( ret == 37, "got %d\n", ret );
4981 for (i = 0; i < 40; i++)
4982 if (i == 12) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
4983 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4984 else ok( dib_bits[i] == top_down[i + 28], "%d: got %08x\n", i, dib_bits[i] );
4985 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4986 memset( dib_bits, 0xaa, 64 * 4 );
4989 DeleteObject( dib );
4990 HeapFree( GetProcessHeap(), 0, info );
4997 hdll = GetModuleHandle("gdi32.dll");
4998 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
4999 pGdiGradientFill = (void*)GetProcAddress(hdll, "GdiGradientFill");
5000 pSetLayout = (void*)GetProcAddress(hdll, "SetLayout");
5002 test_createdibitmap();
5005 test_mono_dibsection();
5008 test_GetDIBits_selected_DIB(1);
5009 test_GetDIBits_selected_DIB(4);
5010 test_GetDIBits_selected_DIB(8);
5011 test_GetDIBits_selected_DDB(TRUE);
5012 test_GetDIBits_selected_DDB(FALSE);
5014 test_GetDIBits_BI_BITFIELDS();
5015 test_select_object();
5016 test_CreateBitmap();
5019 test_StretchDIBits();
5020 test_GdiAlphaBlend();
5021 test_GdiGradientFill();
5022 test_32bit_bitmap_blt();
5023 test_bitmapinfoheadersize();
5026 test_GetDIBits_top_down(16);
5027 test_GetDIBits_top_down(24);
5028 test_GetDIBits_top_down(32);
5029 test_GetSetDIBits_rtl();
5030 test_GetDIBits_scanlines();
5032 test_SetDIBits_RLE4();
5033 test_SetDIBits_RLE8();
5034 test_SetDIBitsToDevice();
5035 test_SetDIBitsToDevice_RLE8();