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 static void _test_color( int line, HDC hdc, COLORREF color, COLORREF exp )
345 c = SetPixel(hdc, 0, 0, color);
346 ok_(__FILE__, line)(c == exp, "SetPixel failed: got 0x%06x expected 0x%06x\n", c, exp);
347 c = GetPixel(hdc, 0, 0);
348 ok_(__FILE__, line)(c == exp, "GetPixel failed: got 0x%06x expected 0x%06x\n", c, exp);
349 c = GetNearestColor(hdc, color);
350 ok_(__FILE__, line)(c == exp, "GetNearestColor failed: got 0x%06x expected 0x%06x\n", c, exp);
352 #define test_color(hdc, color, exp) _test_color( __LINE__, hdc, color, exp )
355 static void test_dib_bits_access( HBITMAP hdib, void *bits )
357 MEMORY_BASIC_INFORMATION info;
358 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
360 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
362 char filename[MAX_PATH];
367 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
368 "VirtualQuery failed\n");
369 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
370 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
371 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
372 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
373 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
374 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
376 memset( pbmi, 0, sizeof(bmibuf) );
377 memset( data, 0xcc, sizeof(data) );
378 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
379 pbmi->bmiHeader.biHeight = 16;
380 pbmi->bmiHeader.biWidth = 16;
381 pbmi->bmiHeader.biBitCount = 32;
382 pbmi->bmiHeader.biPlanes = 1;
383 pbmi->bmiHeader.biCompression = BI_RGB;
387 ret = SetDIBits( hdc, hdib, 0, 16, data, pbmi, DIB_RGB_COLORS );
388 ok(ret == 16, "SetDIBits failed: expected 16 got %d\n", ret);
392 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
393 "VirtualQuery failed\n");
394 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
395 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
396 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
397 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
398 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
399 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
401 /* try writing protected bits to a file */
403 GetTempFileNameA( ".", "dib", 0, filename );
404 file = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
405 CREATE_ALWAYS, 0, 0 );
406 ok( file != INVALID_HANDLE_VALUE, "failed to open %s error %u\n", filename, GetLastError() );
407 ret = WriteFile( file, bits, 8192, &written, NULL );
408 ok( ret, "WriteFile failed error %u\n", GetLastError() );
409 if (ret) ok( written == 8192, "only wrote %u bytes\n", written );
411 DeleteFileA( filename );
414 static void test_dibsections(void)
416 HDC hdc, hdcmem, hdcmem2;
417 HBITMAP hdib, oldbm, hdib2, oldbm2;
418 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
419 char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
420 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
421 BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
422 RGBQUAD *colors = pbmi->bmiColors;
423 RGBTRIPLE *ccolors = pbci->bmciColors;
429 char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
430 LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
431 PALETTEENTRY *palent = plogpal->palPalEntry;
434 HPALETTE hpal, oldpal;
438 MEMORY_BASIC_INFORMATION info;
442 memset(pbmi, 0, sizeof(bmibuf));
443 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
444 pbmi->bmiHeader.biHeight = 100;
445 pbmi->bmiHeader.biWidth = 512;
446 pbmi->bmiHeader.biBitCount = 24;
447 pbmi->bmiHeader.biPlanes = 1;
448 pbmi->bmiHeader.biCompression = BI_RGB;
450 SetLastError(0xdeadbeef);
452 /* invalid pointer for BITMAPINFO
453 (*bits should be NULL on error) */
454 bits = (BYTE*)0xdeadbeef;
455 hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
456 ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n");
458 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
459 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
460 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
461 ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
463 /* test the DIB memory */
464 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
465 "VirtualQuery failed\n");
466 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
467 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
468 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
469 ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
470 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
471 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
472 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
474 test_dib_bits_access( hdib, bits );
476 test_dib_info(hdib, bits, &pbmi->bmiHeader);
479 /* Test a top-down DIB. */
480 pbmi->bmiHeader.biHeight = -100;
481 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
482 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
483 test_dib_info(hdib, bits, &pbmi->bmiHeader);
486 pbmi->bmiHeader.biHeight = 100;
487 pbmi->bmiHeader.biBitCount = 8;
488 pbmi->bmiHeader.biCompression = BI_RLE8;
489 SetLastError(0xdeadbeef);
490 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
491 ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
492 ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
494 pbmi->bmiHeader.biBitCount = 16;
495 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
496 ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
497 ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
498 ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
499 SetLastError(0xdeadbeef);
500 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
501 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
503 /* test the DIB memory */
504 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
505 "VirtualQuery failed\n");
506 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
507 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
508 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
509 ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
510 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
511 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
512 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
514 test_dib_info(hdib, bits, &pbmi->bmiHeader);
517 memset(pbmi, 0, sizeof(bmibuf));
518 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
519 pbmi->bmiHeader.biHeight = 16;
520 pbmi->bmiHeader.biWidth = 16;
521 pbmi->bmiHeader.biBitCount = 1;
522 pbmi->bmiHeader.biPlanes = 1;
523 pbmi->bmiHeader.biCompression = BI_RGB;
524 colors[0].rgbRed = 0xff;
525 colors[0].rgbGreen = 0;
526 colors[0].rgbBlue = 0;
527 colors[1].rgbRed = 0;
528 colors[1].rgbGreen = 0;
529 colors[1].rgbBlue = 0xff;
531 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
532 ok(hdib != NULL, "CreateDIBSection failed\n");
533 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
534 ok(dibsec.dsBmih.biClrUsed == 2,
535 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
537 /* Test if the old BITMAPCOREINFO structure is supported */
539 pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
540 pbci->bmciHeader.bcBitCount = 0;
542 ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
543 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
544 ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
545 && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
546 "GetDIBits didn't fill in the BITMAPCOREHEADER structure properly\n");
548 ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
549 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
550 ok((ccolors[0].rgbtRed == 0xff) && (ccolors[0].rgbtGreen == 0) &&
551 (ccolors[0].rgbtBlue == 0) && (ccolors[1].rgbtRed == 0) &&
552 (ccolors[1].rgbtGreen == 0) && (ccolors[1].rgbtBlue == 0xff),
553 "The color table has not been translated to the old BITMAPCOREINFO format\n");
555 hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
556 ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
558 ZeroMemory(ccolors, 256 * sizeof(RGBTRIPLE));
559 ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
560 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
561 ok((ccolors[0].rgbtRed == 0xff) && (ccolors[0].rgbtGreen == 0) &&
562 (ccolors[0].rgbtBlue == 0) && (ccolors[1].rgbtRed == 0) &&
563 (ccolors[1].rgbtGreen == 0) && (ccolors[1].rgbtBlue == 0xff),
564 "The color table has not been translated to the old BITMAPCOREINFO format\n");
566 DeleteObject(hcoredib);
568 hdcmem = CreateCompatibleDC(hdc);
569 oldbm = SelectObject(hdcmem, hdib);
571 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
572 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
573 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
574 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
575 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
576 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
578 c0 = RGB(colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue);
579 c1 = RGB(colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue);
581 test_color(hdcmem, DIBINDEX(0), c0);
582 test_color(hdcmem, DIBINDEX(1), c1);
583 test_color(hdcmem, DIBINDEX(2), c0);
584 test_color(hdcmem, PALETTEINDEX(0), c0);
585 test_color(hdcmem, PALETTEINDEX(1), c0);
586 test_color(hdcmem, PALETTEINDEX(2), c0);
587 test_color(hdcmem, PALETTERGB(colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue), c0);
588 test_color(hdcmem, PALETTERGB(colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue), c1);
589 test_color(hdcmem, PALETTERGB(0, 0, 0), c0);
590 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0);
591 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1);
593 SelectObject(hdcmem, oldbm);
596 colors[0].rgbRed = 0xff;
597 colors[0].rgbGreen = 0xff;
598 colors[0].rgbBlue = 0xff;
599 colors[1].rgbRed = 0;
600 colors[1].rgbGreen = 0;
601 colors[1].rgbBlue = 0;
603 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
604 ok(hdib != NULL, "CreateDIBSection failed\n");
606 test_dib_info(hdib, bits, &pbmi->bmiHeader);
608 oldbm = SelectObject(hdcmem, hdib);
610 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
611 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
612 ok(!memcmp(rgb, colors, 2 * sizeof(RGBQUAD)),
613 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
614 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
615 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
617 SelectObject(hdcmem, oldbm);
618 test_dib_info(hdib, bits, &pbmi->bmiHeader);
621 pbmi->bmiHeader.biBitCount = 4;
622 for (i = 0; i < 16; i++) {
623 colors[i].rgbRed = i;
624 colors[i].rgbGreen = 16-i;
625 colors[i].rgbBlue = 0;
627 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
628 ok(hdib != NULL, "CreateDIBSection failed\n");
629 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
630 ok(dibsec.dsBmih.biClrUsed == 16,
631 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
632 test_dib_info(hdib, bits, &pbmi->bmiHeader);
635 pbmi->bmiHeader.biBitCount = 8;
637 for (i = 0; i < 128; i++) {
638 colors[i].rgbRed = 255 - i * 2;
639 colors[i].rgbGreen = i * 2;
640 colors[i].rgbBlue = 0;
641 colors[255 - i].rgbRed = 0;
642 colors[255 - i].rgbGreen = i * 2;
643 colors[255 - i].rgbBlue = 255 - i * 2;
645 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
646 ok(hdib != NULL, "CreateDIBSection failed\n");
647 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
648 ok(dibsec.dsBmih.biClrUsed == 256,
649 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
651 oldbm = SelectObject(hdcmem, hdib);
653 for (i = 0; i < 256; i++) {
654 test_color(hdcmem, DIBINDEX(i), RGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue));
655 test_color(hdcmem, PALETTERGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue),
656 RGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue));
659 SelectObject(hdcmem, oldbm);
660 test_dib_info(hdib, bits, &pbmi->bmiHeader);
663 pbmi->bmiHeader.biBitCount = 1;
665 /* Now create a palette and a palette indexed dib section */
666 memset(plogpal, 0, sizeof(logpalbuf));
667 plogpal->palVersion = 0x300;
668 plogpal->palNumEntries = 2;
669 palent[0].peRed = 0xff;
670 palent[0].peBlue = 0xff;
671 palent[1].peGreen = 0xff;
673 index = (WORD*)pbmi->bmiColors;
676 hpal = CreatePalette(plogpal);
677 ok(hpal != NULL, "CreatePalette failed\n");
678 oldpal = SelectPalette(hdc, hpal, TRUE);
679 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
680 ok(hdib != NULL, "CreateDIBSection failed\n");
681 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
682 ok(dibsec.dsBmih.biClrUsed == 2, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
684 /* The colour table has already been grabbed from the dc, so we select back the
687 SelectPalette(hdc, oldpal, TRUE);
688 oldbm = SelectObject(hdcmem, hdib);
689 oldpal = SelectPalette(hdcmem, hpal, TRUE);
691 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
692 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
693 ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
694 rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
695 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
696 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
697 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
699 c0 = RGB(palent[0].peRed, palent[0].peGreen, palent[0].peBlue);
700 c1 = RGB(palent[1].peRed, palent[1].peGreen, palent[1].peBlue);
702 test_color(hdcmem, DIBINDEX(0), c0);
703 test_color(hdcmem, DIBINDEX(1), c1);
704 test_color(hdcmem, DIBINDEX(2), c0);
705 test_color(hdcmem, PALETTEINDEX(0), c0);
706 test_color(hdcmem, PALETTEINDEX(1), c1);
707 test_color(hdcmem, PALETTEINDEX(2), c0);
708 test_color(hdcmem, PALETTERGB(palent[0].peRed, palent[0].peGreen, palent[0].peBlue), c0);
709 test_color(hdcmem, PALETTERGB(palent[1].peRed, palent[1].peGreen, palent[1].peBlue), c1);
710 test_color(hdcmem, PALETTERGB(0, 0, 0), c1);
711 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0);
712 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0);
713 test_color(hdcmem, PALETTERGB(0, 1, 0), c1);
714 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1);
715 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0);
717 /* Bottom and 2nd row from top green, everything else magenta */
718 bits[0] = bits[1] = 0xff;
719 bits[13 * 4] = bits[13*4 + 1] = 0xff;
721 test_dib_info(hdib, bits, &pbmi->bmiHeader);
723 pbmi->bmiHeader.biBitCount = 32;
725 hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
726 ok(hdib2 != NULL, "CreateDIBSection failed\n");
727 hdcmem2 = CreateCompatibleDC(hdc);
728 oldbm2 = SelectObject(hdcmem2, hdib2);
730 BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
732 ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
733 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
735 SelectObject(hdcmem2, oldbm2);
736 test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
739 SelectObject(hdcmem, oldbm);
740 SelectPalette(hdcmem, oldpal, TRUE);
745 pbmi->bmiHeader.biBitCount = 8;
747 memset(plogpal, 0, sizeof(logpalbuf));
748 plogpal->palVersion = 0x300;
749 plogpal->palNumEntries = 256;
751 for (i = 0; i < 128; i++) {
752 palent[i].peRed = 255 - i * 2;
753 palent[i].peBlue = i * 2;
754 palent[i].peGreen = 0;
755 palent[255 - i].peRed = 0;
756 palent[255 - i].peGreen = i * 2;
757 palent[255 - i].peBlue = 255 - i * 2;
760 index = (WORD*)pbmi->bmiColors;
761 for (i = 0; i < 256; i++) {
765 hpal = CreatePalette(plogpal);
766 ok(hpal != NULL, "CreatePalette failed\n");
767 oldpal = SelectPalette(hdc, hpal, TRUE);
768 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
769 ok(hdib != NULL, "CreateDIBSection failed\n");
770 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
771 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
773 test_dib_info(hdib, bits, &pbmi->bmiHeader);
775 SelectPalette(hdc, oldpal, TRUE);
776 oldbm = SelectObject(hdcmem, hdib);
777 oldpal = SelectPalette(hdcmem, hpal, TRUE);
779 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
780 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
781 for (i = 0; i < 256; i++) {
782 ok(rgb[i].rgbRed == palent[i].peRed &&
783 rgb[i].rgbBlue == palent[i].peBlue &&
784 rgb[i].rgbGreen == palent[i].peGreen,
785 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
786 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
789 for (i = 0; i < 256; i++) {
790 test_color(hdcmem, DIBINDEX(i), RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
791 test_color(hdcmem, PALETTEINDEX(i), RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
792 test_color(hdcmem, PALETTERGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue),
793 RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
796 SelectPalette(hdcmem, oldpal, TRUE);
797 SelectObject(hdcmem, oldbm);
801 plogpal->palNumEntries = 37;
802 hpal = CreatePalette(plogpal);
803 ok(hpal != NULL, "CreatePalette failed\n");
804 oldpal = SelectPalette(hdc, hpal, TRUE);
805 pbmi->bmiHeader.biClrUsed = 142;
806 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
807 ok(hdib != NULL, "CreateDIBSection failed\n");
808 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
809 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
811 test_dib_info(hdib, bits, &pbmi->bmiHeader);
813 SelectPalette(hdc, oldpal, TRUE);
814 oldbm = SelectObject(hdcmem, hdib);
816 memset( rgb, 0xcc, sizeof(rgb) );
817 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
818 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
819 for (i = 0; i < 256; i++)
821 if (i < pbmi->bmiHeader.biClrUsed)
823 ok(rgb[i].rgbRed == palent[i % 37].peRed &&
824 rgb[i].rgbBlue == palent[i % 37].peBlue &&
825 rgb[i].rgbGreen == palent[i % 37].peGreen,
826 "GetDIBColorTable returns table %d: r %02x g %02x b %02x res%02x\n",
827 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
828 test_color(hdcmem, DIBINDEX(i),
829 RGB(palent[i % 37].peRed, palent[i % 37].peGreen, palent[i % 37].peBlue));
833 ok(rgb[i].rgbRed == 0 && rgb[i].rgbBlue == 0 && rgb[i].rgbGreen == 0,
834 "GetDIBColorTable returns table %d: r %02x g %02x b %02x res%02x\n",
835 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
836 test_color(hdcmem, DIBINDEX(i), 0 );
839 pbmi->bmiHeader.biClrUsed = 173;
840 memset( pbmi->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
841 GetDIBits( hdc, hdib, 0, 1, bits, pbmi, DIB_RGB_COLORS );
842 ok( pbmi->bmiHeader.biClrUsed == 0, "wrong colors %u\n", pbmi->bmiHeader.biClrUsed );
843 for (i = 0; i < 256; i++)
846 ok(colors[i].rgbRed == palent[i % 37].peRed &&
847 colors[i].rgbBlue == palent[i % 37].peBlue &&
848 colors[i].rgbGreen == palent[i % 37].peGreen,
849 "GetDIBits returns table %d: r %02x g %02x b %02x res%02x\n",
850 i, colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
852 ok(colors[i].rgbRed == 0 && colors[i].rgbBlue == 0 && colors[i].rgbGreen == 0,
853 "GetDIBits returns table %d: r %02x g %02x b %02x res%02x\n",
854 i, colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
857 SelectObject(hdcmem, oldbm);
861 /* ClrUsed ignored on > 8bpp */
862 pbmi->bmiHeader.biBitCount = 16;
863 pbmi->bmiHeader.biClrUsed = 37;
864 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
865 ok(hdib != NULL, "CreateDIBSection failed\n");
866 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
867 ok(dibsec.dsBmih.biClrUsed == 0, "created DIBSection: wrong biClrUsed field: %u\n", dibsec.dsBmih.biClrUsed);
868 oldbm = SelectObject(hdcmem, hdib);
869 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
870 ok(ret == 0, "GetDIBColorTable returned %d\n", ret);
871 SelectObject(hdcmem, oldbm);
879 static void test_dib_formats(void)
884 int planes, bpp, compr, format;
888 BOOL format_ok, expect_ok;
890 bi = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
892 memdc = CreateCompatibleDC( 0 );
893 hbmp = CreateCompatibleBitmap( hdc, 10, 10 );
895 memset( data, 0xaa, sizeof(data) );
897 for (bpp = 0; bpp <= 64; bpp++)
899 for (planes = 0; planes <= 64; planes++)
901 for (compr = 0; compr < 8; compr++)
903 for (format = DIB_RGB_COLORS; format <= DIB_PAL_COLORS; format++)
910 case 24: expect_ok = (compr == BI_RGB); break;
912 case 32: expect_ok = (compr == BI_RGB || compr == BI_BITFIELDS); break;
913 default: expect_ok = FALSE; break;
916 memset( bi, 0, sizeof(bi->bmiHeader) );
917 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
918 bi->bmiHeader.biWidth = 2;
919 bi->bmiHeader.biHeight = 2;
920 bi->bmiHeader.biPlanes = planes;
921 bi->bmiHeader.biBitCount = bpp;
922 bi->bmiHeader.biCompression = compr;
923 bi->bmiHeader.biSizeImage = 0;
924 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
925 ret = GetDIBits(hdc, hbmp, 0, 0, data, bi, format);
926 if (expect_ok || (!bpp && compr != BI_JPEG && compr != BI_PNG) ||
927 (bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8))
928 ok( ret, "GetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
930 ok( !ret || broken(!bpp && (compr == BI_JPEG || compr == BI_PNG)), /* nt4 */
931 "GetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
933 /* all functions check planes except GetDIBits with 0 lines */
934 format_ok = expect_ok;
935 if (!planes) expect_ok = FALSE;
936 memset( bi, 0, sizeof(bi->bmiHeader) );
937 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
938 bi->bmiHeader.biWidth = 2;
939 bi->bmiHeader.biHeight = 2;
940 bi->bmiHeader.biPlanes = planes;
941 bi->bmiHeader.biBitCount = bpp;
942 bi->bmiHeader.biCompression = compr;
943 bi->bmiHeader.biSizeImage = 0;
944 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
946 hdib = CreateDIBSection(hdc, bi, format, &bits, NULL, 0);
947 if (expect_ok && (planes == 1 || planes * bpp <= 16) &&
948 (compr != BI_BITFIELDS || format != DIB_PAL_COLORS))
949 ok( hdib != NULL, "CreateDIBSection failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
951 ok( hdib == NULL, "CreateDIBSection succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
952 if (hdib) DeleteObject( hdib );
954 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, data, bi, format );
955 /* no sanity checks in CreateDIBitmap except compression */
956 if (compr == BI_JPEG || compr == BI_PNG)
957 ok( hdib == NULL || broken(hdib != NULL), /* nt4 */
958 "CreateDIBitmap succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
960 ok( hdib != NULL, "CreateDIBitmap failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
961 if (hdib) DeleteObject( hdib );
963 /* RLE needs a size */
964 bi->bmiHeader.biSizeImage = 0;
965 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, format);
967 ok( ret, "SetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
970 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
971 "SetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
972 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, format );
974 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
977 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
978 "SetDIBitsToDevice succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
979 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, format, SRCCOPY );
981 ok( ret, "StretchDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
984 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
985 "StretchDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
987 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, format);
989 ok( ret, "GetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
991 ok( !ret, "GetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
992 ok( bi->bmiHeader.biBitCount == bpp, "GetDIBits modified bpp %u/%u\n",
993 bpp, bi->bmiHeader.biBitCount );
995 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
996 bi->bmiHeader.biWidth = 2;
997 bi->bmiHeader.biHeight = 2;
998 bi->bmiHeader.biPlanes = planes;
999 bi->bmiHeader.biBitCount = bpp;
1000 bi->bmiHeader.biCompression = compr;
1001 bi->bmiHeader.biSizeImage = 1;
1002 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
1003 /* RLE allowed with valid biSizeImage */
1004 if ((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)) expect_ok = TRUE;
1006 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, format);
1008 ok( ret, "SetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1010 ok( !ret, "SetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1011 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, format );
1013 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1015 ok( !ret, "SetDIBitsToDevice succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1016 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, format, SRCCOPY );
1018 ok( ret, "StretchDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1020 ok( !ret, "StretchDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1022 bi->bmiHeader.biSizeImage = 0;
1023 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, format);
1024 if (expect_ok || !bpp)
1025 ok( ret, "GetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1027 ok( !ret || broken(format_ok && !planes), /* nt4 */
1028 "GetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1034 memset( bi, 0, sizeof(bi->bmiHeader) );
1035 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1036 bi->bmiHeader.biWidth = 2;
1037 bi->bmiHeader.biHeight = 2;
1038 bi->bmiHeader.biPlanes = 1;
1039 bi->bmiHeader.biBitCount = 16;
1040 bi->bmiHeader.biCompression = BI_BITFIELDS;
1041 bi->bmiHeader.biSizeImage = 0;
1042 *(DWORD *)&bi->bmiColors[0] = 0;
1043 *(DWORD *)&bi->bmiColors[1] = 0;
1044 *(DWORD *)&bi->bmiColors[2] = 0;
1046 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1047 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1048 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1049 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1050 /* other functions don't check */
1051 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1052 ok( hdib != NULL, "CreateDIBitmap failed with null bitfields\n" );
1053 DeleteObject( hdib );
1054 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1055 ok( ret, "SetDIBitsToDevice failed with null bitfields\n" );
1056 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1057 ok( ret, "StretchDIBits failed with null bitfields\n" );
1058 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1059 ok( ret, "GetDIBits failed with null bitfields\n" );
1060 bi->bmiHeader.biPlanes = 1;
1061 bi->bmiHeader.biBitCount = 16;
1062 bi->bmiHeader.biCompression = BI_BITFIELDS;
1063 bi->bmiHeader.biSizeImage = 0;
1064 *(DWORD *)&bi->bmiColors[0] = 0;
1065 *(DWORD *)&bi->bmiColors[1] = 0;
1066 *(DWORD *)&bi->bmiColors[2] = 0;
1067 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1068 ok( ret, "GetDIBits failed with null bitfields\n" );
1070 /* all fields must be non-zero */
1071 *(DWORD *)&bi->bmiColors[0] = 3;
1072 *(DWORD *)&bi->bmiColors[1] = 0;
1073 *(DWORD *)&bi->bmiColors[2] = 7;
1074 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1075 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1076 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1077 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1079 /* garbage is ok though */
1080 *(DWORD *)&bi->bmiColors[0] = 0x55;
1081 *(DWORD *)&bi->bmiColors[1] = 0x44;
1082 *(DWORD *)&bi->bmiColors[2] = 0x33;
1083 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1084 ok( hdib != NULL, "CreateDIBSection failed with bad bitfields\n" );
1085 if (hdib) DeleteObject( hdib );
1086 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1087 ok( ret, "SetDIBits failed with bad bitfields\n" );
1089 bi->bmiHeader.biWidth = -2;
1090 bi->bmiHeader.biHeight = 2;
1091 bi->bmiHeader.biBitCount = 32;
1092 bi->bmiHeader.biCompression = BI_RGB;
1093 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1094 ok( hdib == NULL, "CreateDIBSection succeeded with negative width\n" );
1095 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1096 ok( hdib == NULL, "CreateDIBitmap succeeded with negative width\n" );
1097 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1098 ok( !ret, "SetDIBits succeeded with negative width\n" );
1099 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1100 ok( !ret, "SetDIBitsToDevice succeeded with negative width\n" );
1101 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1102 ok( !ret, "StretchDIBits succeeded with negative width\n" );
1103 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1104 ok( !ret, "GetDIBits succeeded with negative width\n" );
1105 bi->bmiHeader.biWidth = -2;
1106 bi->bmiHeader.biHeight = 2;
1107 bi->bmiHeader.biBitCount = 32;
1108 bi->bmiHeader.biCompression = BI_RGB;
1109 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1110 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with negative width\n" );
1112 bi->bmiHeader.biWidth = 0;
1113 bi->bmiHeader.biHeight = 2;
1114 bi->bmiHeader.biBitCount = 32;
1115 bi->bmiHeader.biCompression = BI_RGB;
1116 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1117 ok( hdib == NULL, "CreateDIBSection succeeded with zero width\n" );
1118 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1119 ok( hdib != NULL, "CreateDIBitmap failed with zero width\n" );
1120 DeleteObject( hdib );
1121 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1122 ok( !ret || broken(ret), /* nt4 */ "SetDIBits succeeded with zero width\n" );
1123 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1124 ok( !ret || broken(ret), /* nt4 */ "SetDIBitsToDevice succeeded with zero width\n" );
1125 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1126 ok( !ret || broken(ret), /* nt4 */ "StretchDIBits succeeded with zero width\n" );
1127 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1128 ok( !ret, "GetDIBits succeeded with zero width\n" );
1129 bi->bmiHeader.biWidth = 0;
1130 bi->bmiHeader.biHeight = 2;
1131 bi->bmiHeader.biBitCount = 32;
1132 bi->bmiHeader.biCompression = BI_RGB;
1133 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1134 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero width\n" );
1136 bi->bmiHeader.biWidth = 2;
1137 bi->bmiHeader.biHeight = 0;
1138 bi->bmiHeader.biBitCount = 32;
1139 bi->bmiHeader.biCompression = BI_RGB;
1140 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1141 ok( hdib == NULL, "CreateDIBSection succeeded with zero height\n" );
1142 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1143 ok( hdib != NULL, "CreateDIBitmap failed with zero height\n" );
1144 DeleteObject( hdib );
1145 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1146 ok( !ret, "SetDIBits succeeded with zero height\n" );
1147 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1148 ok( !ret, "SetDIBitsToDevice succeeded with zero height\n" );
1149 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1150 ok( !ret, "StretchDIBits succeeded with zero height\n" );
1151 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1152 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1153 bi->bmiHeader.biWidth = 2;
1154 bi->bmiHeader.biHeight = 0;
1155 bi->bmiHeader.biBitCount = 32;
1156 bi->bmiHeader.biCompression = BI_RGB;
1157 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1158 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1160 /* some functions accept DIB_PAL_COLORS+1, but not beyond */
1162 bi->bmiHeader.biWidth = 2;
1163 bi->bmiHeader.biHeight = 2;
1164 bi->bmiHeader.biBitCount = 1;
1165 bi->bmiHeader.biCompression = BI_RGB;
1166 hdib = CreateDIBSection(hdc, bi, DIB_PAL_COLORS+1, &bits, NULL, 0);
1167 ok( hdib == NULL, "CreateDIBSection succeeded with DIB_PAL_COLORS+1\n" );
1168 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_PAL_COLORS+1 );
1169 ok( hdib != NULL, "CreateDIBitmap failed with DIB_PAL_COLORS+1\n" );
1170 DeleteObject( hdib );
1171 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_PAL_COLORS+1);
1172 ok( !ret, "SetDIBits succeeded with DIB_PAL_COLORS+1\n" );
1173 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_PAL_COLORS+1 );
1174 ok( ret, "SetDIBitsToDevice failed with DIB_PAL_COLORS+1\n" );
1175 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_PAL_COLORS+1, SRCCOPY );
1176 ok( ret, "StretchDIBits failed with DIB_PAL_COLORS+1\n" );
1177 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_PAL_COLORS+1);
1178 ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+1\n" );
1179 bi->bmiHeader.biWidth = 2;
1180 bi->bmiHeader.biHeight = 2;
1181 bi->bmiHeader.biBitCount = 1;
1182 bi->bmiHeader.biCompression = BI_RGB;
1183 ret = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS+1);
1184 ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+1\n" );
1186 bi->bmiHeader.biWidth = 2;
1187 bi->bmiHeader.biHeight = 2;
1188 bi->bmiHeader.biBitCount = 1;
1189 bi->bmiHeader.biCompression = BI_RGB;
1190 hdib = CreateDIBSection(hdc, bi, DIB_PAL_COLORS+2, &bits, NULL, 0);
1191 ok( hdib == NULL, "CreateDIBSection succeeded with DIB_PAL_COLORS+2\n" );
1192 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_PAL_COLORS+2 );
1193 ok( hdib == NULL, "CreateDIBitmap succeeded with DIB_PAL_COLORS+2\n" );
1194 DeleteObject( hdib );
1195 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_PAL_COLORS+2);
1196 ok( !ret, "SetDIBits succeeded with DIB_PAL_COLORS+2\n" );
1197 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_PAL_COLORS+2 );
1198 ok( !ret, "SetDIBitsToDevice succeeded with DIB_PAL_COLORS+2\n" );
1199 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_PAL_COLORS+2, SRCCOPY );
1200 ok( !ret, "StretchDIBits succeeded with DIB_PAL_COLORS+2\n" );
1201 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_PAL_COLORS+2);
1202 ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+2\n" );
1203 bi->bmiHeader.biWidth = 2;
1204 bi->bmiHeader.biHeight = 2;
1205 bi->bmiHeader.biBitCount = 1;
1206 bi->bmiHeader.biCompression = BI_RGB;
1207 ret = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS+2);
1208 ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+2\n" );
1211 DeleteObject( hbmp );
1212 ReleaseDC( 0, hdc );
1213 HeapFree( GetProcessHeap(), 0, bi );
1216 static void test_mono_dibsection(void)
1219 HBITMAP old_bm, mono_ds;
1220 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
1221 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
1222 RGBQUAD *colors = pbmi->bmiColors;
1229 memdc = CreateCompatibleDC(hdc);
1231 memset(pbmi, 0, sizeof(bmibuf));
1232 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
1233 pbmi->bmiHeader.biHeight = 10;
1234 pbmi->bmiHeader.biWidth = 10;
1235 pbmi->bmiHeader.biBitCount = 1;
1236 pbmi->bmiHeader.biPlanes = 1;
1237 pbmi->bmiHeader.biCompression = BI_RGB;
1238 colors[0].rgbRed = 0xff;
1239 colors[0].rgbGreen = 0xff;
1240 colors[0].rgbBlue = 0xff;
1241 colors[1].rgbRed = 0x0;
1242 colors[1].rgbGreen = 0x0;
1243 colors[1].rgbBlue = 0x0;
1246 * First dib section is 'inverted' ie color[0] is white, color[1] is black
1249 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1250 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1251 old_bm = SelectObject(memdc, mono_ds);
1253 /* black border, white interior */
1254 Rectangle(memdc, 0, 0, 10, 10);
1255 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1256 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1258 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1260 memset(bits, 0, sizeof(bits));
1263 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1264 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1266 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1268 colors[0].rgbRed = 0x0;
1269 colors[0].rgbGreen = 0x0;
1270 colors[0].rgbBlue = 0x0;
1271 colors[1].rgbRed = 0xff;
1272 colors[1].rgbGreen = 0xff;
1273 colors[1].rgbBlue = 0xff;
1275 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1276 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1278 SelectObject(memdc, old_bm);
1279 DeleteObject(mono_ds);
1282 * Next dib section is 'normal' ie color[0] is black, color[1] is white
1285 colors[0].rgbRed = 0x0;
1286 colors[0].rgbGreen = 0x0;
1287 colors[0].rgbBlue = 0x0;
1288 colors[1].rgbRed = 0xff;
1289 colors[1].rgbGreen = 0xff;
1290 colors[1].rgbBlue = 0xff;
1292 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1293 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1294 old_bm = SelectObject(memdc, mono_ds);
1296 /* black border, white interior */
1297 Rectangle(memdc, 0, 0, 10, 10);
1298 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
1299 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
1301 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
1303 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1304 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1306 /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
1308 colors[0].rgbRed = 0xff;
1309 colors[0].rgbGreen = 0xff;
1310 colors[0].rgbBlue = 0xff;
1311 colors[1].rgbRed = 0x0;
1312 colors[1].rgbGreen = 0x0;
1313 colors[1].rgbBlue = 0x0;
1315 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1316 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1319 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
1322 colors[0].rgbRed = 0xff;
1323 colors[0].rgbGreen = 0xff;
1324 colors[0].rgbBlue = 0xff;
1325 colors[1].rgbRed = 0x0;
1326 colors[1].rgbGreen = 0x0;
1327 colors[1].rgbBlue = 0x0;
1328 num = SetDIBColorTable(memdc, 0, 2, colors);
1329 ok(num == 2, "num = %d\n", num);
1331 /* black border, white interior */
1332 Rectangle(memdc, 0, 0, 10, 10);
1333 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1334 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1336 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1338 memset(bits, 0, sizeof(bits));
1341 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1342 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1344 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1346 colors[0].rgbRed = 0x0;
1347 colors[0].rgbGreen = 0x0;
1348 colors[0].rgbBlue = 0x0;
1349 colors[1].rgbRed = 0xff;
1350 colors[1].rgbGreen = 0xff;
1351 colors[1].rgbBlue = 0xff;
1353 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1354 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1356 SelectObject(memdc, old_bm);
1357 DeleteObject(mono_ds);
1360 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
1363 colors[0].rgbRed = 0xff;
1364 colors[0].rgbGreen = 0x0;
1365 colors[0].rgbBlue = 0x0;
1366 colors[1].rgbRed = 0xfe;
1367 colors[1].rgbGreen = 0x0;
1368 colors[1].rgbBlue = 0x0;
1370 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1371 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1372 old_bm = SelectObject(memdc, mono_ds);
1374 /* black border, white interior */
1375 Rectangle(memdc, 0, 0, 10, 10);
1376 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1377 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1379 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1381 colors[0].rgbRed = 0x0;
1382 colors[0].rgbGreen = 0x0;
1383 colors[0].rgbBlue = 0x0;
1384 colors[1].rgbRed = 0xff;
1385 colors[1].rgbGreen = 0xff;
1386 colors[1].rgbBlue = 0xff;
1388 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1389 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1391 /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
1393 colors[0].rgbRed = 0xff;
1394 colors[0].rgbGreen = 0xff;
1395 colors[0].rgbBlue = 0xff;
1396 colors[1].rgbRed = 0x0;
1397 colors[1].rgbGreen = 0x0;
1398 colors[1].rgbBlue = 0x0;
1400 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1401 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1403 SelectObject(memdc, old_bm);
1404 DeleteObject(mono_ds);
1410 static void test_bitmap(void)
1412 char buf[256], buf_cmp[256];
1413 HBITMAP hbmp, hbmp_old;
1419 hdc = CreateCompatibleDC(0);
1422 SetLastError(0xdeadbeef);
1423 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1426 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1427 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1428 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1433 SetLastError(0xdeadbeef);
1434 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1437 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1438 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1439 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1444 SetLastError(0xdeadbeef);
1445 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1446 ok(!hbmp, "CreateBitmap should fail\n");
1448 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1449 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1453 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1454 assert(hbmp != NULL);
1456 ret = GetObject(hbmp, sizeof(bm), &bm);
1457 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1459 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1460 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1461 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1462 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1463 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1464 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1465 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1467 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1468 assert(sizeof(buf) == sizeof(buf_cmp));
1470 ret = GetBitmapBits(hbmp, 0, NULL);
1471 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1473 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1474 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1476 memset(buf, 0xAA, sizeof(buf));
1477 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1478 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1479 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1481 hbmp_old = SelectObject(hdc, hbmp);
1483 ret = GetObject(hbmp, sizeof(bm), &bm);
1484 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1486 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1487 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1488 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1489 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1490 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1491 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1492 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1494 memset(buf, 0xAA, sizeof(buf));
1495 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1496 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1497 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1499 hbmp_old = SelectObject(hdc, hbmp_old);
1500 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1502 /* test various buffer sizes for GetObject */
1503 ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
1504 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1506 ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1507 ok(ret == 0, "%d != 0\n", ret);
1509 ret = GetObject(hbmp, 0, &bm);
1510 ok(ret == 0, "%d != 0\n", ret);
1512 ret = GetObject(hbmp, 1, &bm);
1513 ok(ret == 0, "%d != 0\n", ret);
1519 static COLORREF get_nearest( int r, int g, int b )
1521 return (r*r + g*g + b*b < (255-r)*(255-r) + (255-g)*(255-g) + (255-b)*(255-b)) ? 0x000000 : 0xffffff;
1524 static int is_black_pen( COLORREF fg, COLORREF bg, int r, int g, int b )
1526 if (fg == 0 || bg == 0xffffff) return RGB(r,g,b) != 0xffffff && RGB(r,g,b) != bg;
1527 return RGB(r,g,b) == 0x000000 || RGB(r,g,b) == bg;
1530 static void test_bitmap_colors( HDC hdc, COLORREF fg, COLORREF bg, int r, int g, int b )
1532 static const WORD pattern_bits[] = { 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa };
1533 char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1534 BITMAPINFO *info = (BITMAPINFO *)buffer;
1535 RGBQUAD *colors = info->bmiColors;
1544 res = SetPixel( hdc, 0, 0, RGB(r,g,b) );
1545 ok( res == get_nearest( r, g, b ),
1546 "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg );
1547 res = GetPixel( hdc, 0, 0 );
1548 ok( res == get_nearest( r, g, b ),
1549 "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg );
1550 res = GetNearestColor( hdc, RGB(r,g,b) );
1551 ok( res == get_nearest( r, g, b ),
1552 "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg );
1555 old_pen = SelectObject( hdc, CreatePen( PS_SOLID, 1, RGB(r,g,b) ));
1556 MoveToEx( hdc, 0, 0, NULL );
1557 LineTo( hdc, 16, 0 );
1558 res = GetPixel( hdc, 0, 0 );
1559 ok( res == (is_black_pen( fg, bg, r, g, b ) ? 0 : 0xffffff),
1560 "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg );
1561 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1562 ok( bits[0] == (is_black_pen( fg, bg, r, g, b ) ? 0x00 : 0xffff),
1563 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1564 DeleteObject( SelectObject( hdc, old_pen ));
1566 /* mono DDB pattern brush */
1567 bitmap = CreateBitmap( 16, 8, 1, 1, pattern_bits );
1568 old_brush = SelectObject( hdc, CreatePatternBrush( bitmap ));
1569 PatBlt( hdc, 0, 0, 16, 16, PATCOPY );
1570 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1571 ok( bits[0] == 0x5555,
1572 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1573 DeleteObject( SelectObject( hdc, old_brush ));
1575 /* mono DDB bitmap */
1576 memdc = CreateCompatibleDC( hdc );
1577 SelectObject( memdc, bitmap );
1578 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1579 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1580 ok( bits[0] == 0x5555,
1581 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1582 SetTextColor( memdc, RGB(255,255,255) );
1583 SetBkColor( memdc, RGB(0,0,0) );
1584 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1585 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1586 ok( bits[0] == 0x5555,
1587 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1589 /* mono DIB section */
1590 memset( buffer, 0, sizeof(buffer) );
1591 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1592 info->bmiHeader.biHeight = -16;
1593 info->bmiHeader.biWidth = 16;
1594 info->bmiHeader.biBitCount = 1;
1595 info->bmiHeader.biPlanes = 1;
1596 info->bmiHeader.biCompression = BI_RGB;
1597 colors[0].rgbRed = 0xff;
1598 colors[0].rgbGreen = 0xff;
1599 colors[0].rgbBlue = 0xf0;
1600 colors[1].rgbRed = 0x20;
1601 colors[1].rgbGreen = 0x0;
1602 colors[1].rgbBlue = 0x0;
1603 bitmap = CreateDIBSection( 0, info, DIB_RGB_COLORS, &bits_ptr, NULL, 0 );
1604 memset( bits_ptr, 0x55, 64 );
1605 DeleteObject( SelectObject( memdc, bitmap ));
1606 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1607 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1608 ok( bits[0] == 0x5555,
1609 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1611 colors[0].rgbRed = 0x0;
1612 colors[0].rgbGreen = 0x0;
1613 colors[0].rgbBlue = 0x10;
1614 colors[1].rgbRed = 0xff;
1615 colors[1].rgbGreen = 0xf0;
1616 colors[1].rgbBlue = 0xff;
1617 bitmap = CreateDIBSection( 0, info, DIB_RGB_COLORS, &bits_ptr, NULL, 0 );
1618 memset( bits_ptr, 0x55, 64 );
1619 DeleteObject( SelectObject( memdc, bitmap ));
1620 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1621 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1622 ok( bits[0] == 0xaaaa,
1623 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1625 SetTextColor( memdc, RGB(0,20,0) );
1626 SetBkColor( memdc, RGB(240,240,240) );
1627 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1628 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1629 ok( bits[0] == 0x5555,
1630 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1632 SetTextColor( memdc, RGB(250,250,250) );
1633 SetBkColor( memdc, RGB(10,10,10) );
1634 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1635 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1636 ok( bits[0] == 0xaaaa,
1637 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1639 DeleteObject( bitmap );
1642 static void test_mono_bitmap(void)
1644 static const COLORREF colors[][2] =
1646 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff) },
1647 { RGB(0xff,0xff,0xff), RGB(0x00,0x00,0x00) },
1648 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xfe) },
1649 { RGB(0x00,0x01,0x00), RGB(0xff,0xff,0xff) },
1650 { RGB(0x00,0x00,0x00), RGB(0x80,0x80,0x80) },
1651 { RGB(0x80,0x80,0x80), RGB(0xff,0xff,0xff) },
1652 { RGB(0x30,0x40,0x50), RGB(0x60,0x70,0x80) },
1653 { RGB(0xa0,0xa0,0xa0), RGB(0x20,0x30,0x10) },
1654 { PALETTEINDEX(0), PALETTEINDEX(255) },
1655 { PALETTEINDEX(1), PALETTEINDEX(2) },
1663 hdc = CreateCompatibleDC(0);
1666 hbmp = CreateBitmap(16, 16, 1, 1, NULL);
1667 assert(hbmp != NULL);
1669 SelectObject( hdc, hbmp );
1671 for (col = 0; col < sizeof(colors) / sizeof(colors[0]); col++)
1673 SetTextColor( hdc, colors[col][0] );
1674 SetBkColor( hdc, colors[col][1] );
1676 for (i = 0; i < 256; i++)
1678 HPALETTE pal = GetCurrentObject( hdc, OBJ_PAL );
1681 if (!GetPaletteEntries( pal, i, 1, &ent )) GetPaletteEntries( pal, 0, 1, &ent );
1682 test_color( hdc, PALETTEINDEX(i), get_nearest( ent.peRed, ent.peGreen, ent.peBlue ));
1683 test_color( hdc, DIBINDEX(i), (i == 1) ? 0xffffff : 0x000000 );
1686 for (r = 0; r < 256; r += 15)
1687 for (g = 0; g < 256; g += 15)
1688 for (b = 0; b < 256; b += 15)
1689 test_bitmap_colors( hdc, colors[col][0], colors[col][1], r, g, b );
1696 static void test_bmBits(void)
1702 memset(bits, 0, sizeof(bits));
1703 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1704 ok(hbmp != NULL, "CreateBitmap failed\n");
1706 memset(&bmp, 0xFF, sizeof(bmp));
1707 ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1708 "GetObject failed or returned a wrong structure size\n");
1709 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1714 static void test_GetDIBits_selected_DIB(UINT bpp)
1721 UINT dib_size, dib32_size;
1728 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1729 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1731 /* Create a DIB section with a color table */
1733 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1734 info->bmiHeader.biWidth = 32;
1735 info->bmiHeader.biHeight = 32;
1736 info->bmiHeader.biPlanes = 1;
1737 info->bmiHeader.biBitCount = bpp;
1738 info->bmiHeader.biCompression = BI_RGB;
1739 info->bmiHeader.biXPelsPerMeter = 0;
1740 info->bmiHeader.biYPelsPerMeter = 0;
1741 info->bmiHeader.biClrUsed = 0;
1742 info->bmiHeader.biClrImportant = 0;
1744 for (i=0; i < (1u << bpp); i++)
1746 BYTE c = i * (1 << (8 - bpp));
1747 info->bmiColors[i].rgbRed = c;
1748 info->bmiColors[i].rgbGreen = c;
1749 info->bmiColors[i].rgbBlue = c;
1750 info->bmiColors[i].rgbReserved = 0;
1753 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1754 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1755 dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1757 /* Set the bits of the DIB section */
1758 for (i=0; i < dib_size; i++)
1760 ((BYTE *)bits)[i] = i % 256;
1763 /* Select the DIB into a DC */
1764 dib_dc = CreateCompatibleDC(NULL);
1765 old_bmp = SelectObject(dib_dc, dib);
1766 dc = CreateCompatibleDC(NULL);
1767 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
1769 /* Copy the DIB attributes but not the color table */
1770 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1772 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1773 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1775 /* Compare the color table and the bits */
1776 for (i=0; i < (1u << bpp); i++)
1777 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1778 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1779 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1780 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1781 "color table entry %d differs (bpp %d)\n", i, bpp );
1783 ok( !memcmp( bits, bits2, dib_size ), "bit mismatch (bpp %d)\n", bpp );
1785 /* Test various combinations of lines = 0 and bits2 = NULL */
1786 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1787 res = GetDIBits( dc, dib, 0, 0, bits2, info2, DIB_RGB_COLORS );
1788 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1789 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1790 "color table mismatch (bpp %d)\n", bpp );
1792 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1793 res = GetDIBits( dc, dib, 0, 0, NULL, info2, DIB_RGB_COLORS );
1794 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1795 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1796 "color table mismatch (bpp %d)\n", bpp );
1798 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1799 res = GetDIBits( dc, dib, 0, info->bmiHeader.biHeight, NULL, info2, DIB_RGB_COLORS );
1800 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1801 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1802 "color table mismatch (bpp %d)\n", bpp );
1804 /* Map into a 32bit-DIB */
1805 info2->bmiHeader.biBitCount = 32;
1806 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1807 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1809 /* Check if last pixel was set */
1810 pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
1811 ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
1813 HeapFree(GetProcessHeap(), 0, bits2);
1816 SelectObject(dib_dc, old_bmp);
1819 HeapFree(GetProcessHeap(), 0, info2);
1820 HeapFree(GetProcessHeap(), 0, info);
1823 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1837 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1838 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1840 width = height = 16;
1842 /* Create a DDB (device-dependent bitmap) */
1846 ddb = CreateBitmap(width, height, 1, 1, NULL);
1850 HDC screen_dc = GetDC(NULL);
1851 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1852 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1853 ReleaseDC(NULL, screen_dc);
1856 /* Set the pixels */
1857 ddb_dc = CreateCompatibleDC(NULL);
1858 old_bmp = SelectObject(ddb_dc, ddb);
1859 for (i = 0; i < width; i++)
1861 for (j=0; j < height; j++)
1863 BYTE c = (i * width + j) % 256;
1864 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1867 SelectObject(ddb_dc, old_bmp);
1869 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1870 info->bmiHeader.biWidth = width;
1871 info->bmiHeader.biHeight = height;
1872 info->bmiHeader.biPlanes = 1;
1873 info->bmiHeader.biBitCount = bpp;
1874 info->bmiHeader.biCompression = BI_RGB;
1876 dc = CreateCompatibleDC(NULL);
1878 /* Fill in biSizeImage */
1879 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1880 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1882 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1883 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1886 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1887 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1889 /* Copy the DIB attributes but not the color table */
1890 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1892 /* Select the DDB into another DC */
1893 old_bmp = SelectObject(ddb_dc, ddb);
1896 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1897 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1899 /* Compare the color table and the bits */
1902 for (i=0; i < (1u << bpp); i++)
1903 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1904 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1905 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1906 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1907 "color table entry %d differs (bpp %d)\n", i, bpp );
1910 ok( !memcmp( bits, bits2, info->bmiHeader.biSizeImage ), "bit mismatch (bpp %d)\n", bpp );
1912 /* Test the palette */
1913 if (info2->bmiHeader.biBitCount <= 8)
1915 WORD *colors = (WORD*)info2->bmiColors;
1917 /* Get the palette indices */
1918 res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1919 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1921 for (i = 0; i < (1 << info->bmiHeader.biBitCount); i++)
1922 ok( colors[i] == i, "%d: got %d (bpp %d)\n", i, colors[i], bpp );
1925 HeapFree(GetProcessHeap(), 0, bits2);
1926 HeapFree(GetProcessHeap(), 0, bits);
1929 SelectObject(ddb_dc, old_bmp);
1932 HeapFree(GetProcessHeap(), 0, info2);
1933 HeapFree(GetProcessHeap(), 0, info);
1936 static void test_GetDIBits(void)
1938 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1939 static const BYTE bmp_bits_1[16 * 2] =
1941 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1942 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1943 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1944 0xff,0xff, 0,0, 0xff,0xff, 0,0
1946 /* 4-bytes aligned 1-bit DIB data: 16x16 */
1947 static const BYTE dib_bits_1[16 * 4] =
1949 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1950 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1951 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1952 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1954 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1955 static const BYTE bmp_bits_24[16 * 16*3] =
1957 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1958 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1959 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1960 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1961 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1962 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1963 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1964 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1965 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1966 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1967 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1968 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1969 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1970 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1971 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1972 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1973 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1974 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1975 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1976 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1977 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1978 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1979 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1980 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1981 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1982 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1983 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1984 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1985 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1986 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1987 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1988 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1990 /* 4-bytes aligned 24-bit DIB data: 16x16 */
1991 static const BYTE dib_bits_24[16 * 16*3] =
1993 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1994 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1995 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1996 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1997 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1998 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1999 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2000 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2001 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2002 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2003 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2004 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2005 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2006 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2007 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2008 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2009 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2010 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2011 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2012 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2013 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2014 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2015 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2016 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2017 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2018 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2019 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2020 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2021 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2022 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2023 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2024 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
2029 int i, bytes, lines;
2031 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
2032 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
2033 RGBQUAD *colors = bi->bmiColors;
2034 PALETTEENTRY pal_ents[20];
2038 /* 1-bit source bitmap data */
2039 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
2040 ok(hbmp != 0, "CreateBitmap failed\n");
2042 memset(&bm, 0xAA, sizeof(bm));
2043 bytes = GetObject(hbmp, sizeof(bm), &bm);
2044 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2045 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2046 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
2047 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
2048 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2049 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
2050 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2051 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2053 bytes = GetBitmapBits(hbmp, 0, NULL);
2054 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
2055 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
2056 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
2057 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
2059 /* retrieve 1-bit DIB data */
2060 memset(bi, 0, sizeof(*bi));
2061 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2062 bi->bmiHeader.biWidth = bm.bmWidth;
2063 bi->bmiHeader.biHeight = bm.bmHeight;
2064 bi->bmiHeader.biPlanes = 1;
2065 bi->bmiHeader.biBitCount = 1;
2066 bi->bmiHeader.biCompression = BI_RGB;
2067 bi->bmiHeader.biClrUsed = 37;
2068 bi->bmiHeader.biSizeImage = 0;
2069 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2070 SetLastError(0xdeadbeef);
2071 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2072 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
2073 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
2074 broken(GetLastError() == 0xdeadbeef), /* winnt */
2075 "wrong error %u\n", GetLastError());
2076 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
2077 ok(bi->bmiHeader.biClrUsed == 37 || broken(bi->bmiHeader.biClrUsed == 0),
2078 "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2080 memset(buf, 0xAA, sizeof(buf));
2081 SetLastError(0xdeadbeef);
2082 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2083 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2084 lines, bm.bmHeight, GetLastError());
2085 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
2086 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2088 /* the color table consists of black and white */
2089 ok(colors[0].rgbRed == 0 && colors[0].rgbGreen == 0 &&
2090 colors[0].rgbBlue == 0 && colors[0].rgbReserved == 0,
2091 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
2092 colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue, colors[0].rgbReserved);
2093 ok(colors[1].rgbRed == 0xff && colors[1].rgbGreen == 0xff &&
2094 colors[1].rgbBlue == 0xff && colors[1].rgbReserved == 0,
2095 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
2096 colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue, colors[1].rgbReserved);
2097 for (i = 2; i < 256; i++)
2099 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2100 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2101 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2102 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2105 /* returned bits are DWORD aligned and upside down */
2106 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
2108 /* Test the palette indices */
2109 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2110 SetLastError(0xdeadbeef);
2111 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
2112 ok(((WORD*)colors)[0] == 0, "Color 0 is %d\n", ((WORD*)colors)[0]);
2113 ok(((WORD*)colors)[1] == 1, "Color 1 is %d\n", ((WORD*)colors)[1]);
2114 for (i = 2; i < 256; i++)
2115 ok(((WORD*)colors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)colors)[1]);
2117 /* retrieve 24-bit DIB data */
2118 memset(bi, 0, sizeof(*bi));
2119 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2120 bi->bmiHeader.biWidth = bm.bmWidth;
2121 bi->bmiHeader.biHeight = bm.bmHeight;
2122 bi->bmiHeader.biPlanes = 1;
2123 bi->bmiHeader.biBitCount = 24;
2124 bi->bmiHeader.biCompression = BI_RGB;
2125 bi->bmiHeader.biClrUsed = 37;
2126 bi->bmiHeader.biSizeImage = 0;
2127 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2128 memset(buf, 0xAA, sizeof(buf));
2129 SetLastError(0xdeadbeef);
2130 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2131 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2132 lines, bm.bmHeight, GetLastError());
2133 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2134 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2136 /* the color table doesn't exist for 24-bit images */
2137 for (i = 0; i < 256; i++)
2139 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2140 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2141 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2142 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2145 /* returned bits are DWORD aligned and upside down */
2146 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2149 /* 24-bit source bitmap data */
2150 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
2151 ok(hbmp != 0, "CreateBitmap failed\n");
2152 SetLastError(0xdeadbeef);
2153 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
2154 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
2155 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
2156 lines, bm.bmHeight, GetLastError());
2158 memset(&bm, 0xAA, sizeof(bm));
2159 bytes = GetObject(hbmp, sizeof(bm), &bm);
2160 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2161 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2162 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
2163 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
2164 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2165 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
2166 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2167 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2169 bytes = GetBitmapBits(hbmp, 0, NULL);
2170 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
2171 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
2172 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
2173 bm.bmWidthBytes * bm.bmHeight, bytes);
2175 /* retrieve 1-bit DIB data */
2176 memset(bi, 0, sizeof(*bi));
2177 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2178 bi->bmiHeader.biWidth = bm.bmWidth;
2179 bi->bmiHeader.biHeight = bm.bmHeight;
2180 bi->bmiHeader.biPlanes = 1;
2181 bi->bmiHeader.biBitCount = 1;
2182 bi->bmiHeader.biCompression = BI_RGB;
2183 bi->bmiHeader.biClrUsed = 37;
2184 bi->bmiHeader.biSizeImage = 0;
2185 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2186 memset(buf, 0xAA, sizeof(buf));
2187 SetLastError(0xdeadbeef);
2188 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2189 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2190 lines, bm.bmHeight, GetLastError());
2191 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
2192 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2194 /* the color table consists of black and white */
2195 ok(colors[0].rgbRed == 0 && colors[0].rgbGreen == 0 &&
2196 colors[0].rgbBlue == 0 && colors[0].rgbReserved == 0,
2197 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
2198 colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue, colors[0].rgbReserved);
2199 ok(colors[1].rgbRed == 0xff && colors[1].rgbGreen == 0xff &&
2200 colors[1].rgbBlue == 0xff && colors[1].rgbReserved == 0,
2201 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
2202 colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue, colors[1].rgbReserved);
2203 for (i = 2; i < 256; i++)
2205 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2206 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2207 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2208 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2211 /* returned bits are DWORD aligned and upside down */
2212 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
2214 /* Test the palette indices */
2215 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2216 SetLastError(0xdeadbeef);
2217 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
2218 ok(((WORD*)colors)[0] == 0, "Color 0 is %d\n", ((WORD*)colors)[0]);
2219 ok(((WORD*)colors)[1] == 1, "Color 1 is %d\n", ((WORD*)colors)[1]);
2220 for (i = 2; i < 256; i++)
2221 ok(((WORD*)colors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)colors)[i]);
2223 /* retrieve 4-bit DIB data */
2224 memset(bi, 0, sizeof(*bi));
2225 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2226 bi->bmiHeader.biWidth = bm.bmWidth;
2227 bi->bmiHeader.biHeight = bm.bmHeight;
2228 bi->bmiHeader.biPlanes = 1;
2229 bi->bmiHeader.biBitCount = 4;
2230 bi->bmiHeader.biCompression = BI_RGB;
2231 bi->bmiHeader.biClrUsed = 37;
2232 bi->bmiHeader.biSizeImage = 0;
2233 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2234 memset(buf, 0xAA, sizeof(buf));
2235 SetLastError(0xdeadbeef);
2236 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2237 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2238 lines, bm.bmHeight, GetLastError());
2239 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2241 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2243 for (i = 0; i < 16; i++)
2246 int entry = i < 8 ? i : i + 4;
2248 if(entry == 7) entry = 12;
2249 else if(entry == 12) entry = 7;
2251 expect.rgbRed = pal_ents[entry].peRed;
2252 expect.rgbGreen = pal_ents[entry].peGreen;
2253 expect.rgbBlue = pal_ents[entry].peBlue;
2254 expect.rgbReserved = 0;
2256 ok(!memcmp(colors + i, &expect, sizeof(expect)),
2257 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2258 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2259 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2262 /* retrieve 8-bit DIB data */
2263 memset(bi, 0, sizeof(*bi));
2264 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2265 bi->bmiHeader.biWidth = bm.bmWidth;
2266 bi->bmiHeader.biHeight = bm.bmHeight;
2267 bi->bmiHeader.biPlanes = 1;
2268 bi->bmiHeader.biBitCount = 8;
2269 bi->bmiHeader.biCompression = BI_RGB;
2270 bi->bmiHeader.biClrUsed = 37;
2271 bi->bmiHeader.biSizeImage = 0;
2272 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2273 memset(buf, 0xAA, sizeof(buf));
2274 SetLastError(0xdeadbeef);
2275 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2276 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2277 lines, bm.bmHeight, GetLastError());
2278 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2280 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2282 for (i = 0; i < 256; i++)
2286 if (i < 10 || i >= 246)
2288 int entry = i < 10 ? i : i - 236;
2289 expect.rgbRed = pal_ents[entry].peRed;
2290 expect.rgbGreen = pal_ents[entry].peGreen;
2291 expect.rgbBlue = pal_ents[entry].peBlue;
2295 expect.rgbRed = (i & 0x07) << 5;
2296 expect.rgbGreen = (i & 0x38) << 2;
2297 expect.rgbBlue = i & 0xc0;
2299 expect.rgbReserved = 0;
2301 ok(!memcmp(colors + i, &expect, sizeof(expect)),
2302 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2303 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2304 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2307 /* retrieve 24-bit DIB data */
2308 memset(bi, 0, sizeof(*bi));
2309 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2310 bi->bmiHeader.biWidth = bm.bmWidth;
2311 bi->bmiHeader.biHeight = bm.bmHeight;
2312 bi->bmiHeader.biPlanes = 1;
2313 bi->bmiHeader.biBitCount = 24;
2314 bi->bmiHeader.biCompression = BI_RGB;
2315 bi->bmiHeader.biClrUsed = 37;
2316 bi->bmiHeader.biSizeImage = 0;
2317 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2318 memset(buf, 0xAA, sizeof(buf));
2319 SetLastError(0xdeadbeef);
2320 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2321 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2322 lines, bm.bmHeight, GetLastError());
2323 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2324 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2326 /* the color table doesn't exist for 24-bit images */
2327 for (i = 0; i < 256; i++)
2329 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2330 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2331 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2332 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2335 /* returned bits are DWORD aligned and upside down */
2336 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2342 static void test_GetDIBits_BI_BITFIELDS(void)
2344 /* Try a screen resolution detection technique
2345 * from the September 1999 issue of Windows Developer's Journal
2346 * which seems to be in widespread use.
2347 * http://www.lesher.ws/highcolor.html
2348 * http://www.lesher.ws/vidfmt.c
2349 * It hinges on being able to retrieve the bitmaps
2350 * for the three primary colors in non-paletted 16 bit mode.
2352 char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
2354 LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
2355 DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
2361 memset(dibinfo, 0, sizeof(dibinfo_buf));
2362 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2365 ok(hdc != NULL, "GetDC failed?\n");
2366 hbm = CreateCompatibleBitmap(hdc, 1, 1);
2367 ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
2369 /* Call GetDIBits to fill in bmiHeader. */
2370 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2371 ok(ret == 1, "GetDIBits failed\n");
2372 if (dibinfo->bmiHeader.biBitCount > 8)
2374 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2375 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2376 "compression is %u (%d bpp)\n", dibinfo->bmiHeader.biCompression, dibinfo->bmiHeader.biBitCount );
2378 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2380 ok( !bitmasks[0], "red mask is set\n" );
2381 ok( !bitmasks[1], "green mask is set\n" );
2382 ok( !bitmasks[2], "blue mask is set\n" );
2384 /* test with NULL bits pointer and correct bpp */
2385 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2386 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2387 ok(ret == 1, "GetDIBits failed\n");
2389 ok( bitmasks[0] != 0, "red mask is not set\n" );
2390 ok( bitmasks[1] != 0, "green mask is not set\n" );
2391 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2392 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2394 /* test with valid bits pointer */
2395 memset(dibinfo, 0, sizeof(dibinfo_buf));
2396 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2397 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2398 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2399 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2400 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2401 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2403 ok( bitmasks[0] != 0, "red mask is not set\n" );
2404 ok( bitmasks[1] != 0, "green mask is not set\n" );
2405 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2406 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2408 /* now with bits and 0 lines */
2409 memset(dibinfo, 0, sizeof(dibinfo_buf));
2410 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2411 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2412 SetLastError(0xdeadbeef);
2413 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2414 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2416 ok( !bitmasks[0], "red mask is set\n" );
2417 ok( !bitmasks[1], "green mask is set\n" );
2418 ok( !bitmasks[2], "blue mask is set\n" );
2419 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2421 memset(bitmasks, 0, 3*sizeof(DWORD));
2422 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2423 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2424 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2426 ok( bitmasks[0] != 0, "red mask is not set\n" );
2427 ok( bitmasks[1] != 0, "green mask is not set\n" );
2428 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2429 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2432 else skip("bitmap in colortable mode, skipping BI_BITFIELDS tests\n");
2436 /* same thing now with a 32-bpp DIB section */
2438 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2439 dibinfo->bmiHeader.biWidth = 1;
2440 dibinfo->bmiHeader.biHeight = 1;
2441 dibinfo->bmiHeader.biPlanes = 1;
2442 dibinfo->bmiHeader.biBitCount = 32;
2443 dibinfo->bmiHeader.biCompression = BI_RGB;
2444 dibinfo->bmiHeader.biSizeImage = 0;
2445 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2446 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2447 dibinfo->bmiHeader.biClrUsed = 0;
2448 dibinfo->bmiHeader.biClrImportant = 0;
2449 bitmasks[0] = 0x0000ff;
2450 bitmasks[1] = 0x00ff00;
2451 bitmasks[2] = 0xff0000;
2452 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2453 ok( hbm != 0, "failed to create bitmap\n" );
2455 memset(dibinfo, 0, sizeof(dibinfo_buf));
2456 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2457 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2458 ok(ret == 1, "GetDIBits failed\n");
2459 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2461 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2462 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2463 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2464 ok( !bitmasks[0], "red mask is set\n" );
2465 ok( !bitmasks[1], "green mask is set\n" );
2466 ok( !bitmasks[2], "blue mask is set\n" );
2468 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2469 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2470 ok(ret == 1, "GetDIBits failed\n");
2471 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2472 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2473 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2474 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2475 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2477 ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
2478 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2479 ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
2481 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2485 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2486 dibinfo->bmiHeader.biWidth = 1;
2487 dibinfo->bmiHeader.biHeight = 1;
2488 dibinfo->bmiHeader.biPlanes = 1;
2489 dibinfo->bmiHeader.biBitCount = 32;
2490 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2491 dibinfo->bmiHeader.biSizeImage = 0;
2492 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2493 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2494 dibinfo->bmiHeader.biClrUsed = 0;
2495 dibinfo->bmiHeader.biClrImportant = 0;
2496 bitmasks[0] = 0x0000ff;
2497 bitmasks[1] = 0x00ff00;
2498 bitmasks[2] = 0xff0000;
2499 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2500 ok( hbm != 0, "failed to create bitmap\n" );
2504 memset(dibinfo, 0, sizeof(dibinfo_buf));
2505 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2506 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2507 ok(ret == 1, "GetDIBits failed\n");
2509 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
2510 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2511 ok( !bitmasks[0], "red mask is set\n" );
2512 ok( !bitmasks[1], "green mask is set\n" );
2513 ok( !bitmasks[2], "blue mask is set\n" );
2515 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2516 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2517 ok(ret == 1, "GetDIBits failed\n");
2518 ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
2519 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2520 ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
2521 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2526 /* 24-bpp DIB sections don't have bitfields */
2528 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2529 dibinfo->bmiHeader.biWidth = 1;
2530 dibinfo->bmiHeader.biHeight = 1;
2531 dibinfo->bmiHeader.biPlanes = 1;
2532 dibinfo->bmiHeader.biBitCount = 24;
2533 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2534 dibinfo->bmiHeader.biSizeImage = 0;
2535 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2536 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2537 dibinfo->bmiHeader.biClrUsed = 0;
2538 dibinfo->bmiHeader.biClrImportant = 0;
2539 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2540 ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
2541 dibinfo->bmiHeader.biCompression = BI_RGB;
2542 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2543 ok( hbm != 0, "failed to create bitmap\n" );
2545 memset(dibinfo, 0, sizeof(dibinfo_buf));
2546 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2547 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2548 ok(ret == 1, "GetDIBits failed\n");
2549 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2551 ok( dibinfo->bmiHeader.biCompression == BI_RGB,
2552 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2553 ok( !bitmasks[0], "red mask is set\n" );
2554 ok( !bitmasks[1], "green mask is set\n" );
2555 ok( !bitmasks[2], "blue mask is set\n" );
2557 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2558 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2559 ok(ret == 1, "GetDIBits failed\n");
2560 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2561 ok( !bitmasks[0], "red mask is set\n" );
2562 ok( !bitmasks[1], "green mask is set\n" );
2563 ok( !bitmasks[2], "blue mask is set\n" );
2564 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2567 ReleaseDC(NULL, hdc);
2570 static void test_select_object(void)
2573 HBITMAP hbm, hbm_old;
2575 DWORD depths[] = {8, 15, 16, 24, 32};
2580 ok(hdc != 0, "GetDC(0) failed\n");
2581 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2582 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2584 hbm_old = SelectObject(hdc, hbm);
2585 ok(hbm_old == 0, "SelectObject should fail\n");
2590 hdc = CreateCompatibleDC(0);
2591 ok(hdc != 0, "GetDC(0) failed\n");
2592 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2593 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2595 hbm_old = SelectObject(hdc, hbm);
2596 ok(hbm_old != 0, "SelectObject failed\n");
2597 hbm_old = SelectObject(hdc, hbm_old);
2598 ok(hbm_old == hbm, "SelectObject failed\n");
2602 /* test an 1-bpp bitmap */
2603 planes = GetDeviceCaps(hdc, PLANES);
2606 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
2607 ok(hbm != 0, "CreateBitmap failed\n");
2609 hbm_old = SelectObject(hdc, hbm);
2610 ok(hbm_old != 0, "SelectObject failed\n");
2611 hbm_old = SelectObject(hdc, hbm_old);
2612 ok(hbm_old == hbm, "SelectObject failed\n");
2616 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
2617 /* test a color bitmap to dc bpp matching */
2618 planes = GetDeviceCaps(hdc, PLANES);
2619 bpp = GetDeviceCaps(hdc, BITSPIXEL);
2621 hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
2622 ok(hbm != 0, "CreateBitmap failed\n");
2624 hbm_old = SelectObject(hdc, hbm);
2625 if(depths[i] == bpp ||
2626 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
2628 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
2629 SelectObject(hdc, hbm_old);
2631 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
2634 memset(&bm, 0xAA, sizeof(bm));
2635 bytes = GetObject(hbm, sizeof(bm), &bm);
2636 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2637 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2638 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
2639 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
2640 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2641 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
2642 if(depths[i] == 15) {
2643 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
2645 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2647 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2655 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
2660 ret = GetObjectType(hbmp);
2661 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
2663 ret = GetObject(hbmp, 0, 0);
2664 ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
2666 memset(&bm, 0xDA, sizeof(bm));
2667 SetLastError(0xdeadbeef);
2668 ret = GetObject(hbmp, sizeof(bm), &bm);
2669 if (!ret) /* XP, only for curObj2 */ return;
2670 ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
2671 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2672 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2673 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2674 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2675 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2676 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2677 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2680 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2682 static void test_CreateBitmap(void)
2685 HDC screenDC = GetDC(0);
2686 HDC hdc = CreateCompatibleDC(screenDC);
2689 /* all of these are the stock monochrome bitmap */
2690 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2691 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2692 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2693 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2694 HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2695 HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2697 /* these 2 are not the stock monochrome bitmap */
2698 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2699 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2701 HBITMAP old1 = SelectObject(hdc, bm2);
2702 HBITMAP old2 = SelectObject(screenDC, bm3);
2703 SelectObject(hdc, old1);
2704 SelectObject(screenDC, old2);
2706 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2707 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2708 bm, bm1, bm4, bm5, curObj1, old1);
2709 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2711 ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
2712 ok(old2 == 0, "old2 %p\n", old2);
2714 test_mono_1x1_bmp(bm);
2715 test_mono_1x1_bmp(bm1);
2716 test_mono_1x1_bmp(bm2);
2717 test_mono_1x1_bmp(bm3);
2718 test_mono_1x1_bmp(bm4);
2719 test_mono_1x1_bmp(bm5);
2720 test_mono_1x1_bmp(old1);
2721 test_mono_1x1_bmp(curObj1);
2731 ReleaseDC(0, screenDC);
2733 /* show that Windows ignores the provided bm.bmWidthBytes */
2737 bmp.bmWidthBytes = 28;
2739 bmp.bmBitsPixel = 1;
2741 bm = CreateBitmapIndirect(&bmp);
2742 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2743 test_mono_1x1_bmp(bm);
2746 /* Test how the bmBitsPixel field is treated */
2747 for(i = 1; i <= 33; i++) {
2751 bmp.bmWidthBytes = 28;
2753 bmp.bmBitsPixel = i;
2755 SetLastError(0xdeadbeef);
2756 bm = CreateBitmapIndirect(&bmp);
2758 DWORD error = GetLastError();
2759 ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
2760 ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2764 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2765 GetObject(bm, sizeof(bmp), &bmp);
2772 } else if(i <= 16) {
2774 } else if(i <= 24) {
2776 } else if(i <= 32) {
2779 ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2780 i, bmp.bmBitsPixel, expect);
2785 static void test_bitmapinfoheadersize(void)
2792 memset(&bmi, 0, sizeof(BITMAPINFO));
2793 bmi.bmiHeader.biHeight = 100;
2794 bmi.bmiHeader.biWidth = 512;
2795 bmi.bmiHeader.biBitCount = 24;
2796 bmi.bmiHeader.biPlanes = 1;
2798 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2800 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2801 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2803 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2805 SetLastError(0xdeadbeef);
2806 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2807 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2810 bmi.bmiHeader.biSize++;
2812 SetLastError(0xdeadbeef);
2813 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2815 broken(!hdib), /* Win98, WinMe */
2816 "CreateDIBSection error %d\n", GetLastError());
2819 bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2821 SetLastError(0xdeadbeef);
2822 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2824 broken(!hdib), /* Win98, WinMe */
2825 "CreateDIBSection error %d\n", GetLastError());
2828 bmi.bmiHeader.biSize++;
2830 SetLastError(0xdeadbeef);
2831 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2833 broken(!hdib), /* Win98, WinMe */
2834 "CreateDIBSection error %d\n", GetLastError());
2837 bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2839 SetLastError(0xdeadbeef);
2840 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2841 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2844 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2846 SetLastError(0xdeadbeef);
2847 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2849 broken(!hdib), /* Win95 */
2850 "CreateDIBSection error %d\n", GetLastError());
2853 memset(&bci, 0, sizeof(BITMAPCOREINFO));
2854 bci.bmciHeader.bcHeight = 100;
2855 bci.bmciHeader.bcWidth = 512;
2856 bci.bmciHeader.bcBitCount = 24;
2857 bci.bmciHeader.bcPlanes = 1;
2859 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2861 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2862 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2864 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2866 SetLastError(0xdeadbeef);
2867 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2868 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2871 bci.bmciHeader.bcSize++;
2873 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2874 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2876 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2878 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2879 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2884 static void test_get16dibits(void)
2886 BYTE bits[4 * (16 / sizeof(BYTE))];
2888 HDC screen_dc = GetDC(NULL);
2891 int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2893 int overwritten_bytes = 0;
2895 memset(bits, 0, sizeof(bits));
2896 hbmp = CreateBitmap(2, 2, 1, 16, bits);
2897 ok(hbmp != NULL, "CreateBitmap failed\n");
2899 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2902 memset(info, '!', info_len);
2903 memset(info, 0, sizeof(info->bmiHeader));
2905 info->bmiHeader.biSize = sizeof(info->bmiHeader);
2906 info->bmiHeader.biWidth = 2;
2907 info->bmiHeader.biHeight = 2;
2908 info->bmiHeader.biPlanes = 1;
2909 info->bmiHeader.biCompression = BI_RGB;
2911 ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2912 ok(ret != 0, "GetDIBits failed got %d\n", ret);
2914 for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2916 overwritten_bytes++;
2917 ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2919 HeapFree(GetProcessHeap(), 0, info);
2921 ReleaseDC(NULL, screen_dc);
2924 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2925 DWORD dwRop, UINT32 expected, int line)
2927 *srcBuffer = 0xFEDCBA98;
2928 *dstBuffer = 0x89ABCDEF;
2929 BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
2930 ok(expected == *dstBuffer,
2931 "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2932 dwRop, expected, *dstBuffer, line);
2935 static void test_BitBlt(void)
2937 HBITMAP bmpDst, bmpSrc;
2938 HBITMAP oldDst, oldSrc;
2939 HDC hdcScreen, hdcDst, hdcSrc;
2940 UINT32 *dstBuffer, *srcBuffer;
2941 HBRUSH hBrush, hOldBrush;
2942 BITMAPINFO bitmapInfo;
2944 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2945 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2946 bitmapInfo.bmiHeader.biWidth = 1;
2947 bitmapInfo.bmiHeader.biHeight = 1;
2948 bitmapInfo.bmiHeader.biPlanes = 1;
2949 bitmapInfo.bmiHeader.biBitCount = 32;
2950 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2951 bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2953 hdcScreen = CreateCompatibleDC(0);
2954 hdcDst = CreateCompatibleDC(hdcScreen);
2955 hdcSrc = CreateCompatibleDC(hdcDst);
2957 /* Setup the destination dib section */
2958 bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
2960 oldDst = SelectObject(hdcDst, bmpDst);
2962 hBrush = CreateSolidBrush(0x12345678);
2963 hOldBrush = SelectObject(hdcDst, hBrush);
2965 /* Setup the source dib section */
2966 bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
2968 oldSrc = SelectObject(hdcSrc, bmpSrc);
2970 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2971 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2972 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2973 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2974 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2975 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2976 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2977 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2978 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2979 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2980 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2981 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2982 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2983 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2984 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2987 SelectObject(hdcSrc, oldSrc);
2988 DeleteObject(bmpSrc);
2991 SelectObject(hdcDst, hOldBrush);
2992 DeleteObject(hBrush);
2993 SelectObject(hdcDst, oldDst);
2994 DeleteObject(bmpDst);
2998 DeleteDC(hdcScreen);
3001 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
3002 DWORD dwRop, UINT32 expected, int line)
3004 *srcBuffer = 0xFEDCBA98;
3005 *dstBuffer = 0x89ABCDEF;
3006 StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
3007 ok(expected == *dstBuffer,
3008 "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
3009 dwRop, expected, *dstBuffer, line);
3012 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, BITMAPINFO *dst_info, UINT32 *dstBuffer, UINT32 *srcBuffer,
3013 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
3014 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
3015 UINT32 *expected, int line)
3017 int dst_size = get_dib_image_size( dst_info );
3019 memset(dstBuffer, 0, dst_size);
3020 StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
3021 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
3022 ok(memcmp(dstBuffer, expected, dst_size) == 0,
3023 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
3024 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
3025 expected[0], expected[1], expected[2], expected[3],
3026 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
3027 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3028 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
3031 static void test_StretchBlt(void)
3033 HBITMAP bmpDst, bmpSrc;
3034 HBITMAP oldDst, oldSrc;
3035 HDC hdcScreen, hdcDst, hdcSrc;
3036 UINT32 *dstBuffer, *srcBuffer;
3037 HBRUSH hBrush, hOldBrush;
3038 BITMAPINFO biDst, biSrc;
3039 UINT32 expected[256];
3042 memset(&biDst, 0, sizeof(BITMAPINFO));
3043 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3044 biDst.bmiHeader.biWidth = 16;
3045 biDst.bmiHeader.biHeight = -16;
3046 biDst.bmiHeader.biPlanes = 1;
3047 biDst.bmiHeader.biBitCount = 32;
3048 biDst.bmiHeader.biCompression = BI_RGB;
3049 memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
3051 hdcScreen = CreateCompatibleDC(0);
3052 hdcDst = CreateCompatibleDC(hdcScreen);
3053 hdcSrc = CreateCompatibleDC(hdcDst);
3056 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3058 oldDst = SelectObject(hdcDst, bmpDst);
3060 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
3062 oldSrc = SelectObject(hdcSrc, bmpSrc);
3064 hBrush = CreateSolidBrush(0x012345678);
3065 hOldBrush = SelectObject(hdcDst, hBrush);
3067 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3068 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3069 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3070 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3071 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3072 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3073 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3074 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3075 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3076 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3077 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3078 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3079 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3080 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3081 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3083 SelectObject(hdcDst, hOldBrush);
3084 DeleteObject(hBrush);
3086 /* Top-down to top-down tests */
3087 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3088 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
3090 memset( expected, 0, get_dib_image_size( &biDst ) );
3091 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
3092 expected[16] = 0xFEDCBA98, expected[17] = 0x76543210;
3093 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3094 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3096 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3097 expected[16] = 0x00000000, expected[17] = 0x00000000;
3098 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3099 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
3101 expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
3102 expected[16] = 0xCAFED00D, expected[17] = 0xCAFED00D;
3103 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3104 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
3106 /* This is an example of the dst width (height) == 1 exception, explored below */
3107 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3108 expected[16] = 0x00000000, expected[17] = 0x00000000;
3109 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3110 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
3112 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
3113 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
3114 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3115 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3117 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
3118 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
3119 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3120 1, 1, -2, -2, 0, 0, 2, 2, expected, __LINE__);
3122 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3123 expected[16] = 0x00000000, expected[17] = 0x00000000;
3124 todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3125 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
3127 expected[0] = 0x00000000, expected[1] = 0x00000000;
3128 expected[16] = 0x00000000, expected[17] = 0xCAFED00D, expected[18] = 0xFEEDFACE;
3129 expected[32] = 0x00000000, expected[33] = 0xFEDCBA98, expected[34] = 0x76543210;
3131 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3132 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3134 /* when dst width is 1 merge src width - 1 pixels */
3135 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
3136 srcBuffer[0] = 0x0000ff00, srcBuffer[1] = 0x0000f0f0, srcBuffer[2] = 0x0000cccc, srcBuffer[3] = 0x0000aaaa;
3137 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
3139 memset( expected, 0, get_dib_image_size( &biDst ) );
3140 expected[0] = srcBuffer[0];
3141 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3142 0, 0, 1, 1, 0, 0, 2, 1, expected, __LINE__);
3144 expected[0] = srcBuffer[0] & srcBuffer[1];
3145 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3146 0, 0, 1, 1, 0, 0, 3, 1, expected, __LINE__);
3148 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
3149 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3150 0, 0, 1, 1, 0, 0, 4, 1, expected, __LINE__);
3152 /* this doesn't happen if the src width is -ve */
3153 expected[0] = srcBuffer[1] & srcBuffer[2];
3154 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3155 0, 0, 1, 1, 2, 0, -2, 1, expected, __LINE__);
3157 /* when dst width > 1 behaviour reverts to what one would expect */
3158 expected[0] = srcBuffer[0] & srcBuffer[1], expected[1] = srcBuffer[2] & srcBuffer[3];
3159 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3160 0, 0, 2, 1, 0, 0, 4, 1, expected, __LINE__);
3162 /* similarly in the vertical direction */
3163 memset( expected, 0, get_dib_image_size( &biDst ) );
3164 expected[0] = srcBuffer[0];
3165 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3166 0, 0, 1, 1, 0, 0, 1, 2, expected, __LINE__);
3168 /* check that it's the dst size in device units that needs to be 1 */
3169 SetMapMode( hdcDst, MM_ISOTROPIC );
3170 SetWindowExtEx( hdcDst, 200, 200, NULL );
3171 SetViewportExtEx( hdcDst, 100, 100, NULL );
3173 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
3174 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3175 0, 0, 2, 2, 0, 0, 4, 1, expected, __LINE__);
3176 SetMapMode( hdcDst, MM_TEXT );
3178 SelectObject(hdcDst, oldDst);
3179 DeleteObject(bmpDst);
3181 /* Top-down to bottom-up tests */
3182 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
3183 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3184 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
3186 biDst.bmiHeader.biHeight = 16;
3187 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3189 oldDst = SelectObject(hdcDst, bmpDst);
3191 memset( expected, 0, get_dib_image_size( &biDst ) );
3193 expected[224] = 0xFEDCBA98, expected[225] = 0x76543210;
3194 expected[240] = 0xCAFED00D, expected[241] = 0xFEEDFACE;
3195 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3196 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3198 expected[224] = 0xFEEDFACE, expected[225] = 0xCAFED00D;
3199 expected[240] = 0x76543210, expected[241] = 0xFEDCBA98;
3200 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3201 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3203 SelectObject(hdcSrc, oldSrc);
3204 DeleteObject(bmpSrc);
3206 /* Bottom-up to bottom-up tests */
3207 biSrc.bmiHeader.biHeight = 16;
3208 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
3210 srcBuffer[224] = 0xCAFED00D, srcBuffer[225] = 0xFEEDFACE;
3211 srcBuffer[240] = 0xFEDCBA98, srcBuffer[241] = 0x76543210;
3212 oldSrc = SelectObject(hdcSrc, bmpSrc);
3214 memset( expected, 0, get_dib_image_size( &biDst ) );
3216 expected[224] = 0xCAFED00D, expected[225] = 0xFEEDFACE;
3217 expected[240] = 0xFEDCBA98, expected[241] = 0x76543210;
3218 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3219 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3221 expected[224] = 0x76543210, expected[225] = 0xFEDCBA98;
3222 expected[240] = 0xFEEDFACE, expected[241] = 0xCAFED00D;
3223 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3224 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3226 SelectObject(hdcDst, oldDst);
3227 DeleteObject(bmpDst);
3229 /* Bottom-up to top-down tests */
3230 biDst.bmiHeader.biHeight = -16;
3231 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3233 oldDst = SelectObject(hdcDst, bmpDst);
3235 memset( expected, 0, get_dib_image_size( &biDst ) );
3236 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3237 expected[16] = 0xCAFED00D, expected[17] = 0xFEEDFACE;
3238 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3239 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3241 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3242 expected[16] = 0x76543210, expected[17] = 0xFEDCBA98;
3243 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3244 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3246 SelectObject(hdcSrc, oldSrc);
3247 DeleteObject(bmpSrc);
3249 biSrc.bmiHeader.biHeight = -2;
3250 biSrc.bmiHeader.biBitCount = 24;
3251 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
3252 oldSrc = SelectObject(hdcSrc, bmpSrc);
3254 memset( expected, 0, get_dib_image_size( &biDst ) );
3255 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3256 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
3257 memcpy(dstBuffer, expected, 4 * sizeof(*dstBuffer));
3258 StretchBlt(hdcSrc, 0, 0, 4, 1, hdcDst, 0, 0, 4, 1, SRCCOPY );
3259 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
3260 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3261 expected[0] = 0x00EDFACE, expected[1] = 0x00FED00D;
3262 expected[2] = 0x00543210, expected[3] = 0x00DCBA98;
3263 ok(!memcmp(dstBuffer, expected, 16),
3264 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3265 expected[0], expected[1], expected[2], expected[3],
3266 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3268 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3269 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
3270 memcpy(srcBuffer, expected, 4 * sizeof(*dstBuffer));
3271 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
3272 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3273 expected[0] = 0x00EDFACE, expected[1] = 0x00D00DFE;
3274 expected[2] = 0x0010CAFE, expected[3] = 0x00765432;
3275 ok(!memcmp(dstBuffer, expected, 16),
3276 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3277 expected[0], expected[1], expected[2], expected[3],
3278 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3280 SelectObject(hdcSrc, oldSrc);
3281 DeleteObject(bmpSrc);
3283 biSrc.bmiHeader.biBitCount = 1;
3284 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
3285 oldSrc = SelectObject(hdcSrc, bmpSrc);
3286 *((DWORD *)colors + 0) = 0x123456;
3287 *((DWORD *)colors + 1) = 0x335577;
3288 SetDIBColorTable( hdcSrc, 0, 2, colors );
3289 srcBuffer[0] = 0x55555555;
3290 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
3291 SetTextColor( hdcDst, 0 );
3292 SetBkColor( hdcDst, 0 );
3293 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3294 expected[0] = expected[2] = 0x00123456;
3295 expected[1] = expected[3] = 0x00335577;
3296 ok(!memcmp(dstBuffer, expected, 16),
3297 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3298 expected[0], expected[1], expected[2], expected[3],
3299 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3301 SelectObject(hdcSrc, oldSrc);
3302 DeleteObject(bmpSrc);
3304 bmpSrc = CreateBitmap( 16, 16, 1, 1, 0 );
3305 oldSrc = SelectObject(hdcSrc, bmpSrc);
3306 SetPixel( hdcSrc, 0, 0, 0 );
3307 SetPixel( hdcSrc, 1, 0, 0xffffff );
3308 SetPixel( hdcSrc, 2, 0, 0xffffff );
3309 SetPixel( hdcSrc, 3, 0, 0 );
3310 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
3311 SetTextColor( hdcDst, RGB(0x22,0x44,0x66) );
3312 SetBkColor( hdcDst, RGB(0x65,0x43,0x21) );
3313 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3314 expected[0] = expected[3] = 0x00224466;
3315 expected[1] = expected[2] = 0x00654321;
3316 ok(!memcmp(dstBuffer, expected, 16),
3317 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3318 expected[0], expected[1], expected[2], expected[3],
3319 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3321 SelectObject(hdcSrc, oldSrc);
3322 DeleteObject(bmpSrc);
3326 SelectObject(hdcDst, oldDst);
3327 DeleteObject(bmpDst);
3330 DeleteDC(hdcScreen);
3333 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3334 DWORD dwRop, UINT32 expected, int line)
3336 const UINT32 buffer[2] = { 0xFEDCBA98, 0 };
3337 BITMAPINFO bitmapInfo;
3339 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3340 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3341 bitmapInfo.bmiHeader.biWidth = 2;
3342 bitmapInfo.bmiHeader.biHeight = 1;
3343 bitmapInfo.bmiHeader.biPlanes = 1;
3344 bitmapInfo.bmiHeader.biBitCount = 32;
3345 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3346 bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer);
3348 *dstBuffer = 0x89ABCDEF;
3350 StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop);
3351 ok(expected == *dstBuffer,
3352 "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
3353 dwRop, expected, *dstBuffer, line);
3356 static INT check_StretchDIBits_stretch( HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3357 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
3358 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
3359 UINT32 expected[4], int line)
3361 BITMAPINFO bitmapInfo;
3364 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3365 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3366 bitmapInfo.bmiHeader.biWidth = 2;
3367 bitmapInfo.bmiHeader.biHeight = -2;
3368 bitmapInfo.bmiHeader.biPlanes = 1;
3369 bitmapInfo.bmiHeader.biBitCount = 32;
3370 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3372 memset(dstBuffer, 0, 16);
3373 ret = StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
3374 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3375 srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
3376 ok(memcmp(dstBuffer, expected, 16) == 0,
3377 "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
3378 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
3379 expected[0], expected[1], expected[2], expected[3],
3380 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
3381 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3382 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
3386 static void test_StretchDIBits(void)
3390 HDC hdcScreen, hdcDst;
3391 UINT32 *dstBuffer, srcBuffer[4];
3392 HBRUSH hBrush, hOldBrush;
3397 memset(&biDst, 0, sizeof(BITMAPINFO));
3398 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3399 biDst.bmiHeader.biWidth = 2;
3400 biDst.bmiHeader.biHeight = -2;
3401 biDst.bmiHeader.biPlanes = 1;
3402 biDst.bmiHeader.biBitCount = 32;
3403 biDst.bmiHeader.biCompression = BI_RGB;
3405 hdcScreen = CreateCompatibleDC(0);
3406 hdcDst = CreateCompatibleDC(hdcScreen);
3409 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3411 oldDst = SelectObject(hdcDst, bmpDst);
3413 hBrush = CreateSolidBrush(0x012345678);
3414 hOldBrush = SelectObject(hdcDst, hBrush);
3416 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3417 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3418 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3419 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3420 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3421 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3422 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3423 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3424 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3425 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3426 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3427 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3428 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3429 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3430 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3432 SelectObject(hdcDst, hOldBrush);
3433 DeleteObject(hBrush);
3435 /* Top-down destination tests */
3436 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3437 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
3439 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
3440 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
3441 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3442 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3443 ok( ret == 2, "got ret %d\n", ret );
3445 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3446 expected[2] = 0x00000000, expected[3] = 0x00000000;
3447 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3448 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
3449 todo_wine ok( ret == 1, "got ret %d\n", ret );
3451 expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
3452 expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
3453 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3454 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
3455 ok( ret == 2, "got ret %d\n", ret );
3457 expected[0] = 0x42441000, expected[1] = 0x00000000;
3458 expected[2] = 0x00000000, expected[3] = 0x00000000;
3459 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3460 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
3461 ok( ret == 2, "got ret %d\n", ret );
3463 expected[0] = 0x00000000, expected[1] = 0x00000000;
3464 expected[2] = 0x00000000, expected[3] = 0x00000000;
3465 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3466 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3467 ok( ret == 0, "got ret %d\n", ret );
3469 expected[0] = 0x00000000, expected[1] = 0x00000000;
3470 expected[2] = 0x00000000, expected[3] = 0x00000000;
3471 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3472 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3473 ok( ret == 0, "got ret %d\n", ret );
3475 expected[0] = 0x00000000, expected[1] = 0x00000000;
3476 expected[2] = 0x00000000, expected[3] = 0x00000000;
3477 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3478 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
3479 ok( ret == 0, "got ret %d\n", ret );
3481 expected[0] = 0x00000000, expected[1] = 0x00000000;
3482 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
3483 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3484 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3485 ok( ret == 2, "got ret %d\n", ret );
3487 expected[0] = 0x00000000, expected[1] = 0x00000000;
3488 expected[2] = 0x00000000, expected[3] = 0x00000000;
3489 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3490 2, 2, 4, 4, 0, 0, 2, 2, expected, __LINE__);
3491 ok( ret == 2, "got ret %d\n", ret );
3493 expected[0] = 0x00000000, expected[1] = 0x00000000;
3494 expected[2] = 0x00000000, expected[3] = 0x00000000;
3495 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3496 -4, -4, 4, 4, 0, 0, 4, 4, expected, __LINE__);
3497 ok( ret == 2, "got ret %d\n", ret );
3499 SelectObject(hdcDst, oldDst);
3500 DeleteObject(bmpDst);
3502 /* Bottom up destination tests */
3503 biDst.bmiHeader.biHeight = 2;
3504 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3506 oldDst = SelectObject(hdcDst, bmpDst);
3508 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3509 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
3510 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3511 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3514 SelectObject(hdcDst, oldDst);
3515 DeleteObject(bmpDst);
3518 DeleteDC(hdcScreen);
3521 static void test_GdiAlphaBlend(void)
3532 BLENDFUNCTION blend;
3534 if (!pGdiAlphaBlend)
3536 win_skip("GdiAlphaBlend() is not implemented\n");
3540 hdcNull = GetDC(NULL);
3541 hdcDst = CreateCompatibleDC(hdcNull);
3542 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
3543 hdcSrc = CreateCompatibleDC(hdcNull);
3545 bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3546 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3547 bmi->bmiHeader.biHeight = 20;
3548 bmi->bmiHeader.biWidth = 20;
3549 bmi->bmiHeader.biBitCount = 32;
3550 bmi->bmiHeader.biPlanes = 1;
3551 bmi->bmiHeader.biCompression = BI_RGB;
3552 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3553 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3555 SelectObject(hdcDst, bmpDst);
3556 oldSrc = SelectObject(hdcSrc, bmpSrc);
3558 blend.BlendOp = AC_SRC_OVER;
3559 blend.BlendFlags = 0;
3560 blend.SourceConstantAlpha = 128;
3561 blend.AlphaFormat = 0;
3563 SetLastError(0xdeadbeef);
3564 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3565 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3567 SetLastError(0xdeadbeef);
3568 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3569 ok( !ret, "GdiAlphaBlend succeeded\n" );
3570 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3572 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3573 ok( !ret, "GdiAlphaBlend succeeded\n" );
3574 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend);
3575 ok( !ret, "GdiAlphaBlend succeeded\n" );
3576 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3577 ok( !ret, "GdiAlphaBlend succeeded\n" );
3578 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3579 ok( !ret, "GdiAlphaBlend succeeded\n" );
3581 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
3582 SetLastError(0xdeadbeef);
3583 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3584 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3585 SetLastError(0xdeadbeef);
3586 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3587 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3588 SetMapMode(hdcSrc, MM_ANISOTROPIC);
3589 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
3590 SetLastError(0xdeadbeef);
3591 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend);
3592 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3593 SetLastError(0xdeadbeef);
3594 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend);
3595 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3597 SetMapMode(hdcDst, MM_ANISOTROPIC);
3598 SetViewportExtEx(hdcDst, -1, -1, NULL);
3599 SetLastError(0xdeadbeef);
3600 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 50, 50, blend);
3602 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3603 SetLastError(0xdeadbeef);
3604 ret = pGdiAlphaBlend(hdcDst, -20, -20, 20, 20, hdcSrc, 0, -1, 50, 50, blend);
3605 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3606 SetLastError(0xdeadbeef);
3607 ret = pGdiAlphaBlend(hdcDst, -20, -20, -20, -20, hdcSrc, 0, -1, 50, 50, blend);
3608 ok( !ret, "GdiAlphaBlend succeeded\n" );
3609 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3610 SetLastError(0xdeadbeef);
3611 ret = pGdiAlphaBlend(hdcDst, -20, 0, -20, 20, hdcSrc, 0, -1, 50, 50, blend);
3612 ok( !ret, "GdiAlphaBlend succeeded\n" );
3613 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3614 SetLastError(0xdeadbeef);
3615 ret = pGdiAlphaBlend(hdcDst, 0, -20, 20, -20, hdcSrc, 0, -1, 50, 50, blend);
3616 ok( !ret, "GdiAlphaBlend succeeded\n" );
3617 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3618 SetMapMode(hdcDst, MM_TEXT);
3620 SetViewportExtEx(hdcSrc, -1, -1, NULL);
3621 SetLastError(0xdeadbeef);
3622 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, -30, -30, blend);
3623 ok( !ret, "GdiAlphaBlend succeeded\n" );
3624 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3625 SetLastError(0xdeadbeef);
3626 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, 30, -30, blend);
3627 ok( !ret, "GdiAlphaBlend succeeded\n" );
3628 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3629 SetLastError(0xdeadbeef);
3630 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, -30, 30, blend);
3631 ok( !ret, "GdiAlphaBlend succeeded\n" );
3632 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3633 SetLastError(0xdeadbeef);
3634 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, 30, 30, blend);
3635 ok( !ret, "GdiAlphaBlend succeeded\n" );
3636 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3637 SetLastError(0xdeadbeef);
3638 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 20, 20, 30, 30, blend);
3639 ok( !ret, "GdiAlphaBlend succeeded\n" );
3640 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3641 SetLastError(0xdeadbeef);
3642 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -60, -60, 30, 30, blend);
3643 ok( !ret, "GdiAlphaBlend succeeded\n" );
3644 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3645 SetViewportExtEx(hdcSrc, 1, 1, NULL);
3647 SetLastError(0xdeadbeef);
3648 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend);
3649 ok( !ret, "GdiAlphaBlend succeeded\n" );
3650 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3652 /* overlapping source and dest not allowed */
3654 SetLastError(0xdeadbeef);
3655 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 19, 19, 20, 20, blend);
3656 ok( !ret, "GdiAlphaBlend succeeded\n" );
3657 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3659 SetLastError(0xdeadbeef);
3660 ret = pGdiAlphaBlend(hdcDst, 20, 20, 20, 20, hdcDst, 1, 1, 20, 20, blend);
3661 ok( !ret, "GdiAlphaBlend succeeded\n" );
3662 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3664 SetLastError(0xdeadbeef);
3665 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 20, 10, 20, 20, blend);
3666 ok( ret, "GdiAlphaBlend succeeded\n" );
3667 SetLastError(0xdeadbeef);
3668 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 10, 20, 20, 20, blend);
3669 ok( ret, "GdiAlphaBlend succeeded\n" );
3671 /* AC_SRC_ALPHA requires 32-bpp BI_RGB format */
3673 blend.AlphaFormat = AC_SRC_ALPHA;
3674 SetLastError(0xdeadbeef);
3675 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3676 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3678 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3679 ((DWORD *)bmi->bmiColors)[0] = 0xff0000;
3680 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3681 ((DWORD *)bmi->bmiColors)[2] = 0x0000ff;
3682 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3683 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3684 oldSrc = SelectObject(hdcSrc, bmpSrc);
3685 DeleteObject( oldSrc );
3687 SetLastError(0xdeadbeef);
3688 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3689 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3691 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3692 ((DWORD *)bmi->bmiColors)[0] = 0x0000ff;
3693 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3694 ((DWORD *)bmi->bmiColors)[2] = 0xff0000;
3695 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3696 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3697 oldSrc = SelectObject(hdcSrc, bmpSrc);
3698 DeleteObject( oldSrc );
3700 SetLastError(0xdeadbeef);
3701 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3702 ok( !ret, "GdiAlphaBlend succeeded\n" );
3703 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3705 bmi->bmiHeader.biBitCount = 24;
3706 bmi->bmiHeader.biCompression = BI_RGB;
3707 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3708 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3709 oldSrc = SelectObject(hdcSrc, bmpSrc);
3710 DeleteObject( oldSrc );
3712 SetLastError(0xdeadbeef);
3713 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3714 ok( !ret, "GdiAlphaBlend succeeded\n" );
3715 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3717 bmi->bmiHeader.biBitCount = 1;
3718 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3719 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3720 oldSrc = SelectObject(hdcSrc, bmpSrc);
3721 DeleteObject( oldSrc );
3723 SetLastError(0xdeadbeef);
3724 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3725 ok( !ret, "GdiAlphaBlend succeeded\n" );
3726 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3728 bmpSrc = CreateBitmap( 100, 100, 1, 1, NULL );
3729 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3730 oldSrc = SelectObject(hdcSrc, bmpSrc);
3731 DeleteObject( oldSrc );
3733 SetLastError(0xdeadbeef);
3734 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3735 ok( !ret, "GdiAlphaBlend succeeded\n" );
3736 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3740 DeleteObject(bmpSrc);
3741 DeleteObject(bmpDst);
3743 ReleaseDC(NULL, hdcNull);
3747 static void test_GdiGradientFill(void)
3754 GRADIENT_RECT rect[] = { { 0, 0 }, { 0, 1 }, { 2, 3 } };
3755 GRADIENT_TRIANGLE tri[] = { { 0, 0, 0 }, { 0, 1, 2 }, { 0, 2, 1 }, { 0, 1, 3 } };
3756 TRIVERTEX vt[3] = { { 2, 2, 0xff00, 0x0000, 0x0000, 0x8000 },
3757 { 10, 10, 0x0000, 0xff00, 0x0000, 0x8000 },
3758 { 20, 10, 0x0000, 0x0000, 0xff00, 0xff00 } };
3760 if (!pGdiGradientFill)
3762 win_skip( "GdiGradientFill is not implemented\n" );
3766 hdc = CreateCompatibleDC( NULL );
3767 bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3768 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3769 bmi->bmiHeader.biHeight = 20;
3770 bmi->bmiHeader.biWidth = 20;
3771 bmi->bmiHeader.biBitCount = 32;
3772 bmi->bmiHeader.biPlanes = 1;
3773 bmi->bmiHeader.biCompression = BI_RGB;
3774 bmp = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3775 ok( bmp != NULL, "couldn't create bitmap\n" );
3776 SelectObject( hdc, bmp );
3778 SetLastError( 0xdeadbeef );
3779 ret = pGdiGradientFill( hdc, vt, 3, rect, 1, GRADIENT_FILL_RECT_H );
3780 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3781 SetLastError( 0xdeadbeef );
3782 ret = pGdiGradientFill( hdc, vt, 3, rect, 1, 3 );
3783 ok( !ret, "GdiGradientFill succeeded\n" );
3784 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3785 SetLastError( 0xdeadbeef );
3786 ret = pGdiGradientFill( (HDC)0xdead, vt, 3, rect, 1, GRADIENT_FILL_RECT_H );
3787 ok( !ret, "GdiGradientFill succeeded\n" );
3788 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3789 SetLastError( 0xdeadbeef );
3790 ret = pGdiGradientFill( NULL, NULL, 0, rect, 1, GRADIENT_FILL_RECT_H );
3791 ok( !ret, "GdiGradientFill succeeded\n" );
3792 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3793 ret = pGdiGradientFill( hdc, NULL, 0, rect, 1, GRADIENT_FILL_RECT_H );
3794 ok( !ret, "GdiGradientFill succeeded\n" );
3795 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3796 SetLastError( 0xdeadbeef );
3797 ret = pGdiGradientFill( hdc, NULL, 3, rect, 1, GRADIENT_FILL_RECT_H );
3798 ok( !ret, "GdiGradientFill succeeded\n" );
3799 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3800 SetLastError( 0xdeadbeef );
3801 ret = pGdiGradientFill( hdc, vt, 3, NULL, 0, GRADIENT_FILL_RECT_H );
3802 ok( !ret, "GdiGradientFill succeeded\n" );
3803 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3804 SetLastError( 0xdeadbeef );
3805 ret = pGdiGradientFill( hdc, vt, 3, NULL, 1, GRADIENT_FILL_RECT_H );
3806 ok( !ret, "GdiGradientFill succeeded\n" );
3807 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3808 SetLastError( 0xdeadbeef );
3809 ret = pGdiGradientFill( hdc, vt, 3, rect, 0, GRADIENT_FILL_RECT_H );
3810 ok( !ret, "GdiGradientFill succeeded\n" );
3811 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3812 SetLastError( 0xdeadbeef );
3813 ret = pGdiGradientFill( hdc, vt, 3, rect, 3, GRADIENT_FILL_RECT_H );
3814 ok( !ret, "GdiGradientFill succeeded\n" );
3815 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3816 rect[2].UpperLeft = rect[2].LowerRight = 1;
3817 SetLastError( 0xdeadbeef );
3818 ret = pGdiGradientFill( hdc, vt, 3, rect, 3, GRADIENT_FILL_RECT_H );
3819 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3820 SetLastError( 0xdeadbeef );
3821 ret = pGdiGradientFill( hdc, vt, 1, rect, 1, GRADIENT_FILL_RECT_H );
3822 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3823 SetLastError( 0xdeadbeef );
3824 ret = pGdiGradientFill( hdc, vt, 1, tri, 0, GRADIENT_FILL_TRIANGLE );
3825 ok( !ret, "GdiGradientFill succeeded\n" );
3826 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3827 SetLastError( 0xdeadbeef );
3828 ret = pGdiGradientFill( hdc, vt, 1, tri, 1, GRADIENT_FILL_TRIANGLE );
3829 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3830 SetLastError( 0xdeadbeef );
3831 ret = pGdiGradientFill( hdc, vt, 3, tri, 2, GRADIENT_FILL_TRIANGLE );
3832 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3833 SetLastError( 0xdeadbeef );
3834 ret = pGdiGradientFill( hdc, vt, 3, tri, 3, GRADIENT_FILL_TRIANGLE );
3835 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3836 SetLastError( 0xdeadbeef );
3837 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3838 ok( !ret, "GdiGradientFill succeeded\n" );
3839 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3841 SetLastError( 0xdeadbeef );
3842 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3843 ok( !ret, "GdiGradientFill succeeded\n" );
3844 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3846 SetLastError( 0xdeadbeef );
3847 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3848 ok( !ret, "GdiGradientFill succeeded\n" );
3849 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3850 tri[3].Vertex1 = tri[3].Vertex2 = tri[3].Vertex3 = 1;
3851 SetLastError( 0xdeadbeef );
3852 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3853 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3856 DeleteObject( bmp );
3859 static void test_clipping(void)
3867 HDC hdcDst = CreateCompatibleDC( NULL );
3868 HDC hdcSrc = CreateCompatibleDC( NULL );
3870 BITMAPINFO bmpinfo={{0}};
3871 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3872 bmpinfo.bmiHeader.biWidth = 100;
3873 bmpinfo.bmiHeader.biHeight = 100;
3874 bmpinfo.bmiHeader.biPlanes = 1;
3875 bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3876 bmpinfo.bmiHeader.biCompression = BI_RGB;
3878 bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3879 ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3880 SelectObject( hdcDst, bmpDst );
3882 bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3883 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3884 SelectObject( hdcSrc, bmpSrc );
3886 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3887 ok(result, "BitBlt failed\n");
3889 hRgn = CreateRectRgn( 0,0,0,0 );
3890 SelectClipRgn( hdcDst, hRgn );
3892 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3893 ok(result, "BitBlt failed\n");
3895 DeleteObject( bmpDst );
3896 DeleteObject( bmpSrc );
3897 DeleteObject( hRgn );
3902 static void test_32bit_ddb(void)
3904 char buffer[sizeof(BITMAPINFOHEADER) + sizeof(DWORD)];
3905 BITMAPINFO *biDst = (BITMAPINFO *)buffer;
3906 HBITMAP bmpSrc, bmpDst;
3907 HBITMAP oldSrc, oldDst;
3908 HDC hdcSrc, hdcDst, hdcScreen;
3910 DWORD *dstBuffer, *data;
3911 DWORD colorSrc = 0x40201008;
3913 memset(biDst, 0, sizeof(BITMAPINFOHEADER));
3914 biDst->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3915 biDst->bmiHeader.biWidth = 1;
3916 biDst->bmiHeader.biHeight = -1;
3917 biDst->bmiHeader.biPlanes = 1;
3918 biDst->bmiHeader.biBitCount = 32;
3919 biDst->bmiHeader.biCompression = BI_RGB;
3921 hdcScreen = CreateCompatibleDC(0);
3922 if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3924 DeleteDC(hdcScreen);
3925 trace("Skipping 32-bit DDB test\n");
3929 hdcSrc = CreateCompatibleDC(hdcScreen);
3930 bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3931 oldSrc = SelectObject(hdcSrc, bmpSrc);
3933 hdcDst = CreateCompatibleDC(hdcScreen);
3934 bmpDst = CreateDIBSection(hdcDst, biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3935 oldDst = SelectObject(hdcDst, bmpDst);
3937 StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3938 ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3942 BLENDFUNCTION blend;
3945 blend.BlendOp = AC_SRC_OVER;
3946 blend.BlendFlags = 0;
3947 blend.SourceConstantAlpha = 128;
3948 blend.AlphaFormat = 0;
3949 dstBuffer[0] = 0x80808080;
3950 ret = pGdiAlphaBlend( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, blend );
3951 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3952 ok(dstBuffer[0] == 0x60504844, "wrong color %x\n", dstBuffer[0]);
3953 blend.AlphaFormat = AC_SRC_ALPHA;
3954 dstBuffer[0] = 0x80808080;
3955 ret = pGdiAlphaBlend( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, blend );
3956 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3957 ok(dstBuffer[0] == 0x90807874, "wrong color %x\n", dstBuffer[0]);
3960 data = (DWORD *)biDst->bmiColors;
3961 data[0] = 0x20304050;
3962 brush = CreateDIBPatternBrushPt( biDst, DIB_RGB_COLORS );
3963 ok( brush != 0, "brush creation failed\n" );
3964 SelectObject( hdcSrc, brush );
3965 PatBlt( hdcSrc, 0, 0, 1, 1, PATCOPY );
3966 BitBlt( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, SRCCOPY );
3967 ok(dstBuffer[0] == data[0], "Expected color=%x, received color=%x\n", data[0], dstBuffer[0]);
3968 SelectObject( hdcSrc, GetStockObject(BLACK_BRUSH) );
3969 DeleteObject( brush );
3971 biDst->bmiHeader.biBitCount = 24;
3972 brush = CreateDIBPatternBrushPt( biDst, DIB_RGB_COLORS );
3973 ok( brush != 0, "brush creation failed\n" );
3974 SelectObject( hdcSrc, brush );
3975 PatBlt( hdcSrc, 0, 0, 1, 1, PATCOPY );
3976 BitBlt( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, SRCCOPY );
3977 ok(dstBuffer[0] == (data[0] & ~0xff000000),
3978 "Expected color=%x, received color=%x\n", data[0] & 0xff000000, dstBuffer[0]);
3979 SelectObject( hdcSrc, GetStockObject(BLACK_BRUSH) );
3980 DeleteObject( brush );
3983 SelectObject(hdcDst, oldDst);
3984 DeleteObject(bmpDst);
3987 SelectObject(hdcSrc, oldSrc);
3988 DeleteObject(bmpSrc);
3991 DeleteDC(hdcScreen);
3995 * Used by test_GetDIBits_top_down to create the bitmap to test against.
3997 static void setup_picture(char *picture, int bpp)
4005 /*Set the first byte in each pixel to the index of that pixel.*/
4006 for (i = 0; i < 4; i++)
4007 picture[i * (bpp / 8)] = i;
4012 /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
4019 static void test_GetDIBits_top_down(int bpp)
4022 HBITMAP bmptb, bmpbt;
4028 memset( &bi, 0, sizeof(bi) );
4029 bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
4030 bi.bmiHeader.biWidth=2;
4031 bi.bmiHeader.biHeight=2;
4032 bi.bmiHeader.biPlanes=1;
4033 bi.bmiHeader.biBitCount=bpp;
4034 bi.bmiHeader.biCompression=BI_RGB;
4036 /*Get the device context for the screen.*/
4038 ok(hdc != NULL, "Could not get a handle to a device context.\n");
4040 /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
4041 bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
4042 ok(bmpbt != NULL, "Could not create a DIB section.\n");
4043 /*Now that we have a pointer to the pixels, we write to them.*/
4044 setup_picture((char*)picture, bpp);
4045 /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
4046 bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
4047 bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
4048 ok(bmptb != NULL, "Could not create a DIB section.\n");
4049 /*Write to this top to bottom bitmap.*/
4050 setup_picture((char*)picture, bpp);
4052 bi.bmiHeader.biWidth = 1;
4054 bi.bmiHeader.biHeight = 2;
4055 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
4056 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4057 /*Check the first byte of the pixel.*/
4058 ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
4059 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
4060 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4061 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
4062 /*Check second scanline.*/
4063 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
4064 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4065 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
4066 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
4067 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4068 ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
4069 /*Check both scanlines.*/
4070 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
4071 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4072 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
4073 ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
4074 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
4075 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4076 ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
4077 ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
4079 /*Make destination bitmap top-down.*/
4080 bi.bmiHeader.biHeight = -2;
4081 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
4082 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4083 ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
4084 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
4085 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4086 ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
4087 /*Check second scanline.*/
4088 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
4089 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4090 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
4091 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
4092 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4093 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
4094 /*Check both scanlines.*/
4095 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
4096 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4097 ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
4098 ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
4099 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
4100 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4101 ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
4102 ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
4104 DeleteObject(bmpbt);
4105 DeleteObject(bmptb);
4108 static void test_GetSetDIBits_rtl(void)
4111 HBITMAP bitmap, orig_bitmap;
4114 DWORD bits_1[8 * 8], bits_2[8 * 8];
4118 win_skip("Don't have SetLayout\n");
4122 hdc = GetDC( NULL );
4123 hdc_mem = CreateCompatibleDC( hdc );
4124 pSetLayout( hdc_mem, LAYOUT_LTR );
4126 bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
4127 orig_bitmap = SelectObject( hdc_mem, bitmap );
4128 SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
4129 SelectObject( hdc_mem, orig_bitmap );
4131 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
4132 info.bmiHeader.biWidth = 8;
4133 info.bmiHeader.biHeight = 8;
4134 info.bmiHeader.biPlanes = 1;
4135 info.bmiHeader.biBitCount = 32;
4136 info.bmiHeader.biCompression = BI_RGB;
4138 /* First show that GetDIBits ignores the layout mode. */
4140 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
4141 ok(ret == 8, "got %d\n", ret);
4142 ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
4144 pSetLayout( hdc_mem, LAYOUT_RTL );
4146 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
4147 ok(ret == 8, "got %d\n", ret);
4149 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
4151 /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
4152 followed by a GetDIBits and show that the bits remain unchanged. */
4154 pSetLayout( hdc_mem, LAYOUT_LTR );
4156 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
4157 ok(ret == 8, "got %d\n", ret);
4158 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
4159 ok(ret == 8, "got %d\n", ret);
4160 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
4162 pSetLayout( hdc_mem, LAYOUT_RTL );
4164 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
4165 ok(ret == 8, "got %d\n", ret);
4166 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
4167 ok(ret == 8, "got %d\n", ret);
4168 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
4170 DeleteObject( bitmap );
4171 DeleteDC( hdc_mem );
4172 ReleaseDC( NULL, hdc );
4175 static void test_GetDIBits_scanlines(void)
4179 HDC hdc = GetDC( NULL );
4181 DWORD data[128], inverted_bits[64];
4184 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4186 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4187 info->bmiHeader.biWidth = 8;
4188 info->bmiHeader.biHeight = 8;
4189 info->bmiHeader.biPlanes = 1;
4190 info->bmiHeader.biBitCount = 32;
4191 info->bmiHeader.biCompression = BI_RGB;
4193 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4195 for (i = 0; i < 64; i++)
4198 inverted_bits[56 - (i & ~7) + (i & 7)] = i;
4203 memset( data, 0xaa, sizeof(data) );
4205 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4206 ok( ret == 8, "got %d\n", ret );
4207 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4208 memset( data, 0xaa, sizeof(data) );
4210 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4211 ok( ret == 5, "got %d\n", ret );
4212 ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
4213 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4214 memset( data, 0xaa, sizeof(data) );
4216 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4217 ok( ret == 7, "got %d\n", ret );
4218 ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
4219 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4220 memset( data, 0xaa, sizeof(data) );
4222 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4223 ok( ret == 1, "got %d\n", ret );
4224 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4225 memset( data, 0xaa, sizeof(data) );
4227 info->bmiHeader.biHeight = 16;
4228 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4229 ok( ret == 5, "got %d\n", ret );
4230 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4231 ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
4232 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4233 memset( data, 0xaa, sizeof(data) );
4235 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
4236 ok( ret == 6, "got %d\n", ret );
4237 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4238 ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
4239 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4240 memset( data, 0xaa, sizeof(data) );
4242 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
4243 ok( ret == 0, "got %d\n", ret );
4244 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4245 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4246 memset( data, 0xaa, sizeof(data) );
4248 info->bmiHeader.biHeight = 5;
4249 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4250 ok( ret == 2, "got %d\n", ret );
4251 ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
4252 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4253 memset( data, 0xaa, sizeof(data) );
4257 info->bmiHeader.biHeight = -8;
4258 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4259 ok( ret == 8, "got %d\n", ret );
4260 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4261 memset( data, 0xaa, sizeof(data) );
4263 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4264 ok( ret == 5, "got %d\n", ret );
4265 ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
4266 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4267 memset( data, 0xaa, sizeof(data) );
4269 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4270 ok( ret == 7, "got %d\n", ret );
4271 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
4272 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4273 memset( data, 0xaa, sizeof(data) );
4275 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4276 ok( ret == 4, "got %d\n", ret );
4277 ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
4278 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4279 memset( data, 0xaa, sizeof(data) );
4281 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
4282 ok( ret == 5, "got %d\n", ret );
4283 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
4284 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4285 memset( data, 0xaa, sizeof(data) );
4287 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
4288 ok( ret == 5, "got %d\n", ret );
4289 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
4290 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4291 memset( data, 0xaa, sizeof(data) );
4293 info->bmiHeader.biHeight = -16;
4294 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
4295 ok( ret == 8, "got %d\n", ret );
4296 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4297 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4298 memset( data, 0xaa, sizeof(data) );
4300 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4301 ok( ret == 5, "got %d\n", ret );
4302 ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
4303 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4304 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4305 memset( data, 0xaa, sizeof(data) );
4307 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4308 ok( ret == 8, "got %d\n", ret );
4309 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4310 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4311 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4312 memset( data, 0xaa, sizeof(data) );
4314 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4315 ok( ret == 8, "got %d\n", ret );
4316 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4317 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4318 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4319 memset( data, 0xaa, sizeof(data) );
4321 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4322 ok( ret == 7, "got %d\n", ret );
4323 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
4324 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4325 memset( data, 0xaa, sizeof(data) );
4327 ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
4328 ok( ret == 1, "got %d\n", ret );
4329 for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4330 memset( data, 0xaa, sizeof(data) );
4332 info->bmiHeader.biHeight = -5;
4333 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4334 ok( ret == 2, "got %d\n", ret );
4335 ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
4336 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4337 memset( data, 0xaa, sizeof(data) );
4339 DeleteObject( dib );
4341 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4342 info->bmiHeader.biWidth = 8;
4343 info->bmiHeader.biHeight = -8;
4344 info->bmiHeader.biPlanes = 1;
4345 info->bmiHeader.biBitCount = 32;
4346 info->bmiHeader.biCompression = BI_RGB;
4348 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4350 for (i = 0; i < 64; i++) dib_bits[i] = i;
4354 info->bmiHeader.biHeight = -8;
4355 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4356 ok( ret == 8, "got %d\n", ret );
4357 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4358 memset( data, 0xaa, sizeof(data) );
4360 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4361 ok( ret == 5, "got %d\n", ret );
4362 ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
4363 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4364 memset( data, 0xaa, sizeof(data) );
4366 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4367 ok( ret == 7, "got %d\n", ret );
4368 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
4369 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4370 memset( data, 0xaa, sizeof(data) );
4372 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4373 ok( ret == 4, "got %d\n", ret );
4374 ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
4375 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4376 memset( data, 0xaa, sizeof(data) );
4378 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
4379 ok( ret == 5, "got %d\n", ret );
4380 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
4381 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4382 memset( data, 0xaa, sizeof(data) );
4384 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
4385 ok( ret == 5, "got %d\n", ret );
4386 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
4387 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4388 memset( data, 0xaa, sizeof(data) );
4390 info->bmiHeader.biHeight = -16;
4391 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
4392 ok( ret == 8, "got %d\n", ret );
4393 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4394 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4395 memset( data, 0xaa, sizeof(data) );
4397 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4398 ok( ret == 5, "got %d\n", ret );
4399 ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
4400 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4401 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4402 memset( data, 0xaa, sizeof(data) );
4404 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4405 ok( ret == 8, "got %d\n", ret );
4406 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4407 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4408 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4409 memset( data, 0xaa, sizeof(data) );
4411 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4412 ok( ret == 8, "got %d\n", ret );
4413 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4414 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4415 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4416 memset( data, 0xaa, sizeof(data) );
4418 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4419 ok( ret == 7, "got %d\n", ret );
4420 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
4421 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4422 memset( data, 0xaa, sizeof(data) );
4424 info->bmiHeader.biHeight = -5;
4425 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4426 ok( ret == 2, "got %d\n", ret );
4427 ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
4428 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4429 memset( data, 0xaa, sizeof(data) );
4434 info->bmiHeader.biHeight = 8;
4436 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4437 ok( ret == 8, "got %d\n", ret );
4438 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4439 memset( data, 0xaa, sizeof(data) );
4441 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4442 ok( ret == 5, "got %d\n", ret );
4443 ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
4444 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4445 memset( data, 0xaa, sizeof(data) );
4447 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4448 ok( ret == 7, "got %d\n", ret );
4449 ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
4450 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4451 memset( data, 0xaa, sizeof(data) );
4453 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4454 ok( ret == 1, "got %d\n", ret );
4455 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4456 memset( data, 0xaa, sizeof(data) );
4458 info->bmiHeader.biHeight = 16;
4459 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4460 ok( ret == 5, "got %d\n", ret );
4461 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4462 ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
4463 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4464 memset( data, 0xaa, sizeof(data) );
4466 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
4467 ok( ret == 6, "got %d\n", ret );
4468 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4469 ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
4470 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4471 memset( data, 0xaa, sizeof(data) );
4473 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
4474 ok( ret == 0, "got %d\n", ret );
4475 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4476 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4477 memset( data, 0xaa, sizeof(data) );
4479 info->bmiHeader.biHeight = 5;
4480 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4481 ok( ret == 2, "got %d\n", ret );
4482 ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
4483 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4484 memset( data, 0xaa, sizeof(data) );
4486 DeleteObject( dib );
4488 ReleaseDC( NULL, hdc );
4489 HeapFree( GetProcessHeap(), 0, info );
4493 static void test_SetDIBits(void)
4495 char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
4496 LOGPALETTE *pal = (LOGPALETTE *)palbuf;
4497 PALETTEENTRY *palent = pal->palPalEntry;
4501 HDC hdc = GetDC( NULL );
4502 DWORD data[128], inverted_data[128];
4506 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4508 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4509 info->bmiHeader.biWidth = 8;
4510 info->bmiHeader.biHeight = 8;
4511 info->bmiHeader.biPlanes = 1;
4512 info->bmiHeader.biBitCount = 32;
4513 info->bmiHeader.biCompression = BI_RGB;
4515 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4516 memset( dib_bits, 0xaa, 64 * 4 );
4518 for (i = 0; i < 128; i++)
4521 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4526 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4527 ok( ret == 8, "got %d\n", ret );
4528 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4529 memset( dib_bits, 0xaa, 64 * 4 );
4531 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4532 ok( ret == 5, "got %d\n", ret );
4533 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4534 ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
4535 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4536 memset( dib_bits, 0xaa, 64 * 4 );
4538 /* top of dst is aligned with startscans down for the top of the src.
4539 Then starting from the bottom of src, lines rows are copied across. */
4541 info->bmiHeader.biHeight = 16;
4542 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4543 ok( ret == 12, "got %d\n", ret );
4544 ok( !memcmp( dib_bits, data + 56, 40 * 4 ), "bits differ\n");
4545 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4546 memset( dib_bits, 0xaa, 64 * 4 );
4548 info->bmiHeader.biHeight = 5;
4549 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4550 ok( ret == 2, "got %d\n", ret );
4551 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4552 ok( !memcmp( dib_bits + 32, data, 16 * 4 ), "bits differ\n");
4553 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4554 memset( dib_bits, 0xaa, 64 * 4 );
4557 info->bmiHeader.biHeight = -8;
4558 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4559 ok( ret == 8, "got %d\n", ret );
4560 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4561 memset( dib_bits, 0xaa, 64 * 4 );
4563 /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
4564 we copy lines rows from the top of the src */
4566 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4567 ok( ret == 5, "got %d\n", ret );
4568 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4569 ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
4570 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4571 memset( dib_bits, 0xaa, 64 * 4 );
4573 info->bmiHeader.biHeight = -16;
4574 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4575 ok( ret == 12, "got %d\n", ret );
4576 ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
4577 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4578 memset( dib_bits, 0xaa, 64 * 4 );
4580 ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4581 ok( ret == 12, "got %d\n", ret );
4582 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4583 memset( dib_bits, 0xaa, 64 * 4 );
4585 ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4586 ok( ret == 12, "got %d\n", ret );
4587 ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
4588 memset( dib_bits, 0xaa, 64 * 4 );
4590 info->bmiHeader.biHeight = -5;
4591 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4592 ok( ret == 2, "got %d\n", ret );
4593 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4594 ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
4595 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4596 memset( dib_bits, 0xaa, 64 * 4 );
4598 DeleteObject( dib );
4600 info->bmiHeader.biHeight = -8;
4602 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4603 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4607 /* like the t-d -> b-u case. */
4609 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4610 ok( ret == 8, "got %d\n", ret );
4611 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4612 memset( dib_bits, 0xaa, 64 * 4 );
4614 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4615 ok( ret == 5, "got %d\n", ret );
4616 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4617 ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
4618 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4619 memset( dib_bits, 0xaa, 64 * 4 );
4621 info->bmiHeader.biHeight = -16;
4622 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4623 ok( ret == 12, "got %d\n", ret );
4624 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4625 ok( !memcmp( dib_bits + 24, data, 40 * 4 ), "bits differ\n");
4626 memset( dib_bits, 0xaa, 64 * 4 );
4628 info->bmiHeader.biHeight = -5;
4629 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4630 ok( ret == 2, "got %d\n", ret );
4631 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4632 ok( !memcmp( dib_bits + 16, data, 16 * 4 ), "bits differ\n");
4633 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4634 memset( dib_bits, 0xaa, 64 * 4 );
4637 /* like the b-u -> b-u case */
4639 info->bmiHeader.biHeight = 8;
4640 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4641 ok( ret == 8, "got %d\n", ret );
4642 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4643 memset( dib_bits, 0xaa, 64 * 4 );
4645 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4646 ok( ret == 5, "got %d\n", ret );
4647 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4648 ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
4649 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4650 memset( dib_bits, 0xaa, 64 * 4 );
4652 info->bmiHeader.biHeight = 16;
4653 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4654 ok( ret == 12, "got %d\n", ret );
4655 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4656 ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
4657 memset( dib_bits, 0xaa, 64 * 4 );
4659 info->bmiHeader.biHeight = 5;
4660 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4661 ok( ret == 2, "got %d\n", ret );
4662 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4663 ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
4664 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4665 memset( dib_bits, 0xaa, 64 * 4 );
4667 /* handling of partial color table */
4669 info->bmiHeader.biHeight = -8;
4670 info->bmiHeader.biBitCount = 8;
4671 info->bmiHeader.biClrUsed = 137;
4672 for (i = 0; i < 256; i++)
4674 info->bmiColors[i].rgbRed = 255 - i;
4675 info->bmiColors[i].rgbGreen = i * 2;
4676 info->bmiColors[i].rgbBlue = i;
4677 info->bmiColors[i].rgbReserved = 0;
4679 for (i = 0; i < 64; i++) ((BYTE *)data)[i] = i * 4 + 1;
4680 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4681 ok( ret == 8, "got %d\n", ret );
4682 for (i = 0; i < 64; i++)
4684 int idx = i * 4 + 1;
4685 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : (info->bmiColors[idx].rgbRed << 16 |
4686 info->bmiColors[idx].rgbGreen << 8 |
4687 info->bmiColors[idx].rgbBlue);
4688 ok( dib_bits[i] == expect, "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
4690 memset( dib_bits, 0xaa, 64 * 4 );
4692 /* handling of DIB_PAL_COLORS */
4694 pal->palVersion = 0x300;
4695 pal->palNumEntries = 137;
4696 info->bmiHeader.biClrUsed = 221;
4697 for (i = 0; i < 256; i++)
4699 palent[i].peRed = i * 2;
4700 palent[i].peGreen = 255 - i;
4701 palent[i].peBlue = i;
4703 palette = CreatePalette( pal );
4704 ok( palette != 0, "palette creation failed\n" );
4705 SelectPalette( hdc, palette, FALSE );
4706 for (i = 0; i < 256; i++) ((WORD *)info->bmiColors)[i] = 255 - i;
4707 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_PAL_COLORS );
4708 ok( ret == 8, "got %d\n", ret );
4709 for (i = 0; i < 64; i++)
4711 int idx = i * 4 + 1;
4712 int ent = (255 - idx) % pal->palNumEntries;
4713 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 :
4714 (palent[ent].peRed << 16 | palent[ent].peGreen << 8 | palent[ent].peBlue);
4715 ok( dib_bits[i] == expect || broken(dib_bits[i] == 0), /* various Windows versions get some values wrong */
4716 "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
4718 memset( dib_bits, 0xaa, 64 * 4 );
4720 ReleaseDC( NULL, hdc );
4721 DeleteObject( dib );
4722 DeleteObject( palette );
4723 HeapFree( GetProcessHeap(), 0, info );
4726 static void test_SetDIBits_RLE4(void)
4730 HDC hdc = GetDC( NULL );
4731 BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00, /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
4732 0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
4733 0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00, /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
4734 0x00, 0x02, 0x01, 0x02, 0x05, 0x87, /* dx=1, dy=2, 8, 7, 8, 7, 8 */
4735 0x00, 0x01 }; /* <eod> */
4738 DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
4739 0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
4740 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4741 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4742 0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
4743 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4744 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4745 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4747 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4749 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4750 info->bmiHeader.biWidth = 8;
4751 info->bmiHeader.biHeight = 8;
4752 info->bmiHeader.biPlanes = 1;
4753 info->bmiHeader.biBitCount = 32;
4754 info->bmiHeader.biCompression = BI_RGB;
4756 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4757 memset( dib_bits, 0xaa, 64 * 4 );
4759 info->bmiHeader.biBitCount = 4;
4760 info->bmiHeader.biCompression = BI_RLE4;
4761 info->bmiHeader.biSizeImage = sizeof(rle4_data);
4763 for (i = 0; i < 16; i++)
4765 info->bmiColors[i].rgbRed = i;
4766 info->bmiColors[i].rgbGreen = i;
4767 info->bmiColors[i].rgbBlue = i;
4768 info->bmiColors[i].rgbReserved = 0;
4771 ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
4772 ok( ret == 8, "got %d\n", ret );
4773 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
4774 memset( dib_bits, 0xaa, 64 * 4 );
4776 DeleteObject( dib );
4777 ReleaseDC( NULL, hdc );
4778 HeapFree( GetProcessHeap(), 0, info );
4781 static void test_SetDIBits_RLE8(void)
4785 HDC hdc = GetDC( NULL );
4786 BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00, /* 2, 2, 2, f0, f0, f0, f0, <eol> */
4787 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4788 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4789 0x00, 0x01 }; /* <eod> */
4792 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4793 0x00040404, 0x00050505, 0x00060606, 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 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4798 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4799 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4800 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4801 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4802 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4803 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4804 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4805 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4806 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4807 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4809 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4811 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4812 info->bmiHeader.biWidth = 8;
4813 info->bmiHeader.biHeight = 8;
4814 info->bmiHeader.biPlanes = 1;
4815 info->bmiHeader.biBitCount = 32;
4816 info->bmiHeader.biCompression = BI_RGB;
4818 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4819 memset( dib_bits, 0xaa, 64 * 4 );
4821 info->bmiHeader.biBitCount = 8;
4822 info->bmiHeader.biCompression = BI_RLE8;
4823 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4825 for (i = 0; i < 256; i++)
4827 info->bmiColors[i].rgbRed = i;
4828 info->bmiColors[i].rgbGreen = i;
4829 info->bmiColors[i].rgbBlue = i;
4830 info->bmiColors[i].rgbReserved = 0;
4833 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4834 ok( ret == 8, "got %d\n", ret );
4835 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4836 memset( dib_bits, 0xaa, 64 * 4 );
4838 /* startscan and lines are ignored, unless lines == 0 */
4839 ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4840 ok( ret == 8, "got %d\n", ret );
4841 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4842 memset( dib_bits, 0xaa, 64 * 4 );
4844 ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4845 ok( ret == 8, "got %d\n", ret );
4846 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4847 memset( dib_bits, 0xaa, 64 * 4 );
4849 ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4850 ok( ret == 0, "got %d\n", ret );
4851 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4852 memset( dib_bits, 0xaa, 64 * 4 );
4854 /* reduce width to 4, left-hand side of dst is touched. */
4855 info->bmiHeader.biWidth = 4;
4856 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4857 ok( ret == 8, "got %d\n", ret );
4858 for (i = 0; i < 64; i++)
4860 DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4861 ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4863 memset( dib_bits, 0xaa, 64 * 4 );
4865 /* Show that the top lines are aligned by adjusting the height of the src */
4867 /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4868 info->bmiHeader.biWidth = 8;
4869 info->bmiHeader.biHeight = 4;
4870 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4871 ok( ret == 4, "got %d\n", ret );
4872 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4873 ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4874 memset( dib_bits, 0xaa, 64 * 4 );
4876 /* increase the height to 9 -> everything moves down one row. */
4877 info->bmiHeader.biHeight = 9;
4878 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4879 ok( ret == 9, "got %d\n", ret );
4880 ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4881 for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4882 memset( dib_bits, 0xaa, 64 * 4 );
4884 /* top-down compressed dibs are invalid */
4885 info->bmiHeader.biHeight = -8;
4886 SetLastError( 0xdeadbeef );
4887 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4888 ok( ret == 0, "got %d\n", ret );
4889 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4890 DeleteObject( dib );
4894 info->bmiHeader.biHeight = -8;
4895 info->bmiHeader.biBitCount = 32;
4896 info->bmiHeader.biCompression = BI_RGB;
4897 info->bmiHeader.biSizeImage = 0;
4899 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4900 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4902 info->bmiHeader.biHeight = 8;
4903 info->bmiHeader.biBitCount = 8;
4904 info->bmiHeader.biCompression = BI_RLE8;
4905 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4907 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4908 ok( ret == 8, "got %d\n", ret );
4909 ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4910 memset( dib_bits, 0xaa, 64 * 4 );
4912 info->bmiHeader.biHeight = 4;
4913 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4914 ok( ret == 4, "got %d\n", ret );
4915 ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4916 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4917 memset( dib_bits, 0xaa, 64 * 4 );
4919 info->bmiHeader.biHeight = 9;
4920 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4921 ok( ret == 9, "got %d\n", ret );
4922 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4923 ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4924 memset( dib_bits, 0xaa, 64 * 4 );
4926 DeleteObject( dib );
4927 ReleaseDC( NULL, hdc );
4928 HeapFree( GetProcessHeap(), 0, info );
4931 static void test_SetDIBitsToDevice(void)
4933 char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
4934 LOGPALETTE *pal = (LOGPALETTE *)palbuf;
4935 PALETTEENTRY *palent = pal->palPalEntry;
4939 HDC hdc = CreateCompatibleDC( 0 );
4940 DWORD data[128], inverted_data[128];
4944 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4946 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4947 info->bmiHeader.biWidth = 8;
4948 info->bmiHeader.biHeight = 8;
4949 info->bmiHeader.biPlanes = 1;
4950 info->bmiHeader.biBitCount = 32;
4951 info->bmiHeader.biCompression = BI_RGB;
4953 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4954 memset( dib_bits, 0xaa, 64 * 4 );
4955 SelectObject( hdc, dib );
4957 for (i = 0; i < 128; i++)
4960 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4965 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4966 ok( ret == 8, "got %d\n", ret );
4967 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4968 memset( dib_bits, 0xaa, 64 * 4 );
4970 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4971 ok( ret == 5, "got %d\n", ret );
4972 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4973 for (i = 8; i < 48; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4974 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4975 memset( dib_bits, 0xaa, 64 * 4 );
4977 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 3, 1, 5, data, info, DIB_RGB_COLORS );
4978 ok( ret == 5, "got %d\n", ret );
4979 for (i = 0; i < 24; i++) ok( dib_bits[i] == data[i + 16], "%d: got %08x\n", i, dib_bits[i] );
4980 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4981 memset( dib_bits, 0xaa, 64 * 4 );
4983 info->bmiHeader.biHeight = 16;
4984 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4985 ok( ret == 7, "got %d\n", ret );
4986 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4987 for (i = 8; i < 64; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4988 memset( dib_bits, 0xaa, 64 * 4 );
4990 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 8, 0, 6, 1, 12, data, info, DIB_RGB_COLORS );
4991 ok( ret == 12, "got %d\n", ret );
4992 for (i = 0; i < 40; i++) ok( dib_bits[i] == data[i + 56], "%d: got %08x\n", i, dib_bits[i] );
4993 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4994 memset( dib_bits, 0xaa, 64 * 4 );
4996 ret = SetDIBitsToDevice( hdc, 0, -4, 8, 8, 0, 3, 1, 12, data, info, DIB_RGB_COLORS );
4997 ok( ret == 10, "got %d\n", ret );
4998 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4999 for (i = 32; i < 64; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
5000 memset( dib_bits, 0xaa, 64 * 4 );
5002 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, -3, 1, 12, data, info, DIB_RGB_COLORS );
5003 ok( ret == 4, "got %d\n", ret );
5004 for (i = 0; i < 32; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
5005 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5006 memset( dib_bits, 0xaa, 64 * 4 );
5008 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 5, 0, -2, 1, 12, data, info, DIB_RGB_COLORS );
5009 ok( ret == 2, "got %d\n", ret );
5010 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5011 for (i = 32; i < 48; i++) ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
5012 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5013 memset( dib_bits, 0xaa, 64 * 4 );
5015 info->bmiHeader.biHeight = 5;
5016 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 2, 2, data, info, DIB_RGB_COLORS );
5017 ok( ret == 2, "got %d\n", ret );
5018 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5019 for (i = 16; i < 32; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
5020 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5021 memset( dib_bits, 0xaa, 64 * 4 );
5023 ret = SetDIBitsToDevice( hdc, 3, 3, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
5024 ok( ret == 3, "got %d\n", ret );
5025 for (i = 0; i < 64; i++)
5026 if (i == 27 || i == 28 || i == 35 || i == 36)
5027 ok( dib_bits[i] == data[i - 18], "%d: got %08x\n", i, dib_bits[i] );
5029 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5030 memset( dib_bits, 0xaa, 64 * 4 );
5032 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5033 ok( ret == 5, "got %d\n", ret );
5034 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5035 memset( dib_bits, 0xaa, 64 * 4 );
5037 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
5038 ok( ret == 0, "got %d\n", ret );
5039 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5040 memset( dib_bits, 0xaa, 64 * 4 );
5042 SetMapMode( hdc, MM_ANISOTROPIC );
5043 SetWindowExtEx( hdc, 3, 3, NULL );
5044 ret = SetDIBitsToDevice( hdc, 2, 2, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
5045 ok( ret == 3, "got %d\n", ret );
5046 for (i = 0; i < 64; i++)
5047 if (i == 41 || i == 42 || i == 49 || i == 50)
5048 ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
5050 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5051 memset( dib_bits, 0xaa, 64 * 4 );
5053 SetWindowExtEx( hdc, -1, -1, NULL );
5054 ret = SetDIBitsToDevice( hdc, 2, 2, 4, 4, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
5055 ok( ret == 4, "got %d\n", ret );
5056 for (i = 0; i < 64; i++)
5057 if (i == 48 || i == 49 || i == 56 || i == 57)
5058 ok( dib_bits[i] == data[i - 37], "%d: got %08x\n", i, dib_bits[i] );
5060 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5061 memset( dib_bits, 0xaa, 64 * 4 );
5062 SetMapMode( hdc, MM_TEXT );
5066 pSetLayout( hdc, LAYOUT_RTL );
5067 ret = SetDIBitsToDevice( hdc, 1, 2, 3, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
5068 ok( ret == 3, "got %d\n", ret );
5069 for (i = 0; i < 64; i++)
5070 if (i == 36 || i == 37 || i == 38 || i == 44 || i == 45 || i == 46)
5071 ok( dib_bits[i] == data[i - 27], "%d: got %08x\n", i, dib_bits[i] );
5073 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5074 memset( dib_bits, 0xaa, 64 * 4 );
5075 pSetLayout( hdc, LAYOUT_LTR );
5079 info->bmiHeader.biHeight = -8;
5080 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5081 ok( ret == 8, "got %d\n", ret );
5082 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
5083 memset( dib_bits, 0xaa, 64 * 4 );
5085 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
5086 ok( ret == 5, "got %d\n", ret );
5087 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5088 for (i = 8; i < 48; i++) ok( dib_bits[i] == inverted_data[i + 80], "%d: got %08x\n", i, dib_bits[i] );
5089 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5090 memset( dib_bits, 0xaa, 64 * 4 );
5092 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 4, 1, 5, data, info, DIB_RGB_COLORS );
5093 ok( ret == 5, "got %d\n", ret );
5094 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
5095 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5096 memset( dib_bits, 0xaa, 64 * 4 );
5098 info->bmiHeader.biHeight = -16;
5099 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
5100 ok( ret == 12, "got %d\n", ret );
5101 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5102 for (i = 8; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 24], "%d: got %08x\n", i, dib_bits[i] );
5103 memset( dib_bits, 0xaa, 64 * 4 );
5105 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, 7, 1, 12, data, info, DIB_RGB_COLORS );
5106 ok( ret == 12, "got %d\n", ret );
5107 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
5108 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5109 memset( dib_bits, 0xaa, 64 * 4 );
5111 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 4, 12, data, info, DIB_RGB_COLORS );
5112 ok( ret == 12, "got %d\n", ret );
5113 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5114 for (i = 32; i < 64; i++) ok( dib_bits[i] == inverted_data[i], "%d: got %08x\n", i, dib_bits[i] );
5115 memset( dib_bits, 0xaa, 64 * 4 );
5117 ret = SetDIBitsToDevice( hdc, 0, -3, 8, 8, 0, 2, 4, 12, data, info, DIB_RGB_COLORS );
5118 ok( ret == 12, "got %d\n", ret );
5119 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5120 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5121 memset( dib_bits, 0xaa, 64 * 4 );
5123 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, -2, 4, 12, data, info, DIB_RGB_COLORS );
5124 ok( ret == 12, "got %d\n", ret );
5125 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5126 for (i = 24; i < 40; i++) ok( dib_bits[i] == inverted_data[i + 8], "%d: got %08x\n", i, dib_bits[i] );
5127 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5128 memset( dib_bits, 0xaa, 64 * 4 );
5130 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 5, 12, data, info, DIB_RGB_COLORS );
5131 ok( ret == 12, "got %d\n", ret );
5132 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5133 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5134 memset( dib_bits, 0xaa, 64 * 4 );
5136 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
5137 ok( ret == 12, "got %d\n", ret );
5138 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5139 memset( dib_bits, 0xaa, 64 * 4 );
5141 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -2, -4, 0, 12, data, info, DIB_RGB_COLORS );
5142 ok( ret == 12, "got %d\n", ret );
5143 for (i = 0; i < 64; i++)
5144 if (i == 31 || i == 39 || i == 47 || i == 55 || i == 63)
5145 ok( dib_bits[i] == inverted_data[i + 1], "%d: got %08x\n", i, dib_bits[i] );
5147 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5148 memset( dib_bits, 0xaa, 64 * 4 );
5150 info->bmiHeader.biHeight = -5;
5151 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
5152 ok( ret == 2, "got %d\n", ret );
5153 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5154 for (i = 8; i < 24; i++) ok( dib_bits[i] == inverted_data[i + 104], "%d: got %08x\n", i, dib_bits[i] );
5155 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5156 memset( dib_bits, 0xaa, 64 * 4 );
5158 ret = SetDIBitsToDevice( hdc, 5, 4, 2, 2, 6, 3, 1, 5, data, info, DIB_RGB_COLORS );
5159 ok( ret == 5, "got %d\n", ret );
5160 for (i = 0; i < 64; i++)
5161 if (i == 21 || i == 22 || i == 29 || i == 30)
5162 ok( dib_bits[i] == inverted_data[i + 89], "%d: got %08x\n", i, dib_bits[i] );
5164 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5165 memset( dib_bits, 0xaa, 64 * 4 );
5167 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5168 ok( ret == 5, "got %d\n", ret );
5169 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5170 memset( dib_bits, 0xaa, 64 * 4 );
5172 info->bmiHeader.biHeight = -8;
5174 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5175 DeleteObject( SelectObject( hdc, dib ));
5176 memset( dib_bits, 0xaa, 16 * 16 * 4 );
5180 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5181 ok( ret == 8, "got %d\n", ret );
5182 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
5183 memset( dib_bits, 0xaa, 64 * 4 );
5185 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
5186 ok( ret == 5, "got %d\n", ret );
5187 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5188 for (i = 16; i < 56; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
5189 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5190 memset( dib_bits, 0xaa, 64 * 4 );
5192 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 3, 0, 2, 1, 5, data, info, DIB_RGB_COLORS );
5193 ok( ret == 5, "got %d\n", ret );
5194 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5195 for (i = 24; i < 48; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
5196 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5197 memset( dib_bits, 0xaa, 64 * 4 );
5199 info->bmiHeader.biHeight = -16;
5200 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
5201 ok( ret == 12, "got %d\n", ret );
5202 for (i = 0; i < 56; i++) ok( dib_bits[i] == data[i + 40], "%d: got %08x\n", i, dib_bits[i] );
5203 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5204 memset( dib_bits, 0xaa, 64 * 4 );
5206 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -1, -8, 0, 12, data, info, DIB_RGB_COLORS );
5207 ok( ret == 12, "got %d\n", ret );
5208 for (i = 0; i < 64; i++)
5209 if (i == 6 || i == 7)
5210 ok( dib_bits[i] == data[i + 82], "%d: got %08x\n", i, dib_bits[i] );
5212 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5213 memset( dib_bits, 0xaa, 64 * 4 );
5215 info->bmiHeader.biHeight = -5;
5216 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
5217 ok( ret == 2, "got %d\n", ret );
5218 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5219 for (i = 40; i < 56; i++) ok( dib_bits[i] == data[i - 40], "%d: got %08x\n", i, dib_bits[i] );
5220 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5221 memset( dib_bits, 0xaa, 64 * 4 );
5223 ret = SetDIBitsToDevice( hdc, 7, 2, 8, 8, 1, 0, 0, 5, data, info, DIB_RGB_COLORS );
5224 ok( ret == 5, "got %d\n", ret );
5225 for (i = 0; i < 64; i++)
5226 if (i == 47 || i == 55 || i == 63)
5227 ok( dib_bits[i] == data[i - 46], "%d: got %08x\n", i, dib_bits[i] );
5229 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5230 memset( dib_bits, 0xaa, 64 * 4 );
5232 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5233 ok( ret == 5, "got %d\n", ret );
5234 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5235 memset( dib_bits, 0xaa, 64 * 4 );
5239 info->bmiHeader.biHeight = 8;
5240 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5241 ok( ret == 8, "got %d\n", ret );
5242 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
5243 memset( dib_bits, 0xaa, 64 * 4 );
5245 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
5246 ok( ret == 5, "got %d\n", ret );
5247 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5248 for (i = 16; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
5249 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5250 memset( dib_bits, 0xaa, 64 * 4 );
5252 info->bmiHeader.biHeight = 16;
5253 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
5254 ok( ret == 7, "got %d\n", ret );
5255 for (i = 0; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
5256 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5257 memset( dib_bits, 0xaa, 64 * 4 );
5259 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, 0, -4, 1, 12, data, info, DIB_RGB_COLORS );
5260 ok( ret == 3, "got %d\n", ret );
5261 for (i = 0; i < 64; i++)
5262 if ((i >= 36 && i <= 39) || (i >= 44 && i <= 47) || (i >= 52 && i <= 55))
5263 ok( dib_bits[i] == inverted_data[i + 68], "%d: got %08x\n", i, dib_bits[i] );
5265 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5266 memset( dib_bits, 0xaa, 64 * 4 );
5268 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, -30, -30, 1, 12, data, info, DIB_RGB_COLORS );
5269 ok( ret == 0, "got %d\n", ret );
5270 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5271 memset( dib_bits, 0xaa, 64 * 4 );
5273 ret = SetDIBitsToDevice( hdc, 5, -5, 8, 16, -2, -4, 4, 12, data, info, DIB_RGB_COLORS );
5274 ok( ret == 8, "got %d\n", ret );
5275 for (i = 0; i < 64; i++)
5276 if (i == 7 || i == 15 || i == 23)
5277 ok( dib_bits[i] == inverted_data[i + 97], "%d: got %08x\n", i, dib_bits[i] );
5279 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5280 memset( dib_bits, 0xaa, 64 * 4 );
5282 info->bmiHeader.biHeight = 5;
5283 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
5284 ok( ret == 2, "got %d\n", ret );
5285 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5286 for (i = 40; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
5287 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5288 memset( dib_bits, 0xaa, 64 * 4 );
5290 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5291 ok( ret == 5, "got %d\n", ret );
5292 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5293 memset( dib_bits, 0xaa, 64 * 4 );
5295 /* handling of partial color table */
5297 info->bmiHeader.biHeight = -8;
5298 info->bmiHeader.biBitCount = 8;
5299 info->bmiHeader.biClrUsed = 137;
5300 for (i = 0; i < 256; i++)
5302 info->bmiColors[i].rgbRed = 255 - i;
5303 info->bmiColors[i].rgbGreen = i * 2;
5304 info->bmiColors[i].rgbBlue = i;
5305 info->bmiColors[i].rgbReserved = 0;
5307 for (i = 0; i < 64; i++) ((BYTE *)data)[i] = i * 4 + 1;
5308 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5309 ok( ret == 8, "got %d\n", ret );
5310 for (i = 0; i < 64; i++)
5312 int idx = i * 4 + 1;
5313 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : (info->bmiColors[idx].rgbRed << 16 |
5314 info->bmiColors[idx].rgbGreen << 8 |
5315 info->bmiColors[idx].rgbBlue);
5316 ok( dib_bits[i] == expect, "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
5318 memset( dib_bits, 0xaa, 64 * 4 );
5320 /* handling of DIB_PAL_COLORS */
5322 pal->palVersion = 0x300;
5323 pal->palNumEntries = 137;
5324 info->bmiHeader.biClrUsed = 221;
5325 for (i = 0; i < 256; i++)
5327 palent[i].peRed = i * 2;
5328 palent[i].peGreen = 255 - i;
5329 palent[i].peBlue = i;
5331 palette = CreatePalette( pal );
5332 ok( palette != 0, "palette creation failed\n" );
5333 SelectPalette( hdc, palette, FALSE );
5334 for (i = 0; i < 256; i++) ((WORD *)info->bmiColors)[i] = 255 - i;
5335 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_PAL_COLORS );
5336 ok( ret == 8, "got %d\n", ret );
5337 for (i = 0; i < 64; i++)
5339 int idx = i * 4 + 1;
5340 int ent = (255 - idx) % pal->palNumEntries;
5341 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 :
5342 (palent[ent].peRed << 16 | palent[ent].peGreen << 8 | palent[ent].peBlue);
5343 ok( dib_bits[i] == expect || broken(dib_bits[i] == 0),
5344 "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
5346 memset( dib_bits, 0xaa, 64 * 4 );
5349 DeleteObject( dib );
5350 DeleteObject( palette );
5351 HeapFree( GetProcessHeap(), 0, info );
5354 static void test_SetDIBitsToDevice_RLE8(void)
5358 HDC hdc = CreateCompatibleDC( 0 );
5359 BYTE rle8_data[20] = { 0x04, 0x02, 0x03, 0xf0, 0x00, 0x00, /* 2, 2, 2, 2, f0, f0, f0, <eol> */
5360 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
5361 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
5362 0x00, 0x01 }; /* <eod> */
5365 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
5366 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5367 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5368 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
5369 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5370 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5371 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5372 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
5373 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5374 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5375 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5376 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5377 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
5378 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5379 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5380 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
5382 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
5384 info->bmiHeader.biSize = sizeof(info->bmiHeader);
5385 info->bmiHeader.biWidth = 8;
5386 info->bmiHeader.biHeight = 8;
5387 info->bmiHeader.biPlanes = 1;
5388 info->bmiHeader.biBitCount = 32;
5389 info->bmiHeader.biCompression = BI_RGB;
5391 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5392 memset( dib_bits, 0xaa, 64 * 4 );
5393 SelectObject( hdc, dib );
5395 info->bmiHeader.biBitCount = 8;
5396 info->bmiHeader.biCompression = BI_RLE8;
5397 info->bmiHeader.biSizeImage = sizeof(rle8_data);
5399 for (i = 0; i < 256; i++)
5401 info->bmiColors[i].rgbRed = i;
5402 info->bmiColors[i].rgbGreen = i;
5403 info->bmiColors[i].rgbBlue = i;
5404 info->bmiColors[i].rgbReserved = 0;
5407 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5408 ok( ret == 8, "got %d\n", ret );
5409 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5410 memset( dib_bits, 0xaa, 64 * 4 );
5412 /* startscan and lines are ignored, unless lines == 0 */
5413 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 8, rle8_data, info, DIB_RGB_COLORS );
5414 ok( ret == 8, "got %d\n", ret );
5415 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5416 memset( dib_bits, 0xaa, 64 * 4 );
5418 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 1, rle8_data, info, DIB_RGB_COLORS );
5419 ok( ret == 8, "got %d\n", ret );
5420 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5421 memset( dib_bits, 0xaa, 64 * 4 );
5423 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 0, rle8_data, info, DIB_RGB_COLORS );
5424 ok( ret == 0, "got %d\n", ret );
5425 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5426 memset( dib_bits, 0xaa, 64 * 4 );
5428 info->bmiHeader.biWidth = 2;
5429 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5430 ok( ret == 8, "got %d\n", ret );
5431 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5432 memset( dib_bits, 0xaa, 64 * 4 );
5434 info->bmiHeader.biWidth = 8;
5435 info->bmiHeader.biHeight = 2;
5436 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5437 ok( ret == 2, "got %d\n", ret );
5438 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5439 memset( dib_bits, 0xaa, 64 * 4 );
5441 info->bmiHeader.biHeight = 9;
5442 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5443 ok( ret == 9, "got %d\n", ret );
5444 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5445 memset( dib_bits, 0xaa, 64 * 4 );
5447 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5448 ok( ret == 9, "got %d\n", ret );
5449 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5450 memset( dib_bits, 0xaa, 64 * 4 );
5452 info->bmiHeader.biHeight = 8;
5453 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 9, rle8_data, info, DIB_RGB_COLORS );
5454 ok( ret == 8, "got %d\n", ret );
5455 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5456 memset( dib_bits, 0xaa, 64 * 4 );
5458 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5459 ok( ret == 8, "got %d\n", ret );
5460 for (i = 0; i < 40; i++) ok( dib_bits[i] == bottom_up[i + 24], "%d: got %08x\n", i, dib_bits[i] );
5461 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5462 memset( dib_bits, 0xaa, 64 * 4 );
5464 ret = SetDIBitsToDevice( hdc, 0, 3, 4, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5465 ok( ret == 8, "got %d\n", ret );
5466 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5467 for (i = 8; i < 40; i++)
5468 if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5469 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5470 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5471 memset( dib_bits, 0xaa, 64 * 4 );
5473 ret = SetDIBitsToDevice( hdc, 3, 3, 8, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5474 ok( ret == 8, "got %d\n", ret );
5475 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5476 for (i = 8; i < 40; i++)
5477 if ((i & 7) < 3) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5478 else ok( dib_bits[i] == bottom_up[i - 11], "%d: got %08x\n", i, dib_bits[i] );
5479 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5480 memset( dib_bits, 0xaa, 64 * 4 );
5482 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 4, 2, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5483 ok( ret == 8, "got %d\n", ret );
5484 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5485 for (i = 8; i < 40; i++)
5486 if ((i & 7) < 2) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5487 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5488 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5489 memset( dib_bits, 0xaa, 64 * 4 );
5491 info->bmiHeader.biWidth = 37;
5492 info->bmiHeader.biHeight = 37;
5493 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
5494 ok( ret == 37, "got %d\n", ret );
5495 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5496 for (i = 24; i < 64; i++)
5497 if (i == 52) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
5498 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5499 else ok( dib_bits[i] == bottom_up[i - 20], "%d: got %08x\n", i, dib_bits[i] );
5500 memset( dib_bits, 0xaa, 64 * 4 );
5502 /* top-down compressed dibs are invalid */
5503 info->bmiHeader.biWidth = 8;
5504 info->bmiHeader.biHeight = -8;
5505 SetLastError( 0xdeadbeef );
5506 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5507 ok( ret == 0, "got %d\n", ret );
5508 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
5512 info->bmiHeader.biHeight = -8;
5513 info->bmiHeader.biBitCount = 32;
5514 info->bmiHeader.biCompression = BI_RGB;
5515 info->bmiHeader.biSizeImage = 0;
5517 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5518 memset( dib_bits, 0xaa, 16 * 16 * 4 );
5519 DeleteObject( SelectObject( hdc, dib ));
5521 info->bmiHeader.biHeight = 8;
5522 info->bmiHeader.biBitCount = 8;
5523 info->bmiHeader.biCompression = BI_RLE8;
5524 info->bmiHeader.biSizeImage = sizeof(rle8_data);
5526 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5527 ok( ret == 8, "got %d\n", ret );
5528 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5529 memset( dib_bits, 0xaa, 64 * 4 );
5531 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5532 ok( ret == 8, "got %d\n", ret );
5533 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5534 memset( dib_bits, 0xaa, 64 * 4 );
5536 info->bmiHeader.biHeight = 4;
5537 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5538 ok( ret == 4, "got %d\n", ret );
5539 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5540 memset( dib_bits, 0xaa, 64 * 4 );
5542 info->bmiHeader.biHeight = 9;
5543 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5544 ok( ret == 9, "got %d\n", ret );
5545 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5546 memset( dib_bits, 0xaa, 64 * 4 );
5548 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5549 ok( ret == 9, "got %d\n", ret );
5550 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5551 memset( dib_bits, 0xaa, 64 * 4 );
5553 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 6, 2, 2, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5554 ok( ret == 9, "got %d\n", ret );
5555 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5556 for (i = 24; i < 64; i++) ok( dib_bits[i] == top_down[i - 24], "%d: got %08x\n", i, dib_bits[i] );
5557 memset( dib_bits, 0xaa, 64 * 4 );
5559 info->bmiHeader.biWidth = 37;
5560 info->bmiHeader.biHeight = 37;
5561 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
5562 ok( ret == 37, "got %d\n", ret );
5563 for (i = 0; i < 40; i++)
5564 if (i == 12) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
5565 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5566 else ok( dib_bits[i] == top_down[i + 28], "%d: got %08x\n", i, dib_bits[i] );
5567 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5568 memset( dib_bits, 0xaa, 64 * 4 );
5571 DeleteObject( dib );
5572 HeapFree( GetProcessHeap(), 0, info );
5579 hdll = GetModuleHandle("gdi32.dll");
5580 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
5581 pGdiGradientFill = (void*)GetProcAddress(hdll, "GdiGradientFill");
5582 pSetLayout = (void*)GetProcAddress(hdll, "SetLayout");
5584 test_createdibitmap();
5587 test_mono_dibsection();
5591 test_GetDIBits_selected_DIB(1);
5592 test_GetDIBits_selected_DIB(4);
5593 test_GetDIBits_selected_DIB(8);
5594 test_GetDIBits_selected_DDB(TRUE);
5595 test_GetDIBits_selected_DDB(FALSE);
5597 test_GetDIBits_BI_BITFIELDS();
5598 test_select_object();
5599 test_CreateBitmap();
5602 test_StretchDIBits();
5603 test_GdiAlphaBlend();
5604 test_GdiGradientFill();
5606 test_bitmapinfoheadersize();
5609 test_GetDIBits_top_down(16);
5610 test_GetDIBits_top_down(24);
5611 test_GetDIBits_top_down(32);
5612 test_GetSetDIBits_rtl();
5613 test_GetDIBits_scanlines();
5615 test_SetDIBits_RLE4();
5616 test_SetDIBits_RLE8();
5617 test_SetDIBitsToDevice();
5618 test_SetDIBitsToDevice_RLE8();