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 void 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;
3363 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3364 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3365 bitmapInfo.bmiHeader.biWidth = 2;
3366 bitmapInfo.bmiHeader.biHeight = -2;
3367 bitmapInfo.bmiHeader.biPlanes = 1;
3368 bitmapInfo.bmiHeader.biBitCount = 32;
3369 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3371 memset(dstBuffer, 0, 16);
3372 StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
3373 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3374 srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
3375 ok(memcmp(dstBuffer, expected, 16) == 0,
3376 "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
3377 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
3378 expected[0], expected[1], expected[2], expected[3],
3379 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
3380 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3381 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
3384 static void test_StretchDIBits(void)
3388 HDC hdcScreen, hdcDst;
3389 UINT32 *dstBuffer, srcBuffer[4];
3390 HBRUSH hBrush, hOldBrush;
3394 memset(&biDst, 0, sizeof(BITMAPINFO));
3395 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3396 biDst.bmiHeader.biWidth = 2;
3397 biDst.bmiHeader.biHeight = -2;
3398 biDst.bmiHeader.biPlanes = 1;
3399 biDst.bmiHeader.biBitCount = 32;
3400 biDst.bmiHeader.biCompression = BI_RGB;
3402 hdcScreen = CreateCompatibleDC(0);
3403 hdcDst = CreateCompatibleDC(hdcScreen);
3406 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3408 oldDst = SelectObject(hdcDst, bmpDst);
3410 hBrush = CreateSolidBrush(0x012345678);
3411 hOldBrush = SelectObject(hdcDst, hBrush);
3413 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3414 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3415 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3416 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3417 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3418 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3419 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3420 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3421 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3422 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3423 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3424 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3425 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3426 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3427 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3429 SelectObject(hdcDst, hOldBrush);
3430 DeleteObject(hBrush);
3432 /* Top-down destination tests */
3433 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3434 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
3436 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
3437 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
3438 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3439 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3441 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3442 expected[2] = 0x00000000, expected[3] = 0x00000000;
3443 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3444 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
3446 expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
3447 expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
3448 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3449 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
3451 expected[0] = 0x42441000, expected[1] = 0x00000000;
3452 expected[2] = 0x00000000, expected[3] = 0x00000000;
3453 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3454 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
3456 expected[0] = 0x00000000, expected[1] = 0x00000000;
3457 expected[2] = 0x00000000, expected[3] = 0x00000000;
3458 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3459 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3461 expected[0] = 0x00000000, expected[1] = 0x00000000;
3462 expected[2] = 0x00000000, expected[3] = 0x00000000;
3463 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3464 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3466 expected[0] = 0x00000000, expected[1] = 0x00000000;
3467 expected[2] = 0x00000000, expected[3] = 0x00000000;
3468 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3469 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
3471 expected[0] = 0x00000000, expected[1] = 0x00000000;
3472 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
3473 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3474 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3476 SelectObject(hdcDst, oldDst);
3477 DeleteObject(bmpDst);
3479 /* Bottom up destination tests */
3480 biDst.bmiHeader.biHeight = 2;
3481 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3483 oldDst = SelectObject(hdcDst, bmpDst);
3485 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3486 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
3487 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3488 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3491 SelectObject(hdcDst, oldDst);
3492 DeleteObject(bmpDst);
3495 DeleteDC(hdcScreen);
3498 static void test_GdiAlphaBlend(void)
3510 BLENDFUNCTION blend;
3512 if (!pGdiAlphaBlend)
3514 win_skip("GdiAlphaBlend() is not implemented\n");
3518 hdcNull = GetDC(NULL);
3519 hdcDst = CreateCompatibleDC(hdcNull);
3520 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
3521 hdcSrc = CreateCompatibleDC(hdcNull);
3523 bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3524 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3525 bmi->bmiHeader.biHeight = 20;
3526 bmi->bmiHeader.biWidth = 20;
3527 bmi->bmiHeader.biBitCount = 32;
3528 bmi->bmiHeader.biPlanes = 1;
3529 bmi->bmiHeader.biCompression = BI_RGB;
3530 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3531 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3533 oldDst = SelectObject(hdcDst, bmpDst);
3534 oldSrc = SelectObject(hdcSrc, bmpSrc);
3536 blend.BlendOp = AC_SRC_OVER;
3537 blend.BlendFlags = 0;
3538 blend.SourceConstantAlpha = 128;
3539 blend.AlphaFormat = 0;
3541 SetLastError(0xdeadbeef);
3542 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3543 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3545 SetLastError(0xdeadbeef);
3546 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3547 ok( !ret, "GdiAlphaBlend succeeded\n" );
3548 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3550 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3551 ok( !ret, "GdiAlphaBlend succeeded\n" );
3552 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend);
3553 ok( !ret, "GdiAlphaBlend succeeded\n" );
3554 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3555 ok( !ret, "GdiAlphaBlend succeeded\n" );
3556 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3557 ok( !ret, "GdiAlphaBlend succeeded\n" );
3559 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
3560 SetLastError(0xdeadbeef);
3561 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3562 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3563 SetLastError(0xdeadbeef);
3564 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3565 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3566 SetMapMode(hdcSrc, MM_ANISOTROPIC);
3567 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
3568 SetLastError(0xdeadbeef);
3569 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend);
3570 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3571 SetLastError(0xdeadbeef);
3572 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend);
3573 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3575 SetMapMode(hdcDst, MM_ANISOTROPIC);
3576 SetViewportExtEx(hdcDst, -1, -1, NULL);
3577 SetLastError(0xdeadbeef);
3578 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 50, 50, blend);
3580 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3581 SetLastError(0xdeadbeef);
3582 ret = pGdiAlphaBlend(hdcDst, -20, -20, 20, 20, hdcSrc, 0, -1, 50, 50, blend);
3583 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3584 SetLastError(0xdeadbeef);
3585 ret = pGdiAlphaBlend(hdcDst, -20, -20, -20, -20, hdcSrc, 0, -1, 50, 50, blend);
3586 ok( !ret, "GdiAlphaBlend succeeded\n" );
3587 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3588 SetLastError(0xdeadbeef);
3589 ret = pGdiAlphaBlend(hdcDst, -20, 0, -20, 20, hdcSrc, 0, -1, 50, 50, blend);
3590 ok( !ret, "GdiAlphaBlend succeeded\n" );
3591 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3592 SetLastError(0xdeadbeef);
3593 ret = pGdiAlphaBlend(hdcDst, 0, -20, 20, -20, hdcSrc, 0, -1, 50, 50, blend);
3594 ok( !ret, "GdiAlphaBlend succeeded\n" );
3595 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3596 SetMapMode(hdcDst, MM_TEXT);
3598 SetViewportExtEx(hdcSrc, -1, -1, NULL);
3599 SetLastError(0xdeadbeef);
3600 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, -30, -30, blend);
3601 ok( !ret, "GdiAlphaBlend succeeded\n" );
3602 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3603 SetLastError(0xdeadbeef);
3604 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, 30, -30, blend);
3605 ok( !ret, "GdiAlphaBlend succeeded\n" );
3606 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3607 SetLastError(0xdeadbeef);
3608 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, -30, 30, blend);
3609 ok( !ret, "GdiAlphaBlend succeeded\n" );
3610 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3611 SetLastError(0xdeadbeef);
3612 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, 30, 30, blend);
3613 ok( !ret, "GdiAlphaBlend succeeded\n" );
3614 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3615 SetLastError(0xdeadbeef);
3616 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 20, 20, 30, 30, blend);
3617 ok( !ret, "GdiAlphaBlend succeeded\n" );
3618 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3619 SetLastError(0xdeadbeef);
3620 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -60, -60, 30, 30, blend);
3621 ok( !ret, "GdiAlphaBlend succeeded\n" );
3622 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3623 SetViewportExtEx(hdcSrc, 1, 1, NULL);
3625 SetLastError(0xdeadbeef);
3626 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend);
3627 ok( !ret, "GdiAlphaBlend succeeded\n" );
3628 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3630 /* overlapping source and dest not allowed */
3632 SetLastError(0xdeadbeef);
3633 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 19, 19, 20, 20, blend);
3634 ok( !ret, "GdiAlphaBlend succeeded\n" );
3635 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3637 SetLastError(0xdeadbeef);
3638 ret = pGdiAlphaBlend(hdcDst, 20, 20, 20, 20, hdcDst, 1, 1, 20, 20, blend);
3639 ok( !ret, "GdiAlphaBlend succeeded\n" );
3640 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3642 SetLastError(0xdeadbeef);
3643 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 20, 10, 20, 20, blend);
3644 ok( ret, "GdiAlphaBlend succeeded\n" );
3645 SetLastError(0xdeadbeef);
3646 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 10, 20, 20, 20, blend);
3647 ok( ret, "GdiAlphaBlend succeeded\n" );
3649 /* AC_SRC_ALPHA requires 32-bpp BI_RGB format */
3651 blend.AlphaFormat = AC_SRC_ALPHA;
3652 SetLastError(0xdeadbeef);
3653 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3654 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3656 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3657 ((DWORD *)bmi->bmiColors)[0] = 0xff0000;
3658 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3659 ((DWORD *)bmi->bmiColors)[2] = 0x0000ff;
3660 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3661 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3662 oldSrc = SelectObject(hdcSrc, bmpSrc);
3663 DeleteObject( oldSrc );
3665 SetLastError(0xdeadbeef);
3666 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3667 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3669 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3670 ((DWORD *)bmi->bmiColors)[0] = 0x0000ff;
3671 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3672 ((DWORD *)bmi->bmiColors)[2] = 0xff0000;
3673 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3674 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3675 oldSrc = SelectObject(hdcSrc, bmpSrc);
3676 DeleteObject( oldSrc );
3678 SetLastError(0xdeadbeef);
3679 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3680 ok( !ret, "GdiAlphaBlend succeeded\n" );
3681 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3683 bmi->bmiHeader.biBitCount = 24;
3684 bmi->bmiHeader.biCompression = BI_RGB;
3685 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3686 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3687 oldSrc = SelectObject(hdcSrc, bmpSrc);
3688 DeleteObject( oldSrc );
3690 SetLastError(0xdeadbeef);
3691 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3692 ok( !ret, "GdiAlphaBlend succeeded\n" );
3693 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3695 bmi->bmiHeader.biBitCount = 1;
3696 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3697 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3698 oldSrc = SelectObject(hdcSrc, bmpSrc);
3699 DeleteObject( oldSrc );
3701 SetLastError(0xdeadbeef);
3702 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3703 ok( !ret, "GdiAlphaBlend succeeded\n" );
3704 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3706 bmpSrc = CreateBitmap( 100, 100, 1, 1, NULL );
3707 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3708 oldSrc = SelectObject(hdcSrc, bmpSrc);
3709 DeleteObject( oldSrc );
3711 SetLastError(0xdeadbeef);
3712 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3713 ok( !ret, "GdiAlphaBlend succeeded\n" );
3714 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3716 SelectObject(hdcDst, oldDst);
3717 SelectObject(hdcSrc, oldSrc);
3718 DeleteObject(bmpSrc);
3719 DeleteObject(bmpDst);
3723 ReleaseDC(NULL, hdcNull);
3727 static void test_GdiGradientFill(void)
3734 GRADIENT_RECT rect[] = { { 0, 0 }, { 0, 1 }, { 2, 3 } };
3735 GRADIENT_TRIANGLE tri[] = { { 0, 0, 0 }, { 0, 1, 2 }, { 0, 2, 1 }, { 0, 1, 3 } };
3736 TRIVERTEX vt[3] = { { 2, 2, 0xff00, 0x0000, 0x0000, 0x8000 },
3737 { 10, 10, 0x0000, 0xff00, 0x0000, 0x8000 },
3738 { 20, 10, 0x0000, 0x0000, 0xff00, 0xff00 } };
3740 if (!pGdiGradientFill)
3742 win_skip( "GdiGradientFill is not implemented\n" );
3746 hdc = CreateCompatibleDC( NULL );
3747 bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3748 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3749 bmi->bmiHeader.biHeight = 20;
3750 bmi->bmiHeader.biWidth = 20;
3751 bmi->bmiHeader.biBitCount = 32;
3752 bmi->bmiHeader.biPlanes = 1;
3753 bmi->bmiHeader.biCompression = BI_RGB;
3754 bmp = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3755 ok( bmp != NULL, "couldn't create bitmap\n" );
3756 SelectObject( hdc, bmp );
3758 SetLastError( 0xdeadbeef );
3759 ret = pGdiGradientFill( hdc, vt, 3, rect, 1, GRADIENT_FILL_RECT_H );
3760 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3761 SetLastError( 0xdeadbeef );
3762 ret = pGdiGradientFill( hdc, vt, 3, rect, 1, 3 );
3763 ok( !ret, "GdiGradientFill succeeded\n" );
3764 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3765 SetLastError( 0xdeadbeef );
3766 ret = pGdiGradientFill( (HDC)0xdead, vt, 3, rect, 1, GRADIENT_FILL_RECT_H );
3767 ok( !ret, "GdiGradientFill succeeded\n" );
3768 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3769 SetLastError( 0xdeadbeef );
3770 ret = pGdiGradientFill( NULL, NULL, 0, rect, 1, GRADIENT_FILL_RECT_H );
3771 ok( !ret, "GdiGradientFill succeeded\n" );
3772 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3773 ret = pGdiGradientFill( hdc, NULL, 0, rect, 1, GRADIENT_FILL_RECT_H );
3774 ok( !ret, "GdiGradientFill succeeded\n" );
3775 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3776 SetLastError( 0xdeadbeef );
3777 ret = pGdiGradientFill( hdc, NULL, 3, rect, 1, GRADIENT_FILL_RECT_H );
3778 ok( !ret, "GdiGradientFill succeeded\n" );
3779 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3780 SetLastError( 0xdeadbeef );
3781 ret = pGdiGradientFill( hdc, vt, 3, NULL, 0, GRADIENT_FILL_RECT_H );
3782 ok( !ret, "GdiGradientFill succeeded\n" );
3783 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3784 SetLastError( 0xdeadbeef );
3785 ret = pGdiGradientFill( hdc, vt, 3, NULL, 1, GRADIENT_FILL_RECT_H );
3786 ok( !ret, "GdiGradientFill succeeded\n" );
3787 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3788 SetLastError( 0xdeadbeef );
3789 ret = pGdiGradientFill( hdc, vt, 3, rect, 0, GRADIENT_FILL_RECT_H );
3790 ok( !ret, "GdiGradientFill succeeded\n" );
3791 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3792 SetLastError( 0xdeadbeef );
3793 ret = pGdiGradientFill( hdc, vt, 3, rect, 3, GRADIENT_FILL_RECT_H );
3794 ok( !ret, "GdiGradientFill succeeded\n" );
3795 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3796 rect[2].UpperLeft = rect[2].LowerRight = 1;
3797 SetLastError( 0xdeadbeef );
3798 ret = pGdiGradientFill( hdc, vt, 3, rect, 3, GRADIENT_FILL_RECT_H );
3799 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3800 SetLastError( 0xdeadbeef );
3801 ret = pGdiGradientFill( hdc, vt, 1, rect, 1, GRADIENT_FILL_RECT_H );
3802 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3803 SetLastError( 0xdeadbeef );
3804 ret = pGdiGradientFill( hdc, vt, 1, tri, 0, GRADIENT_FILL_TRIANGLE );
3805 ok( !ret, "GdiGradientFill succeeded\n" );
3806 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3807 SetLastError( 0xdeadbeef );
3808 ret = pGdiGradientFill( hdc, vt, 1, tri, 1, GRADIENT_FILL_TRIANGLE );
3809 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3810 SetLastError( 0xdeadbeef );
3811 ret = pGdiGradientFill( hdc, vt, 3, tri, 2, GRADIENT_FILL_TRIANGLE );
3812 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3813 SetLastError( 0xdeadbeef );
3814 ret = pGdiGradientFill( hdc, vt, 3, tri, 3, GRADIENT_FILL_TRIANGLE );
3815 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3816 SetLastError( 0xdeadbeef );
3817 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3818 ok( !ret, "GdiGradientFill succeeded\n" );
3819 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3821 SetLastError( 0xdeadbeef );
3822 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3823 ok( !ret, "GdiGradientFill succeeded\n" );
3824 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3826 SetLastError( 0xdeadbeef );
3827 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3828 ok( !ret, "GdiGradientFill succeeded\n" );
3829 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3830 tri[3].Vertex1 = tri[3].Vertex2 = tri[3].Vertex3 = 1;
3831 SetLastError( 0xdeadbeef );
3832 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3833 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3836 DeleteObject( bmp );
3839 static void test_clipping(void)
3847 HDC hdcDst = CreateCompatibleDC( NULL );
3848 HDC hdcSrc = CreateCompatibleDC( NULL );
3850 BITMAPINFO bmpinfo={{0}};
3851 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3852 bmpinfo.bmiHeader.biWidth = 100;
3853 bmpinfo.bmiHeader.biHeight = 100;
3854 bmpinfo.bmiHeader.biPlanes = 1;
3855 bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3856 bmpinfo.bmiHeader.biCompression = BI_RGB;
3858 bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3859 ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3860 SelectObject( hdcDst, bmpDst );
3862 bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3863 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3864 SelectObject( hdcSrc, bmpSrc );
3866 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3867 ok(result, "BitBlt failed\n");
3869 hRgn = CreateRectRgn( 0,0,0,0 );
3870 SelectClipRgn( hdcDst, hRgn );
3872 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3873 ok(result, "BitBlt failed\n");
3875 DeleteObject( bmpDst );
3876 DeleteObject( bmpSrc );
3877 DeleteObject( hRgn );
3882 static void test_32bit_ddb(void)
3884 char buffer[sizeof(BITMAPINFOHEADER) + sizeof(DWORD)];
3885 BITMAPINFO *biDst = (BITMAPINFO *)buffer;
3886 HBITMAP bmpSrc, bmpDst;
3887 HBITMAP oldSrc, oldDst;
3888 HDC hdcSrc, hdcDst, hdcScreen;
3890 DWORD *dstBuffer, *data;
3891 DWORD colorSrc = 0x40201008;
3893 memset(biDst, 0, sizeof(BITMAPINFOHEADER));
3894 biDst->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3895 biDst->bmiHeader.biWidth = 1;
3896 biDst->bmiHeader.biHeight = -1;
3897 biDst->bmiHeader.biPlanes = 1;
3898 biDst->bmiHeader.biBitCount = 32;
3899 biDst->bmiHeader.biCompression = BI_RGB;
3901 hdcScreen = CreateCompatibleDC(0);
3902 if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3904 DeleteDC(hdcScreen);
3905 trace("Skipping 32-bit DDB test\n");
3909 hdcSrc = CreateCompatibleDC(hdcScreen);
3910 bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3911 oldSrc = SelectObject(hdcSrc, bmpSrc);
3913 hdcDst = CreateCompatibleDC(hdcScreen);
3914 bmpDst = CreateDIBSection(hdcDst, biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3915 oldDst = SelectObject(hdcDst, bmpDst);
3917 StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3918 ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3922 BLENDFUNCTION blend;
3925 blend.BlendOp = AC_SRC_OVER;
3926 blend.BlendFlags = 0;
3927 blend.SourceConstantAlpha = 128;
3928 blend.AlphaFormat = 0;
3929 dstBuffer[0] = 0x80808080;
3930 ret = pGdiAlphaBlend( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, blend );
3931 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3932 ok(dstBuffer[0] == 0x60504844, "wrong color %x\n", dstBuffer[0]);
3933 blend.AlphaFormat = AC_SRC_ALPHA;
3934 dstBuffer[0] = 0x80808080;
3935 ret = pGdiAlphaBlend( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, blend );
3936 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3937 ok(dstBuffer[0] == 0x90807874, "wrong color %x\n", dstBuffer[0]);
3940 data = (DWORD *)biDst->bmiColors;
3941 data[0] = 0x20304050;
3942 brush = CreateDIBPatternBrushPt( biDst, DIB_RGB_COLORS );
3943 ok( brush != 0, "brush creation failed\n" );
3944 SelectObject( hdcSrc, brush );
3945 PatBlt( hdcSrc, 0, 0, 1, 1, PATCOPY );
3946 BitBlt( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, SRCCOPY );
3947 ok(dstBuffer[0] == data[0], "Expected color=%x, received color=%x\n", data[0], dstBuffer[0]);
3948 SelectObject( hdcSrc, GetStockObject(BLACK_BRUSH) );
3949 DeleteObject( brush );
3951 biDst->bmiHeader.biBitCount = 24;
3952 brush = CreateDIBPatternBrushPt( biDst, DIB_RGB_COLORS );
3953 ok( brush != 0, "brush creation failed\n" );
3954 SelectObject( hdcSrc, brush );
3955 PatBlt( hdcSrc, 0, 0, 1, 1, PATCOPY );
3956 BitBlt( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, SRCCOPY );
3957 ok(dstBuffer[0] == (data[0] & ~0xff000000),
3958 "Expected color=%x, received color=%x\n", data[0] & 0xff000000, dstBuffer[0]);
3959 SelectObject( hdcSrc, GetStockObject(BLACK_BRUSH) );
3960 DeleteObject( brush );
3963 SelectObject(hdcDst, oldDst);
3964 DeleteObject(bmpDst);
3967 SelectObject(hdcSrc, oldSrc);
3968 DeleteObject(bmpSrc);
3971 DeleteDC(hdcScreen);
3975 * Used by test_GetDIBits_top_down to create the bitmap to test against.
3977 static void setup_picture(char *picture, int bpp)
3985 /*Set the first byte in each pixel to the index of that pixel.*/
3986 for (i = 0; i < 4; i++)
3987 picture[i * (bpp / 8)] = i;
3992 /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
3999 static void test_GetDIBits_top_down(int bpp)
4002 HBITMAP bmptb, bmpbt;
4008 memset( &bi, 0, sizeof(bi) );
4009 bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
4010 bi.bmiHeader.biWidth=2;
4011 bi.bmiHeader.biHeight=2;
4012 bi.bmiHeader.biPlanes=1;
4013 bi.bmiHeader.biBitCount=bpp;
4014 bi.bmiHeader.biCompression=BI_RGB;
4016 /*Get the device context for the screen.*/
4018 ok(hdc != NULL, "Could not get a handle to a device context.\n");
4020 /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
4021 bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
4022 ok(bmpbt != NULL, "Could not create a DIB section.\n");
4023 /*Now that we have a pointer to the pixels, we write to them.*/
4024 setup_picture((char*)picture, bpp);
4025 /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
4026 bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
4027 bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
4028 ok(bmptb != NULL, "Could not create a DIB section.\n");
4029 /*Write to this top to bottom bitmap.*/
4030 setup_picture((char*)picture, bpp);
4032 bi.bmiHeader.biWidth = 1;
4034 bi.bmiHeader.biHeight = 2;
4035 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
4036 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4037 /*Check the first byte of the pixel.*/
4038 ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
4039 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
4040 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4041 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
4042 /*Check second scanline.*/
4043 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
4044 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4045 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
4046 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
4047 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4048 ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
4049 /*Check both scanlines.*/
4050 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
4051 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4052 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
4053 ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
4054 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
4055 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4056 ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
4057 ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
4059 /*Make destination bitmap top-down.*/
4060 bi.bmiHeader.biHeight = -2;
4061 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
4062 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4063 ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
4064 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
4065 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4066 ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
4067 /*Check second scanline.*/
4068 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
4069 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4070 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
4071 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
4072 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4073 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
4074 /*Check both scanlines.*/
4075 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
4076 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4077 ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
4078 ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
4079 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
4080 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4081 ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
4082 ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
4084 DeleteObject(bmpbt);
4085 DeleteObject(bmptb);
4088 static void test_GetSetDIBits_rtl(void)
4091 HBITMAP bitmap, orig_bitmap;
4094 DWORD bits_1[8 * 8], bits_2[8 * 8];
4098 win_skip("Don't have SetLayout\n");
4102 hdc = GetDC( NULL );
4103 hdc_mem = CreateCompatibleDC( hdc );
4104 pSetLayout( hdc_mem, LAYOUT_LTR );
4106 bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
4107 orig_bitmap = SelectObject( hdc_mem, bitmap );
4108 SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
4109 SelectObject( hdc_mem, orig_bitmap );
4111 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
4112 info.bmiHeader.biWidth = 8;
4113 info.bmiHeader.biHeight = 8;
4114 info.bmiHeader.biPlanes = 1;
4115 info.bmiHeader.biBitCount = 32;
4116 info.bmiHeader.biCompression = BI_RGB;
4118 /* First show that GetDIBits ignores the layout mode. */
4120 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
4121 ok(ret == 8, "got %d\n", ret);
4122 ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
4124 pSetLayout( hdc_mem, LAYOUT_RTL );
4126 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
4127 ok(ret == 8, "got %d\n", ret);
4129 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
4131 /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
4132 followed by a GetDIBits and show that the bits remain unchanged. */
4134 pSetLayout( hdc_mem, LAYOUT_LTR );
4136 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
4137 ok(ret == 8, "got %d\n", ret);
4138 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
4139 ok(ret == 8, "got %d\n", ret);
4140 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
4142 pSetLayout( hdc_mem, LAYOUT_RTL );
4144 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
4145 ok(ret == 8, "got %d\n", ret);
4146 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
4147 ok(ret == 8, "got %d\n", ret);
4148 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
4150 DeleteObject( bitmap );
4151 DeleteDC( hdc_mem );
4152 ReleaseDC( NULL, hdc );
4155 static void test_GetDIBits_scanlines(void)
4159 HDC hdc = GetDC( NULL );
4161 DWORD data[128], inverted_bits[64];
4164 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4166 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4167 info->bmiHeader.biWidth = 8;
4168 info->bmiHeader.biHeight = 8;
4169 info->bmiHeader.biPlanes = 1;
4170 info->bmiHeader.biBitCount = 32;
4171 info->bmiHeader.biCompression = BI_RGB;
4173 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4175 for (i = 0; i < 64; i++)
4178 inverted_bits[56 - (i & ~7) + (i & 7)] = i;
4183 memset( data, 0xaa, sizeof(data) );
4185 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4186 ok( ret == 8, "got %d\n", ret );
4187 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4188 memset( data, 0xaa, sizeof(data) );
4190 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4191 ok( ret == 5, "got %d\n", ret );
4192 ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
4193 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4194 memset( data, 0xaa, sizeof(data) );
4196 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4197 ok( ret == 7, "got %d\n", ret );
4198 ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
4199 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4200 memset( data, 0xaa, sizeof(data) );
4202 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4203 ok( ret == 1, "got %d\n", ret );
4204 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4205 memset( data, 0xaa, sizeof(data) );
4207 info->bmiHeader.biHeight = 16;
4208 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4209 ok( ret == 5, "got %d\n", ret );
4210 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4211 ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
4212 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4213 memset( data, 0xaa, sizeof(data) );
4215 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
4216 ok( ret == 6, "got %d\n", ret );
4217 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4218 ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
4219 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4220 memset( data, 0xaa, sizeof(data) );
4222 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
4223 ok( ret == 0, "got %d\n", ret );
4224 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4225 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4226 memset( data, 0xaa, sizeof(data) );
4228 info->bmiHeader.biHeight = 5;
4229 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4230 ok( ret == 2, "got %d\n", ret );
4231 ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
4232 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4233 memset( data, 0xaa, sizeof(data) );
4237 info->bmiHeader.biHeight = -8;
4238 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4239 ok( ret == 8, "got %d\n", ret );
4240 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4241 memset( data, 0xaa, sizeof(data) );
4243 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4244 ok( ret == 5, "got %d\n", ret );
4245 ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
4246 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4247 memset( data, 0xaa, sizeof(data) );
4249 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4250 ok( ret == 7, "got %d\n", ret );
4251 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
4252 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4253 memset( data, 0xaa, sizeof(data) );
4255 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4256 ok( ret == 4, "got %d\n", ret );
4257 ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
4258 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4259 memset( data, 0xaa, sizeof(data) );
4261 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
4262 ok( ret == 5, "got %d\n", ret );
4263 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
4264 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4265 memset( data, 0xaa, sizeof(data) );
4267 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
4268 ok( ret == 5, "got %d\n", ret );
4269 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
4270 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4271 memset( data, 0xaa, sizeof(data) );
4273 info->bmiHeader.biHeight = -16;
4274 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
4275 ok( ret == 8, "got %d\n", ret );
4276 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4277 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4278 memset( data, 0xaa, sizeof(data) );
4280 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4281 ok( ret == 5, "got %d\n", ret );
4282 ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
4283 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4284 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4285 memset( data, 0xaa, sizeof(data) );
4287 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4288 ok( ret == 8, "got %d\n", ret );
4289 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4290 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4291 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4292 memset( data, 0xaa, sizeof(data) );
4294 ret = GetDIBits( hdc, dib, 5, 12, 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 < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4298 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4299 memset( data, 0xaa, sizeof(data) );
4301 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4302 ok( ret == 7, "got %d\n", ret );
4303 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
4304 for (i = 56; 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, 18, 12, data, info, DIB_RGB_COLORS );
4308 ok( ret == 1, "got %d\n", ret );
4309 for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4310 memset( data, 0xaa, sizeof(data) );
4312 info->bmiHeader.biHeight = -5;
4313 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4314 ok( ret == 2, "got %d\n", ret );
4315 ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
4316 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4317 memset( data, 0xaa, sizeof(data) );
4319 DeleteObject( dib );
4321 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4322 info->bmiHeader.biWidth = 8;
4323 info->bmiHeader.biHeight = -8;
4324 info->bmiHeader.biPlanes = 1;
4325 info->bmiHeader.biBitCount = 32;
4326 info->bmiHeader.biCompression = BI_RGB;
4328 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4330 for (i = 0; i < 64; i++) dib_bits[i] = i;
4334 info->bmiHeader.biHeight = -8;
4335 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4336 ok( ret == 8, "got %d\n", ret );
4337 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4338 memset( data, 0xaa, sizeof(data) );
4340 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4341 ok( ret == 5, "got %d\n", ret );
4342 ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
4343 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4344 memset( data, 0xaa, sizeof(data) );
4346 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4347 ok( ret == 7, "got %d\n", ret );
4348 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
4349 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4350 memset( data, 0xaa, sizeof(data) );
4352 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4353 ok( ret == 4, "got %d\n", ret );
4354 ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
4355 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4356 memset( data, 0xaa, sizeof(data) );
4358 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
4359 ok( ret == 5, "got %d\n", ret );
4360 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
4361 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4362 memset( data, 0xaa, sizeof(data) );
4364 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
4365 ok( ret == 5, "got %d\n", ret );
4366 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
4367 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4368 memset( data, 0xaa, sizeof(data) );
4370 info->bmiHeader.biHeight = -16;
4371 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
4372 ok( ret == 8, "got %d\n", ret );
4373 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4374 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4375 memset( data, 0xaa, sizeof(data) );
4377 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4378 ok( ret == 5, "got %d\n", ret );
4379 ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
4380 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4381 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4382 memset( data, 0xaa, sizeof(data) );
4384 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4385 ok( ret == 8, "got %d\n", ret );
4386 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4387 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4388 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4389 memset( data, 0xaa, sizeof(data) );
4391 ret = GetDIBits( hdc, dib, 5, 12, 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 < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4395 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4396 memset( data, 0xaa, sizeof(data) );
4398 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4399 ok( ret == 7, "got %d\n", ret );
4400 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
4401 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4402 memset( data, 0xaa, sizeof(data) );
4404 info->bmiHeader.biHeight = -5;
4405 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4406 ok( ret == 2, "got %d\n", ret );
4407 ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
4408 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4409 memset( data, 0xaa, sizeof(data) );
4414 info->bmiHeader.biHeight = 8;
4416 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4417 ok( ret == 8, "got %d\n", ret );
4418 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4419 memset( data, 0xaa, sizeof(data) );
4421 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4422 ok( ret == 5, "got %d\n", ret );
4423 ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
4424 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4425 memset( data, 0xaa, sizeof(data) );
4427 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4428 ok( ret == 7, "got %d\n", ret );
4429 ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
4430 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4431 memset( data, 0xaa, sizeof(data) );
4433 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4434 ok( ret == 1, "got %d\n", ret );
4435 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4436 memset( data, 0xaa, sizeof(data) );
4438 info->bmiHeader.biHeight = 16;
4439 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4440 ok( ret == 5, "got %d\n", ret );
4441 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4442 ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
4443 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4444 memset( data, 0xaa, sizeof(data) );
4446 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
4447 ok( ret == 6, "got %d\n", ret );
4448 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4449 ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
4450 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4451 memset( data, 0xaa, sizeof(data) );
4453 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
4454 ok( ret == 0, "got %d\n", ret );
4455 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4456 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4457 memset( data, 0xaa, sizeof(data) );
4459 info->bmiHeader.biHeight = 5;
4460 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4461 ok( ret == 2, "got %d\n", ret );
4462 ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
4463 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4464 memset( data, 0xaa, sizeof(data) );
4466 DeleteObject( dib );
4468 ReleaseDC( NULL, hdc );
4469 HeapFree( GetProcessHeap(), 0, info );
4473 static void test_SetDIBits(void)
4475 char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
4476 LOGPALETTE *pal = (LOGPALETTE *)palbuf;
4477 PALETTEENTRY *palent = pal->palPalEntry;
4481 HDC hdc = GetDC( NULL );
4482 DWORD data[128], inverted_data[128];
4486 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4488 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4489 info->bmiHeader.biWidth = 8;
4490 info->bmiHeader.biHeight = 8;
4491 info->bmiHeader.biPlanes = 1;
4492 info->bmiHeader.biBitCount = 32;
4493 info->bmiHeader.biCompression = BI_RGB;
4495 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4496 memset( dib_bits, 0xaa, 64 * 4 );
4498 for (i = 0; i < 128; i++)
4501 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4506 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4507 ok( ret == 8, "got %d\n", ret );
4508 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4509 memset( dib_bits, 0xaa, 64 * 4 );
4511 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4512 ok( ret == 5, "got %d\n", ret );
4513 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4514 ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
4515 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4516 memset( dib_bits, 0xaa, 64 * 4 );
4518 /* top of dst is aligned with startscans down for the top of the src.
4519 Then starting from the bottom of src, lines rows are copied across. */
4521 info->bmiHeader.biHeight = 16;
4522 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4523 ok( ret == 12, "got %d\n", ret );
4524 ok( !memcmp( dib_bits, data + 56, 40 * 4 ), "bits differ\n");
4525 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4526 memset( dib_bits, 0xaa, 64 * 4 );
4528 info->bmiHeader.biHeight = 5;
4529 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4530 ok( ret == 2, "got %d\n", ret );
4531 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4532 ok( !memcmp( dib_bits + 32, data, 16 * 4 ), "bits differ\n");
4533 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4534 memset( dib_bits, 0xaa, 64 * 4 );
4537 info->bmiHeader.biHeight = -8;
4538 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4539 ok( ret == 8, "got %d\n", ret );
4540 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4541 memset( dib_bits, 0xaa, 64 * 4 );
4543 /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
4544 we copy lines rows from the top of the src */
4546 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4547 ok( ret == 5, "got %d\n", ret );
4548 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4549 ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
4550 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4551 memset( dib_bits, 0xaa, 64 * 4 );
4553 info->bmiHeader.biHeight = -16;
4554 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4555 ok( ret == 12, "got %d\n", ret );
4556 ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
4557 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4558 memset( dib_bits, 0xaa, 64 * 4 );
4560 ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4561 ok( ret == 12, "got %d\n", ret );
4562 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4563 memset( dib_bits, 0xaa, 64 * 4 );
4565 ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4566 ok( ret == 12, "got %d\n", ret );
4567 ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
4568 memset( dib_bits, 0xaa, 64 * 4 );
4570 info->bmiHeader.biHeight = -5;
4571 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4572 ok( ret == 2, "got %d\n", ret );
4573 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4574 ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
4575 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4576 memset( dib_bits, 0xaa, 64 * 4 );
4578 DeleteObject( dib );
4580 info->bmiHeader.biHeight = -8;
4582 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4583 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4587 /* like the t-d -> b-u case. */
4589 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4590 ok( ret == 8, "got %d\n", ret );
4591 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4592 memset( dib_bits, 0xaa, 64 * 4 );
4594 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4595 ok( ret == 5, "got %d\n", ret );
4596 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4597 ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
4598 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4599 memset( dib_bits, 0xaa, 64 * 4 );
4601 info->bmiHeader.biHeight = -16;
4602 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4603 ok( ret == 12, "got %d\n", ret );
4604 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4605 ok( !memcmp( dib_bits + 24, data, 40 * 4 ), "bits differ\n");
4606 memset( dib_bits, 0xaa, 64 * 4 );
4608 info->bmiHeader.biHeight = -5;
4609 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4610 ok( ret == 2, "got %d\n", ret );
4611 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4612 ok( !memcmp( dib_bits + 16, data, 16 * 4 ), "bits differ\n");
4613 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4614 memset( dib_bits, 0xaa, 64 * 4 );
4617 /* like the b-u -> b-u case */
4619 info->bmiHeader.biHeight = 8;
4620 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4621 ok( ret == 8, "got %d\n", ret );
4622 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4623 memset( dib_bits, 0xaa, 64 * 4 );
4625 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4626 ok( ret == 5, "got %d\n", ret );
4627 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4628 ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
4629 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4630 memset( dib_bits, 0xaa, 64 * 4 );
4632 info->bmiHeader.biHeight = 16;
4633 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4634 ok( ret == 12, "got %d\n", ret );
4635 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4636 ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
4637 memset( dib_bits, 0xaa, 64 * 4 );
4639 info->bmiHeader.biHeight = 5;
4640 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4641 ok( ret == 2, "got %d\n", ret );
4642 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4643 ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
4644 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4645 memset( dib_bits, 0xaa, 64 * 4 );
4647 /* handling of partial color table */
4649 info->bmiHeader.biHeight = -8;
4650 info->bmiHeader.biBitCount = 8;
4651 info->bmiHeader.biClrUsed = 137;
4652 for (i = 0; i < 256; i++)
4654 info->bmiColors[i].rgbRed = 255 - i;
4655 info->bmiColors[i].rgbGreen = i * 2;
4656 info->bmiColors[i].rgbBlue = i;
4657 info->bmiColors[i].rgbReserved = 0;
4659 for (i = 0; i < 64; i++) ((BYTE *)data)[i] = i * 4 + 1;
4660 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4661 ok( ret == 8, "got %d\n", ret );
4662 for (i = 0; i < 64; i++)
4664 int idx = i * 4 + 1;
4665 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : (info->bmiColors[idx].rgbRed << 16 |
4666 info->bmiColors[idx].rgbGreen << 8 |
4667 info->bmiColors[idx].rgbBlue);
4668 ok( dib_bits[i] == expect, "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
4670 memset( dib_bits, 0xaa, 64 * 4 );
4672 /* handling of DIB_PAL_COLORS */
4674 pal->palVersion = 0x300;
4675 pal->palNumEntries = 137;
4676 info->bmiHeader.biClrUsed = 221;
4677 for (i = 0; i < 256; i++)
4679 palent[i].peRed = i * 2;
4680 palent[i].peGreen = 255 - i;
4681 palent[i].peBlue = i;
4683 palette = CreatePalette( pal );
4684 ok( palette != 0, "palette creation failed\n" );
4685 SelectPalette( hdc, palette, FALSE );
4686 for (i = 0; i < 256; i++) ((WORD *)info->bmiColors)[i] = 255 - i;
4687 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_PAL_COLORS );
4688 ok( ret == 8, "got %d\n", ret );
4689 for (i = 0; i < 64; i++)
4691 int idx = i * 4 + 1;
4692 int ent = (255 - idx) % pal->palNumEntries;
4693 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 :
4694 (palent[ent].peRed << 16 | palent[ent].peGreen << 8 | palent[ent].peBlue);
4695 ok( dib_bits[i] == expect || broken(dib_bits[i] == 0), /* various Windows versions get some values wrong */
4696 "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
4698 memset( dib_bits, 0xaa, 64 * 4 );
4700 ReleaseDC( NULL, hdc );
4701 DeleteObject( dib );
4702 DeleteObject( palette );
4703 HeapFree( GetProcessHeap(), 0, info );
4706 static void test_SetDIBits_RLE4(void)
4710 HDC hdc = GetDC( NULL );
4711 BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00, /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
4712 0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
4713 0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00, /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
4714 0x00, 0x02, 0x01, 0x02, 0x05, 0x87, /* dx=1, dy=2, 8, 7, 8, 7, 8 */
4715 0x00, 0x01 }; /* <eod> */
4718 DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
4719 0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
4720 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4721 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4722 0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
4723 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4724 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4725 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4727 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4729 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4730 info->bmiHeader.biWidth = 8;
4731 info->bmiHeader.biHeight = 8;
4732 info->bmiHeader.biPlanes = 1;
4733 info->bmiHeader.biBitCount = 32;
4734 info->bmiHeader.biCompression = BI_RGB;
4736 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4737 memset( dib_bits, 0xaa, 64 * 4 );
4739 info->bmiHeader.biBitCount = 4;
4740 info->bmiHeader.biCompression = BI_RLE4;
4741 info->bmiHeader.biSizeImage = sizeof(rle4_data);
4743 for (i = 0; i < 16; i++)
4745 info->bmiColors[i].rgbRed = i;
4746 info->bmiColors[i].rgbGreen = i;
4747 info->bmiColors[i].rgbBlue = i;
4748 info->bmiColors[i].rgbReserved = 0;
4751 ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
4752 ok( ret == 8, "got %d\n", ret );
4753 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
4754 memset( dib_bits, 0xaa, 64 * 4 );
4756 DeleteObject( dib );
4757 ReleaseDC( NULL, hdc );
4758 HeapFree( GetProcessHeap(), 0, info );
4761 static void test_SetDIBits_RLE8(void)
4765 HDC hdc = GetDC( NULL );
4766 BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00, /* 2, 2, 2, f0, f0, f0, f0, <eol> */
4767 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4768 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4769 0x00, 0x01 }; /* <eod> */
4772 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4773 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4774 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4775 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4776 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4777 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4778 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4779 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4780 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4781 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4782 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4783 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4784 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4785 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4786 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4787 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4789 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4791 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4792 info->bmiHeader.biWidth = 8;
4793 info->bmiHeader.biHeight = 8;
4794 info->bmiHeader.biPlanes = 1;
4795 info->bmiHeader.biBitCount = 32;
4796 info->bmiHeader.biCompression = BI_RGB;
4798 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4799 memset( dib_bits, 0xaa, 64 * 4 );
4801 info->bmiHeader.biBitCount = 8;
4802 info->bmiHeader.biCompression = BI_RLE8;
4803 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4805 for (i = 0; i < 256; i++)
4807 info->bmiColors[i].rgbRed = i;
4808 info->bmiColors[i].rgbGreen = i;
4809 info->bmiColors[i].rgbBlue = i;
4810 info->bmiColors[i].rgbReserved = 0;
4813 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4814 ok( ret == 8, "got %d\n", ret );
4815 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4816 memset( dib_bits, 0xaa, 64 * 4 );
4818 /* startscan and lines are ignored, unless lines == 0 */
4819 ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4820 ok( ret == 8, "got %d\n", ret );
4821 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4822 memset( dib_bits, 0xaa, 64 * 4 );
4824 ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4825 ok( ret == 8, "got %d\n", ret );
4826 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4827 memset( dib_bits, 0xaa, 64 * 4 );
4829 ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4830 ok( ret == 0, "got %d\n", ret );
4831 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4832 memset( dib_bits, 0xaa, 64 * 4 );
4834 /* reduce width to 4, left-hand side of dst is touched. */
4835 info->bmiHeader.biWidth = 4;
4836 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4837 ok( ret == 8, "got %d\n", ret );
4838 for (i = 0; i < 64; i++)
4840 DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4841 ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4843 memset( dib_bits, 0xaa, 64 * 4 );
4845 /* Show that the top lines are aligned by adjusting the height of the src */
4847 /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4848 info->bmiHeader.biWidth = 8;
4849 info->bmiHeader.biHeight = 4;
4850 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4851 ok( ret == 4, "got %d\n", ret );
4852 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4853 ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4854 memset( dib_bits, 0xaa, 64 * 4 );
4856 /* increase the height to 9 -> everything moves down one row. */
4857 info->bmiHeader.biHeight = 9;
4858 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4859 ok( ret == 9, "got %d\n", ret );
4860 ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4861 for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4862 memset( dib_bits, 0xaa, 64 * 4 );
4864 /* top-down compressed dibs are invalid */
4865 info->bmiHeader.biHeight = -8;
4866 SetLastError( 0xdeadbeef );
4867 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4868 ok( ret == 0, "got %d\n", ret );
4869 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4870 DeleteObject( dib );
4874 info->bmiHeader.biHeight = -8;
4875 info->bmiHeader.biBitCount = 32;
4876 info->bmiHeader.biCompression = BI_RGB;
4877 info->bmiHeader.biSizeImage = 0;
4879 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4880 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4882 info->bmiHeader.biHeight = 8;
4883 info->bmiHeader.biBitCount = 8;
4884 info->bmiHeader.biCompression = BI_RLE8;
4885 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4887 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4888 ok( ret == 8, "got %d\n", ret );
4889 ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4890 memset( dib_bits, 0xaa, 64 * 4 );
4892 info->bmiHeader.biHeight = 4;
4893 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4894 ok( ret == 4, "got %d\n", ret );
4895 ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4896 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4897 memset( dib_bits, 0xaa, 64 * 4 );
4899 info->bmiHeader.biHeight = 9;
4900 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4901 ok( ret == 9, "got %d\n", ret );
4902 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4903 ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4904 memset( dib_bits, 0xaa, 64 * 4 );
4906 DeleteObject( dib );
4907 ReleaseDC( NULL, hdc );
4908 HeapFree( GetProcessHeap(), 0, info );
4911 static void test_SetDIBitsToDevice(void)
4913 char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
4914 LOGPALETTE *pal = (LOGPALETTE *)palbuf;
4915 PALETTEENTRY *palent = pal->palPalEntry;
4919 HDC hdc = CreateCompatibleDC( 0 );
4920 DWORD data[128], inverted_data[128];
4924 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4926 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4927 info->bmiHeader.biWidth = 8;
4928 info->bmiHeader.biHeight = 8;
4929 info->bmiHeader.biPlanes = 1;
4930 info->bmiHeader.biBitCount = 32;
4931 info->bmiHeader.biCompression = BI_RGB;
4933 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4934 memset( dib_bits, 0xaa, 64 * 4 );
4935 SelectObject( hdc, dib );
4937 for (i = 0; i < 128; i++)
4940 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4945 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4946 ok( ret == 8, "got %d\n", ret );
4947 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4948 memset( dib_bits, 0xaa, 64 * 4 );
4950 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4951 ok( ret == 5, "got %d\n", ret );
4952 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4953 for (i = 8; i < 48; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4954 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4955 memset( dib_bits, 0xaa, 64 * 4 );
4957 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 3, 1, 5, data, info, DIB_RGB_COLORS );
4958 ok( ret == 5, "got %d\n", ret );
4959 for (i = 0; i < 24; i++) ok( dib_bits[i] == data[i + 16], "%d: got %08x\n", i, dib_bits[i] );
4960 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4961 memset( dib_bits, 0xaa, 64 * 4 );
4963 info->bmiHeader.biHeight = 16;
4964 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4965 ok( ret == 7, "got %d\n", ret );
4966 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4967 for (i = 8; i < 64; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4968 memset( dib_bits, 0xaa, 64 * 4 );
4970 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 8, 0, 6, 1, 12, data, info, DIB_RGB_COLORS );
4971 ok( ret == 12, "got %d\n", ret );
4972 for (i = 0; i < 40; i++) ok( dib_bits[i] == data[i + 56], "%d: got %08x\n", i, dib_bits[i] );
4973 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4974 memset( dib_bits, 0xaa, 64 * 4 );
4976 ret = SetDIBitsToDevice( hdc, 0, -4, 8, 8, 0, 3, 1, 12, data, info, DIB_RGB_COLORS );
4977 ok( ret == 10, "got %d\n", ret );
4978 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4979 for (i = 32; i < 64; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4980 memset( dib_bits, 0xaa, 64 * 4 );
4982 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, -3, 1, 12, data, info, DIB_RGB_COLORS );
4983 ok( ret == 4, "got %d\n", ret );
4984 for (i = 0; i < 32; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4985 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4986 memset( dib_bits, 0xaa, 64 * 4 );
4988 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 5, 0, -2, 1, 12, data, info, DIB_RGB_COLORS );
4989 ok( ret == 2, "got %d\n", ret );
4990 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4991 for (i = 32; i < 48; i++) ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4992 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4993 memset( dib_bits, 0xaa, 64 * 4 );
4995 info->bmiHeader.biHeight = 5;
4996 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 2, 2, data, info, DIB_RGB_COLORS );
4997 ok( ret == 2, "got %d\n", ret );
4998 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4999 for (i = 16; i < 32; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
5000 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5001 memset( dib_bits, 0xaa, 64 * 4 );
5003 ret = SetDIBitsToDevice( hdc, 3, 3, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
5004 ok( ret == 3, "got %d\n", ret );
5005 for (i = 0; i < 64; i++)
5006 if (i == 27 || i == 28 || i == 35 || i == 36)
5007 ok( dib_bits[i] == data[i - 18], "%d: got %08x\n", i, dib_bits[i] );
5009 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5010 memset( dib_bits, 0xaa, 64 * 4 );
5012 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5013 ok( ret == 5, "got %d\n", ret );
5014 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5015 memset( dib_bits, 0xaa, 64 * 4 );
5017 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
5018 ok( ret == 0, "got %d\n", ret );
5019 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5020 memset( dib_bits, 0xaa, 64 * 4 );
5022 SetMapMode( hdc, MM_ANISOTROPIC );
5023 SetWindowExtEx( hdc, 3, 3, NULL );
5024 ret = SetDIBitsToDevice( hdc, 2, 2, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
5025 ok( ret == 3, "got %d\n", ret );
5026 for (i = 0; i < 64; i++)
5027 if (i == 41 || i == 42 || i == 49 || i == 50)
5028 ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
5030 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5031 memset( dib_bits, 0xaa, 64 * 4 );
5033 SetWindowExtEx( hdc, -1, -1, NULL );
5034 ret = SetDIBitsToDevice( hdc, 2, 2, 4, 4, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
5035 ok( ret == 4, "got %d\n", ret );
5036 for (i = 0; i < 64; i++)
5037 if (i == 48 || i == 49 || i == 56 || i == 57)
5038 ok( dib_bits[i] == data[i - 37], "%d: got %08x\n", i, dib_bits[i] );
5040 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5041 memset( dib_bits, 0xaa, 64 * 4 );
5042 SetMapMode( hdc, MM_TEXT );
5046 pSetLayout( hdc, LAYOUT_RTL );
5047 ret = SetDIBitsToDevice( hdc, 1, 2, 3, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
5048 ok( ret == 3, "got %d\n", ret );
5049 for (i = 0; i < 64; i++)
5050 if (i == 36 || i == 37 || i == 38 || i == 44 || i == 45 || i == 46)
5051 ok( dib_bits[i] == data[i - 27], "%d: got %08x\n", i, dib_bits[i] );
5053 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5054 memset( dib_bits, 0xaa, 64 * 4 );
5055 pSetLayout( hdc, LAYOUT_LTR );
5059 info->bmiHeader.biHeight = -8;
5060 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5061 ok( ret == 8, "got %d\n", ret );
5062 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
5063 memset( dib_bits, 0xaa, 64 * 4 );
5065 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
5066 ok( ret == 5, "got %d\n", ret );
5067 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5068 for (i = 8; i < 48; i++) ok( dib_bits[i] == inverted_data[i + 80], "%d: got %08x\n", i, dib_bits[i] );
5069 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5070 memset( dib_bits, 0xaa, 64 * 4 );
5072 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 4, 1, 5, data, info, DIB_RGB_COLORS );
5073 ok( ret == 5, "got %d\n", ret );
5074 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
5075 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5076 memset( dib_bits, 0xaa, 64 * 4 );
5078 info->bmiHeader.biHeight = -16;
5079 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
5080 ok( ret == 12, "got %d\n", ret );
5081 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5082 for (i = 8; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 24], "%d: got %08x\n", i, dib_bits[i] );
5083 memset( dib_bits, 0xaa, 64 * 4 );
5085 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, 7, 1, 12, data, info, DIB_RGB_COLORS );
5086 ok( ret == 12, "got %d\n", ret );
5087 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
5088 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5089 memset( dib_bits, 0xaa, 64 * 4 );
5091 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 4, 12, data, info, DIB_RGB_COLORS );
5092 ok( ret == 12, "got %d\n", ret );
5093 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5094 for (i = 32; i < 64; i++) ok( dib_bits[i] == inverted_data[i], "%d: got %08x\n", i, dib_bits[i] );
5095 memset( dib_bits, 0xaa, 64 * 4 );
5097 ret = SetDIBitsToDevice( hdc, 0, -3, 8, 8, 0, 2, 4, 12, data, info, DIB_RGB_COLORS );
5098 ok( ret == 12, "got %d\n", ret );
5099 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5100 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5101 memset( dib_bits, 0xaa, 64 * 4 );
5103 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, -2, 4, 12, data, info, DIB_RGB_COLORS );
5104 ok( ret == 12, "got %d\n", ret );
5105 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5106 for (i = 24; i < 40; i++) ok( dib_bits[i] == inverted_data[i + 8], "%d: got %08x\n", i, dib_bits[i] );
5107 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5108 memset( dib_bits, 0xaa, 64 * 4 );
5110 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 5, 12, data, info, DIB_RGB_COLORS );
5111 ok( ret == 12, "got %d\n", ret );
5112 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5113 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5114 memset( dib_bits, 0xaa, 64 * 4 );
5116 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
5117 ok( ret == 12, "got %d\n", ret );
5118 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5119 memset( dib_bits, 0xaa, 64 * 4 );
5121 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -2, -4, 0, 12, data, info, DIB_RGB_COLORS );
5122 ok( ret == 12, "got %d\n", ret );
5123 for (i = 0; i < 64; i++)
5124 if (i == 31 || i == 39 || i == 47 || i == 55 || i == 63)
5125 ok( dib_bits[i] == inverted_data[i + 1], "%d: got %08x\n", i, dib_bits[i] );
5127 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5128 memset( dib_bits, 0xaa, 64 * 4 );
5130 info->bmiHeader.biHeight = -5;
5131 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
5132 ok( ret == 2, "got %d\n", ret );
5133 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5134 for (i = 8; i < 24; i++) ok( dib_bits[i] == inverted_data[i + 104], "%d: got %08x\n", i, dib_bits[i] );
5135 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5136 memset( dib_bits, 0xaa, 64 * 4 );
5138 ret = SetDIBitsToDevice( hdc, 5, 4, 2, 2, 6, 3, 1, 5, data, info, DIB_RGB_COLORS );
5139 ok( ret == 5, "got %d\n", ret );
5140 for (i = 0; i < 64; i++)
5141 if (i == 21 || i == 22 || i == 29 || i == 30)
5142 ok( dib_bits[i] == inverted_data[i + 89], "%d: got %08x\n", i, dib_bits[i] );
5144 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5145 memset( dib_bits, 0xaa, 64 * 4 );
5147 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5148 ok( ret == 5, "got %d\n", ret );
5149 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5150 memset( dib_bits, 0xaa, 64 * 4 );
5152 info->bmiHeader.biHeight = -8;
5154 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5155 DeleteObject( SelectObject( hdc, dib ));
5156 memset( dib_bits, 0xaa, 16 * 16 * 4 );
5160 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5161 ok( ret == 8, "got %d\n", ret );
5162 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
5163 memset( dib_bits, 0xaa, 64 * 4 );
5165 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
5166 ok( ret == 5, "got %d\n", ret );
5167 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5168 for (i = 16; i < 56; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
5169 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5170 memset( dib_bits, 0xaa, 64 * 4 );
5172 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 3, 0, 2, 1, 5, data, info, DIB_RGB_COLORS );
5173 ok( ret == 5, "got %d\n", ret );
5174 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5175 for (i = 24; i < 48; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
5176 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5177 memset( dib_bits, 0xaa, 64 * 4 );
5179 info->bmiHeader.biHeight = -16;
5180 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
5181 ok( ret == 12, "got %d\n", ret );
5182 for (i = 0; i < 56; i++) ok( dib_bits[i] == data[i + 40], "%d: got %08x\n", i, dib_bits[i] );
5183 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5184 memset( dib_bits, 0xaa, 64 * 4 );
5186 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -1, -8, 0, 12, data, info, DIB_RGB_COLORS );
5187 ok( ret == 12, "got %d\n", ret );
5188 for (i = 0; i < 64; i++)
5189 if (i == 6 || i == 7)
5190 ok( dib_bits[i] == data[i + 82], "%d: got %08x\n", i, dib_bits[i] );
5192 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5193 memset( dib_bits, 0xaa, 64 * 4 );
5195 info->bmiHeader.biHeight = -5;
5196 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
5197 ok( ret == 2, "got %d\n", ret );
5198 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5199 for (i = 40; i < 56; i++) ok( dib_bits[i] == data[i - 40], "%d: got %08x\n", i, dib_bits[i] );
5200 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5201 memset( dib_bits, 0xaa, 64 * 4 );
5203 ret = SetDIBitsToDevice( hdc, 7, 2, 8, 8, 1, 0, 0, 5, data, info, DIB_RGB_COLORS );
5204 ok( ret == 5, "got %d\n", ret );
5205 for (i = 0; i < 64; i++)
5206 if (i == 47 || i == 55 || i == 63)
5207 ok( dib_bits[i] == data[i - 46], "%d: got %08x\n", i, dib_bits[i] );
5209 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5210 memset( dib_bits, 0xaa, 64 * 4 );
5212 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5213 ok( ret == 5, "got %d\n", ret );
5214 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5215 memset( dib_bits, 0xaa, 64 * 4 );
5219 info->bmiHeader.biHeight = 8;
5220 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5221 ok( ret == 8, "got %d\n", ret );
5222 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
5223 memset( dib_bits, 0xaa, 64 * 4 );
5225 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
5226 ok( ret == 5, "got %d\n", ret );
5227 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5228 for (i = 16; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
5229 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5230 memset( dib_bits, 0xaa, 64 * 4 );
5232 info->bmiHeader.biHeight = 16;
5233 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
5234 ok( ret == 7, "got %d\n", ret );
5235 for (i = 0; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
5236 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5237 memset( dib_bits, 0xaa, 64 * 4 );
5239 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, 0, -4, 1, 12, data, info, DIB_RGB_COLORS );
5240 ok( ret == 3, "got %d\n", ret );
5241 for (i = 0; i < 64; i++)
5242 if ((i >= 36 && i <= 39) || (i >= 44 && i <= 47) || (i >= 52 && i <= 55))
5243 ok( dib_bits[i] == inverted_data[i + 68], "%d: got %08x\n", i, dib_bits[i] );
5245 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5246 memset( dib_bits, 0xaa, 64 * 4 );
5248 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, -30, -30, 1, 12, data, info, DIB_RGB_COLORS );
5249 ok( ret == 0, "got %d\n", ret );
5250 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5251 memset( dib_bits, 0xaa, 64 * 4 );
5253 ret = SetDIBitsToDevice( hdc, 5, -5, 8, 16, -2, -4, 4, 12, data, info, DIB_RGB_COLORS );
5254 ok( ret == 8, "got %d\n", ret );
5255 for (i = 0; i < 64; i++)
5256 if (i == 7 || i == 15 || i == 23)
5257 ok( dib_bits[i] == inverted_data[i + 97], "%d: got %08x\n", i, dib_bits[i] );
5259 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5260 memset( dib_bits, 0xaa, 64 * 4 );
5262 info->bmiHeader.biHeight = 5;
5263 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
5264 ok( ret == 2, "got %d\n", ret );
5265 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5266 for (i = 40; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
5267 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5268 memset( dib_bits, 0xaa, 64 * 4 );
5270 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5271 ok( ret == 5, "got %d\n", ret );
5272 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5273 memset( dib_bits, 0xaa, 64 * 4 );
5275 /* handling of partial color table */
5277 info->bmiHeader.biHeight = -8;
5278 info->bmiHeader.biBitCount = 8;
5279 info->bmiHeader.biClrUsed = 137;
5280 for (i = 0; i < 256; i++)
5282 info->bmiColors[i].rgbRed = 255 - i;
5283 info->bmiColors[i].rgbGreen = i * 2;
5284 info->bmiColors[i].rgbBlue = i;
5285 info->bmiColors[i].rgbReserved = 0;
5287 for (i = 0; i < 64; i++) ((BYTE *)data)[i] = i * 4 + 1;
5288 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5289 ok( ret == 8, "got %d\n", ret );
5290 for (i = 0; i < 64; i++)
5292 int idx = i * 4 + 1;
5293 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : (info->bmiColors[idx].rgbRed << 16 |
5294 info->bmiColors[idx].rgbGreen << 8 |
5295 info->bmiColors[idx].rgbBlue);
5296 ok( dib_bits[i] == expect, "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
5298 memset( dib_bits, 0xaa, 64 * 4 );
5300 /* handling of DIB_PAL_COLORS */
5302 pal->palVersion = 0x300;
5303 pal->palNumEntries = 137;
5304 info->bmiHeader.biClrUsed = 221;
5305 for (i = 0; i < 256; i++)
5307 palent[i].peRed = i * 2;
5308 palent[i].peGreen = 255 - i;
5309 palent[i].peBlue = i;
5311 palette = CreatePalette( pal );
5312 ok( palette != 0, "palette creation failed\n" );
5313 SelectPalette( hdc, palette, FALSE );
5314 for (i = 0; i < 256; i++) ((WORD *)info->bmiColors)[i] = 255 - i;
5315 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_PAL_COLORS );
5316 ok( ret == 8, "got %d\n", ret );
5317 for (i = 0; i < 64; i++)
5319 int idx = i * 4 + 1;
5320 int ent = (255 - idx) % pal->palNumEntries;
5321 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 :
5322 (palent[ent].peRed << 16 | palent[ent].peGreen << 8 | palent[ent].peBlue);
5323 ok( dib_bits[i] == expect || broken(dib_bits[i] == 0),
5324 "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
5326 memset( dib_bits, 0xaa, 64 * 4 );
5329 DeleteObject( dib );
5330 DeleteObject( palette );
5331 HeapFree( GetProcessHeap(), 0, info );
5334 static void test_SetDIBitsToDevice_RLE8(void)
5338 HDC hdc = CreateCompatibleDC( 0 );
5339 BYTE rle8_data[20] = { 0x04, 0x02, 0x03, 0xf0, 0x00, 0x00, /* 2, 2, 2, 2, f0, f0, f0, <eol> */
5340 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
5341 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
5342 0x00, 0x01 }; /* <eod> */
5345 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
5346 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5347 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5348 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
5349 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5350 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5351 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5352 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
5353 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5354 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5355 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5356 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5357 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
5358 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5359 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5360 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
5362 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
5364 info->bmiHeader.biSize = sizeof(info->bmiHeader);
5365 info->bmiHeader.biWidth = 8;
5366 info->bmiHeader.biHeight = 8;
5367 info->bmiHeader.biPlanes = 1;
5368 info->bmiHeader.biBitCount = 32;
5369 info->bmiHeader.biCompression = BI_RGB;
5371 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5372 memset( dib_bits, 0xaa, 64 * 4 );
5373 SelectObject( hdc, dib );
5375 info->bmiHeader.biBitCount = 8;
5376 info->bmiHeader.biCompression = BI_RLE8;
5377 info->bmiHeader.biSizeImage = sizeof(rle8_data);
5379 for (i = 0; i < 256; i++)
5381 info->bmiColors[i].rgbRed = i;
5382 info->bmiColors[i].rgbGreen = i;
5383 info->bmiColors[i].rgbBlue = i;
5384 info->bmiColors[i].rgbReserved = 0;
5387 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5388 ok( ret == 8, "got %d\n", ret );
5389 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5390 memset( dib_bits, 0xaa, 64 * 4 );
5392 /* startscan and lines are ignored, unless lines == 0 */
5393 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 8, rle8_data, info, DIB_RGB_COLORS );
5394 ok( ret == 8, "got %d\n", ret );
5395 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5396 memset( dib_bits, 0xaa, 64 * 4 );
5398 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 1, rle8_data, info, DIB_RGB_COLORS );
5399 ok( ret == 8, "got %d\n", ret );
5400 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5401 memset( dib_bits, 0xaa, 64 * 4 );
5403 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 0, rle8_data, info, DIB_RGB_COLORS );
5404 ok( ret == 0, "got %d\n", ret );
5405 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5406 memset( dib_bits, 0xaa, 64 * 4 );
5408 info->bmiHeader.biWidth = 2;
5409 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5410 ok( ret == 8, "got %d\n", ret );
5411 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5412 memset( dib_bits, 0xaa, 64 * 4 );
5414 info->bmiHeader.biWidth = 8;
5415 info->bmiHeader.biHeight = 2;
5416 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5417 ok( ret == 2, "got %d\n", ret );
5418 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5419 memset( dib_bits, 0xaa, 64 * 4 );
5421 info->bmiHeader.biHeight = 9;
5422 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5423 ok( ret == 9, "got %d\n", ret );
5424 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5425 memset( dib_bits, 0xaa, 64 * 4 );
5427 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5428 ok( ret == 9, "got %d\n", ret );
5429 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5430 memset( dib_bits, 0xaa, 64 * 4 );
5432 info->bmiHeader.biHeight = 8;
5433 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 9, rle8_data, info, DIB_RGB_COLORS );
5434 ok( ret == 8, "got %d\n", ret );
5435 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5436 memset( dib_bits, 0xaa, 64 * 4 );
5438 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5439 ok( ret == 8, "got %d\n", ret );
5440 for (i = 0; i < 40; i++) ok( dib_bits[i] == bottom_up[i + 24], "%d: got %08x\n", i, dib_bits[i] );
5441 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5442 memset( dib_bits, 0xaa, 64 * 4 );
5444 ret = SetDIBitsToDevice( hdc, 0, 3, 4, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5445 ok( ret == 8, "got %d\n", ret );
5446 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5447 for (i = 8; i < 40; i++)
5448 if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5449 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5450 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5451 memset( dib_bits, 0xaa, 64 * 4 );
5453 ret = SetDIBitsToDevice( hdc, 3, 3, 8, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5454 ok( ret == 8, "got %d\n", ret );
5455 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5456 for (i = 8; i < 40; i++)
5457 if ((i & 7) < 3) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5458 else ok( dib_bits[i] == bottom_up[i - 11], "%d: got %08x\n", i, dib_bits[i] );
5459 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5460 memset( dib_bits, 0xaa, 64 * 4 );
5462 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 4, 2, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5463 ok( ret == 8, "got %d\n", ret );
5464 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5465 for (i = 8; i < 40; i++)
5466 if ((i & 7) < 2) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5467 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5468 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5469 memset( dib_bits, 0xaa, 64 * 4 );
5471 info->bmiHeader.biWidth = 37;
5472 info->bmiHeader.biHeight = 37;
5473 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
5474 ok( ret == 37, "got %d\n", ret );
5475 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5476 for (i = 24; i < 64; i++)
5477 if (i == 52) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
5478 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5479 else ok( dib_bits[i] == bottom_up[i - 20], "%d: got %08x\n", i, dib_bits[i] );
5480 memset( dib_bits, 0xaa, 64 * 4 );
5482 /* top-down compressed dibs are invalid */
5483 info->bmiHeader.biWidth = 8;
5484 info->bmiHeader.biHeight = -8;
5485 SetLastError( 0xdeadbeef );
5486 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5487 ok( ret == 0, "got %d\n", ret );
5488 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
5492 info->bmiHeader.biHeight = -8;
5493 info->bmiHeader.biBitCount = 32;
5494 info->bmiHeader.biCompression = BI_RGB;
5495 info->bmiHeader.biSizeImage = 0;
5497 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5498 memset( dib_bits, 0xaa, 16 * 16 * 4 );
5499 DeleteObject( SelectObject( hdc, dib ));
5501 info->bmiHeader.biHeight = 8;
5502 info->bmiHeader.biBitCount = 8;
5503 info->bmiHeader.biCompression = BI_RLE8;
5504 info->bmiHeader.biSizeImage = sizeof(rle8_data);
5506 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5507 ok( ret == 8, "got %d\n", ret );
5508 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5509 memset( dib_bits, 0xaa, 64 * 4 );
5511 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5512 ok( ret == 8, "got %d\n", ret );
5513 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5514 memset( dib_bits, 0xaa, 64 * 4 );
5516 info->bmiHeader.biHeight = 4;
5517 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5518 ok( ret == 4, "got %d\n", ret );
5519 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5520 memset( dib_bits, 0xaa, 64 * 4 );
5522 info->bmiHeader.biHeight = 9;
5523 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5524 ok( ret == 9, "got %d\n", ret );
5525 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5526 memset( dib_bits, 0xaa, 64 * 4 );
5528 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5529 ok( ret == 9, "got %d\n", ret );
5530 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5531 memset( dib_bits, 0xaa, 64 * 4 );
5533 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 6, 2, 2, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5534 ok( ret == 9, "got %d\n", ret );
5535 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5536 for (i = 24; i < 64; i++) ok( dib_bits[i] == top_down[i - 24], "%d: got %08x\n", i, dib_bits[i] );
5537 memset( dib_bits, 0xaa, 64 * 4 );
5539 info->bmiHeader.biWidth = 37;
5540 info->bmiHeader.biHeight = 37;
5541 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
5542 ok( ret == 37, "got %d\n", ret );
5543 for (i = 0; i < 40; i++)
5544 if (i == 12) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
5545 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5546 else ok( dib_bits[i] == top_down[i + 28], "%d: got %08x\n", i, dib_bits[i] );
5547 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5548 memset( dib_bits, 0xaa, 64 * 4 );
5551 DeleteObject( dib );
5552 HeapFree( GetProcessHeap(), 0, info );
5559 hdll = GetModuleHandle("gdi32.dll");
5560 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
5561 pGdiGradientFill = (void*)GetProcAddress(hdll, "GdiGradientFill");
5562 pSetLayout = (void*)GetProcAddress(hdll, "SetLayout");
5564 test_createdibitmap();
5567 test_mono_dibsection();
5571 test_GetDIBits_selected_DIB(1);
5572 test_GetDIBits_selected_DIB(4);
5573 test_GetDIBits_selected_DIB(8);
5574 test_GetDIBits_selected_DDB(TRUE);
5575 test_GetDIBits_selected_DDB(FALSE);
5577 test_GetDIBits_BI_BITFIELDS();
5578 test_select_object();
5579 test_CreateBitmap();
5582 test_StretchDIBits();
5583 test_GdiAlphaBlend();
5584 test_GdiGradientFill();
5586 test_bitmapinfoheadersize();
5589 test_GetDIBits_top_down(16);
5590 test_GetDIBits_top_down(24);
5591 test_GetDIBits_top_down(32);
5592 test_GetSetDIBits_rtl();
5593 test_GetDIBits_scanlines();
5595 test_SetDIBits_RLE4();
5596 test_SetDIBits_RLE8();
5597 test_SetDIBitsToDevice();
5598 test_SetDIBitsToDevice_RLE8();