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