2 * Unit test suite for bitmaps
4 * Copyright 2004 Huw Davies
5 * Copyright 2006 Dmitry Timoshkov
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
33 #include "wine/test.h"
35 static BOOL (WINAPI *pGdiAlphaBlend)(HDC,int,int,int,int,HDC,int,int,int,int,BLENDFUNCTION);
36 static BOOL (WINAPI *pGdiGradientFill)(HDC,TRIVERTEX*,ULONG,void*,ULONG,ULONG);
37 static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
39 static inline int get_bitmap_stride( int width, int bpp )
41 return ((width * bpp + 15) >> 3) & ~1;
44 static inline int get_dib_stride( int width, int bpp )
46 return ((width * bpp + 31) >> 3) & ~3;
49 static inline int get_dib_image_size( const BITMAPINFO *info )
51 return get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount )
52 * abs( info->bmiHeader.biHeight );
55 static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHEADER *bmih)
60 BYTE buf[512], buf_cmp[512];
62 ret = GetObject(hbm, sizeof(bm), &bm);
63 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
65 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
66 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
67 ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
68 width_bytes = get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel);
69 ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
70 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
71 ok(bm.bmBitsPixel == expected_depth, "wrong bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, expected_depth);
72 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
74 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
75 assert(sizeof(buf) == sizeof(buf_cmp));
77 SetLastError(0xdeadbeef);
78 ret = GetBitmapBits(hbm, 0, NULL);
79 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
81 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
82 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
84 memset(buf, 0xAA, sizeof(buf));
85 ret = GetBitmapBits(hbm, sizeof(buf), buf);
86 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
87 ok(!memcmp(buf, buf_cmp, sizeof(buf)),
88 "buffers do not match, depth %d\n", bmih->biBitCount);
90 /* test various buffer sizes for GetObject */
91 ret = GetObject(hbm, sizeof(*bma) * 2, bma);
92 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
94 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
95 ok(ret == 0, "%d != 0\n", ret);
97 ret = GetObject(hbm, 0, &bm);
98 ok(ret == 0, "%d != 0\n", ret);
100 ret = GetObject(hbm, 1, &bm);
101 ok(ret == 0, "%d != 0\n", ret);
103 ret = GetObject(hbm, 0, NULL);
104 ok(ret == sizeof(bm), "wrong size %d\n", ret);
107 static void test_createdibitmap(void)
110 BITMAPINFOHEADER bmih;
112 HBITMAP hbm, hbm_colour, hbm_old;
117 screen_depth = GetDeviceCaps(hdc, BITSPIXEL);
118 memset(&bmih, 0, sizeof(bmih));
119 bmih.biSize = sizeof(bmih);
123 bmih.biBitCount = 32;
124 bmih.biCompression = BI_RGB;
126 hbm = CreateDIBitmap(hdc, NULL, CBM_INIT, NULL, NULL, 0);
127 ok(hbm == NULL, "CreateDIBitmap should fail\n");
128 hbm = CreateDIBitmap(hdc, NULL, 0, NULL, NULL, 0);
129 ok(hbm == NULL, "CreateDIBitmap should fail\n");
131 /* First create an un-initialised bitmap. The depth of the bitmap
132 should match that of the hdc and not that supplied in bmih.
135 /* First try 32 bits */
136 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
137 ok(hbm != NULL, "CreateDIBitmap failed\n");
138 test_bitmap_info(hbm, screen_depth, &bmih);
142 bmih.biBitCount = 16;
143 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
144 ok(hbm != NULL, "CreateDIBitmap failed\n");
145 test_bitmap_info(hbm, screen_depth, &bmih);
150 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
151 ok(hbm != NULL, "CreateDIBitmap failed\n");
152 test_bitmap_info(hbm, screen_depth, &bmih);
155 /* Now with a monochrome dc we expect a monochrome bitmap */
156 hdcmem = CreateCompatibleDC(hdc);
158 /* First try 32 bits */
159 bmih.biBitCount = 32;
160 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
161 ok(hbm != NULL, "CreateDIBitmap failed\n");
162 test_bitmap_info(hbm, 1, &bmih);
166 bmih.biBitCount = 16;
167 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
168 ok(hbm != NULL, "CreateDIBitmap failed\n");
169 test_bitmap_info(hbm, 1, &bmih);
174 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
175 ok(hbm != NULL, "CreateDIBitmap failed\n");
176 test_bitmap_info(hbm, 1, &bmih);
179 /* Now select a polychrome bitmap into the dc and we expect
180 screen_depth bitmaps again */
181 hbm_colour = CreateCompatibleBitmap(hdc, bmih.biWidth, bmih.biHeight);
182 test_bitmap_info(hbm_colour, screen_depth, &bmih);
183 hbm_old = SelectObject(hdcmem, hbm_colour);
185 /* First try 32 bits */
186 bmih.biBitCount = 32;
187 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
188 ok(hbm != NULL, "CreateDIBitmap failed\n");
189 test_bitmap_info(hbm, screen_depth, &bmih);
193 bmih.biBitCount = 16;
194 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
195 ok(hbm != NULL, "CreateDIBitmap failed\n");
196 test_bitmap_info(hbm, screen_depth, &bmih);
201 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
202 ok(hbm != NULL, "CreateDIBitmap failed\n");
203 test_bitmap_info(hbm, screen_depth, &bmih);
206 SelectObject(hdcmem, hbm_old);
207 DeleteObject(hbm_colour);
210 bmih.biBitCount = 32;
211 hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0);
212 ok(hbm != NULL, "CreateDIBitmap failed\n");
213 test_bitmap_info(hbm, 1, &bmih);
216 /* Test how formats are converted */
222 memset(&bm, 0, sizeof(bm));
223 bm.bmiHeader.biSize = sizeof(bm.bmiHeader);
224 bm.bmiHeader.biWidth = 1;
225 bm.bmiHeader.biHeight = 1;
226 bm.bmiHeader.biPlanes = 1;
227 bm.bmiHeader.biBitCount= 24;
228 bm.bmiHeader.biCompression= BI_RGB;
229 bm.bmiHeader.biSizeImage = 0;
230 hbm = CreateDIBitmap(hdc, &bmih, CBM_INIT, &pixel, &bm, DIB_RGB_COLORS);
231 ok(hbm != NULL, "CreateDIBitmap failed\n");
234 bm.bmiHeader.biBitCount= 32;
235 GetDIBits(hdc, hbm, 0, 1, &pixel, &bm, DIB_RGB_COLORS);
236 ok(pixel == 0x00ffffff, "Reading a 32 bit pixel from a DDB returned %08x\n", pixel);
242 static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
248 INT ret, bm_width_bytes, dib_width_bytes;
251 ret = GetObject(hbm, sizeof(bm), &bm);
252 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
254 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
255 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
256 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
257 dib_width_bytes = get_dib_stride(bm.bmWidth, bm.bmBitsPixel);
258 bm_width_bytes = get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel);
259 if (bm.bmWidthBytes != dib_width_bytes) /* Win2k bug */
260 ok(bm.bmWidthBytes == bm_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, bm_width_bytes);
262 ok(bm.bmWidthBytes == dib_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, dib_width_bytes);
263 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
264 ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount);
265 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
267 buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);
269 /* GetBitmapBits returns not 32-bit aligned data */
270 SetLastError(0xdeadbeef);
271 ret = GetBitmapBits(hbm, 0, NULL);
272 ok(ret == bm_width_bytes * bm.bmHeight,
273 "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
275 memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
276 ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
277 ok(ret == bm_width_bytes * bm.bmHeight, "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
279 HeapFree(GetProcessHeap(), 0, buf);
281 /* test various buffer sizes for GetObject */
282 memset(&ds, 0xAA, sizeof(ds));
283 ret = GetObject(hbm, sizeof(*bma) * 2, bma);
284 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
285 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
286 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
287 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
289 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
290 ok(ret == 0, "%d != 0\n", ret);
292 ret = GetObject(hbm, 0, &bm);
293 ok(ret == 0, "%d != 0\n", ret);
295 ret = GetObject(hbm, 1, &bm);
296 ok(ret == 0, "%d != 0\n", ret);
298 /* test various buffer sizes for GetObject */
299 ret = GetObject(hbm, 0, NULL);
300 ok(ret == sizeof(bm), "wrong size %d\n", ret);
302 ret = GetObject(hbm, sizeof(*dsa) * 2, dsa);
303 ok(ret == sizeof(*dsa), "wrong size %d\n", ret);
305 memset(&ds, 0xAA, sizeof(ds));
306 ret = GetObject(hbm, sizeof(ds), &ds);
307 ok(ret == sizeof(ds), "wrong size %d\n", ret);
309 ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
310 if (ds.dsBm.bmWidthBytes != bm_width_bytes) /* Win2k bug */
311 ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%u != %u\n",
312 ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
313 ok(bmih->biSizeImage == 0, "%u != 0\n", bmih->biSizeImage);
314 ds.dsBmih.biSizeImage = 0;
316 ok(ds.dsBmih.biSize == bmih->biSize, "%u != %u\n", ds.dsBmih.biSize, bmih->biSize);
317 ok(ds.dsBmih.biWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
318 ok(ds.dsBmih.biHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
319 ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes);
320 ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount);
321 ok(ds.dsBmih.biCompression == bmih->biCompression ||
322 ((bmih->biBitCount == 32) && broken(ds.dsBmih.biCompression == BI_BITFIELDS)), /* nt4 sp1 and 2 */
323 "%u != %u\n", ds.dsBmih.biCompression, bmih->biCompression);
324 ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%u != %u\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
325 ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%d != %d\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
326 ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%d != %d\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);
328 memset(&ds, 0xAA, sizeof(ds));
329 ret = GetObject(hbm, sizeof(ds) - 4, &ds);
330 ok(ret == sizeof(ds.dsBm), "wrong size %d\n", ret);
331 ok(ds.dsBm.bmWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
332 ok(ds.dsBm.bmHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
333 ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);
335 ret = GetObject(hbm, 0, &ds);
336 ok(ret == 0, "%d != 0\n", ret);
338 ret = GetObject(hbm, 1, &ds);
339 ok(ret == 0, "%d != 0\n", ret);
342 #define test_color(hdc, color, exp) \
345 c = SetPixel(hdc, 0, 0, color); \
346 ok(c == exp, "SetPixel failed: got 0x%06x expected 0x%06x\n", c, (UINT)exp); \
347 c = GetPixel(hdc, 0, 0); \
348 ok(c == exp, "GetPixel failed: got 0x%06x expected 0x%06x\n", c, (UINT)exp); \
349 c = GetNearestColor(hdc, color); \
350 ok(c == exp, "GetNearestColor failed: got 0x%06x expected 0x%06x\n", c, (UINT)exp); \
353 static void test_dib_bits_access( HBITMAP hdib, void *bits )
355 MEMORY_BASIC_INFORMATION info;
356 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
358 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
360 char filename[MAX_PATH];
365 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
366 "VirtualQuery failed\n");
367 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
368 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
369 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
370 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
371 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
372 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
374 memset( pbmi, 0, sizeof(bmibuf) );
375 memset( data, 0xcc, sizeof(data) );
376 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
377 pbmi->bmiHeader.biHeight = 16;
378 pbmi->bmiHeader.biWidth = 16;
379 pbmi->bmiHeader.biBitCount = 32;
380 pbmi->bmiHeader.biPlanes = 1;
381 pbmi->bmiHeader.biCompression = BI_RGB;
385 ret = SetDIBits( hdc, hdib, 0, 16, data, pbmi, DIB_RGB_COLORS );
386 ok(ret == 16, "SetDIBits failed: expected 16 got %d\n", ret);
390 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
391 "VirtualQuery failed\n");
392 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
393 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
394 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
395 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
396 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
397 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
399 /* try writing protected bits to a file */
401 GetTempFileNameA( ".", "dib", 0, filename );
402 file = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
403 CREATE_ALWAYS, 0, 0 );
404 ok( file != INVALID_HANDLE_VALUE, "failed to open %s error %u\n", filename, GetLastError() );
405 ret = WriteFile( file, bits, 8192, &written, NULL );
406 ok( ret, "WriteFile failed error %u\n", GetLastError() );
407 if (ret) ok( written == 8192, "only wrote %u bytes\n", written );
409 DeleteFileA( filename );
412 static void test_dibsections(void)
414 HDC hdc, hdcmem, hdcmem2;
415 HBITMAP hdib, oldbm, hdib2, oldbm2;
416 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
417 char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
418 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
419 BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
420 RGBQUAD *colors = pbmi->bmiColors;
421 RGBTRIPLE *ccolors = pbci->bmciColors;
427 char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
428 LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
429 PALETTEENTRY *palent = plogpal->palPalEntry;
432 HPALETTE hpal, oldpal;
436 MEMORY_BASIC_INFORMATION info;
440 memset(pbmi, 0, sizeof(bmibuf));
441 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
442 pbmi->bmiHeader.biHeight = 100;
443 pbmi->bmiHeader.biWidth = 512;
444 pbmi->bmiHeader.biBitCount = 24;
445 pbmi->bmiHeader.biPlanes = 1;
446 pbmi->bmiHeader.biCompression = BI_RGB;
448 SetLastError(0xdeadbeef);
450 /* invalid pointer for BITMAPINFO
451 (*bits should be NULL on error) */
452 bits = (BYTE*)0xdeadbeef;
453 hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
454 ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n");
456 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
457 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
458 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
459 ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
461 /* test the DIB memory */
462 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
463 "VirtualQuery failed\n");
464 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
465 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
466 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
467 ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
468 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
469 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
470 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
472 test_dib_bits_access( hdib, bits );
474 test_dib_info(hdib, bits, &pbmi->bmiHeader);
477 /* Test a top-down DIB. */
478 pbmi->bmiHeader.biHeight = -100;
479 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
480 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
481 test_dib_info(hdib, bits, &pbmi->bmiHeader);
484 pbmi->bmiHeader.biHeight = 100;
485 pbmi->bmiHeader.biBitCount = 8;
486 pbmi->bmiHeader.biCompression = BI_RLE8;
487 SetLastError(0xdeadbeef);
488 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
489 ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
490 ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
492 pbmi->bmiHeader.biBitCount = 16;
493 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
494 ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
495 ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
496 ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
497 SetLastError(0xdeadbeef);
498 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
499 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
501 /* test the DIB memory */
502 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
503 "VirtualQuery failed\n");
504 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
505 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
506 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
507 ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
508 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
509 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
510 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
512 test_dib_info(hdib, bits, &pbmi->bmiHeader);
515 memset(pbmi, 0, sizeof(bmibuf));
516 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
517 pbmi->bmiHeader.biHeight = 16;
518 pbmi->bmiHeader.biWidth = 16;
519 pbmi->bmiHeader.biBitCount = 1;
520 pbmi->bmiHeader.biPlanes = 1;
521 pbmi->bmiHeader.biCompression = BI_RGB;
522 colors[0].rgbRed = 0xff;
523 colors[0].rgbGreen = 0;
524 colors[0].rgbBlue = 0;
525 colors[1].rgbRed = 0;
526 colors[1].rgbGreen = 0;
527 colors[1].rgbBlue = 0xff;
529 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
530 ok(hdib != NULL, "CreateDIBSection failed\n");
531 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
532 ok(dibsec.dsBmih.biClrUsed == 2,
533 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
535 /* Test if the old BITMAPCOREINFO structure is supported */
537 pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
538 pbci->bmciHeader.bcBitCount = 0;
540 ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
541 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
542 ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
543 && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
544 "GetDIBits didn't fill in the BITMAPCOREHEADER structure properly\n");
546 ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
547 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
548 ok((ccolors[0].rgbtRed == 0xff) && (ccolors[0].rgbtGreen == 0) &&
549 (ccolors[0].rgbtBlue == 0) && (ccolors[1].rgbtRed == 0) &&
550 (ccolors[1].rgbtGreen == 0) && (ccolors[1].rgbtBlue == 0xff),
551 "The color table has not been translated to the old BITMAPCOREINFO format\n");
553 hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
554 ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
556 ZeroMemory(ccolors, 256 * sizeof(RGBTRIPLE));
557 ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
558 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
559 ok((ccolors[0].rgbtRed == 0xff) && (ccolors[0].rgbtGreen == 0) &&
560 (ccolors[0].rgbtBlue == 0) && (ccolors[1].rgbtRed == 0) &&
561 (ccolors[1].rgbtGreen == 0) && (ccolors[1].rgbtBlue == 0xff),
562 "The color table has not been translated to the old BITMAPCOREINFO format\n");
564 DeleteObject(hcoredib);
566 hdcmem = CreateCompatibleDC(hdc);
567 oldbm = SelectObject(hdcmem, hdib);
569 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
570 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
571 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
572 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
573 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
574 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
576 c0 = RGB(colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue);
577 c1 = RGB(colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue);
579 test_color(hdcmem, DIBINDEX(0), c0);
580 test_color(hdcmem, DIBINDEX(1), c1);
581 test_color(hdcmem, DIBINDEX(2), c0);
582 test_color(hdcmem, PALETTEINDEX(0), c0);
583 test_color(hdcmem, PALETTEINDEX(1), c0);
584 test_color(hdcmem, PALETTEINDEX(2), c0);
585 test_color(hdcmem, PALETTERGB(colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue), c0);
586 test_color(hdcmem, PALETTERGB(colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue), c1);
587 test_color(hdcmem, PALETTERGB(0, 0, 0), c0);
588 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0);
589 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1);
591 SelectObject(hdcmem, oldbm);
594 colors[0].rgbRed = 0xff;
595 colors[0].rgbGreen = 0xff;
596 colors[0].rgbBlue = 0xff;
597 colors[1].rgbRed = 0;
598 colors[1].rgbGreen = 0;
599 colors[1].rgbBlue = 0;
601 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
602 ok(hdib != NULL, "CreateDIBSection failed\n");
604 test_dib_info(hdib, bits, &pbmi->bmiHeader);
606 oldbm = SelectObject(hdcmem, hdib);
608 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
609 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
610 ok(!memcmp(rgb, colors, 2 * sizeof(RGBQUAD)),
611 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
612 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
613 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
615 SelectObject(hdcmem, oldbm);
616 test_dib_info(hdib, bits, &pbmi->bmiHeader);
619 pbmi->bmiHeader.biBitCount = 4;
620 for (i = 0; i < 16; i++) {
621 colors[i].rgbRed = i;
622 colors[i].rgbGreen = 16-i;
623 colors[i].rgbBlue = 0;
625 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
626 ok(hdib != NULL, "CreateDIBSection failed\n");
627 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
628 ok(dibsec.dsBmih.biClrUsed == 16,
629 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
630 test_dib_info(hdib, bits, &pbmi->bmiHeader);
633 pbmi->bmiHeader.biBitCount = 8;
635 for (i = 0; i < 128; i++) {
636 colors[i].rgbRed = 255 - i * 2;
637 colors[i].rgbGreen = i * 2;
638 colors[i].rgbBlue = 0;
639 colors[255 - i].rgbRed = 0;
640 colors[255 - i].rgbGreen = i * 2;
641 colors[255 - i].rgbBlue = 255 - i * 2;
643 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
644 ok(hdib != NULL, "CreateDIBSection failed\n");
645 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
646 ok(dibsec.dsBmih.biClrUsed == 256,
647 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
649 oldbm = SelectObject(hdcmem, hdib);
651 for (i = 0; i < 256; i++) {
652 test_color(hdcmem, DIBINDEX(i), RGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue));
653 test_color(hdcmem, PALETTERGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue),
654 RGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue));
657 SelectObject(hdcmem, oldbm);
658 test_dib_info(hdib, bits, &pbmi->bmiHeader);
661 pbmi->bmiHeader.biBitCount = 1;
663 /* Now create a palette and a palette indexed dib section */
664 memset(plogpal, 0, sizeof(logpalbuf));
665 plogpal->palVersion = 0x300;
666 plogpal->palNumEntries = 2;
667 palent[0].peRed = 0xff;
668 palent[0].peBlue = 0xff;
669 palent[1].peGreen = 0xff;
671 index = (WORD*)pbmi->bmiColors;
674 hpal = CreatePalette(plogpal);
675 ok(hpal != NULL, "CreatePalette failed\n");
676 oldpal = SelectPalette(hdc, hpal, TRUE);
677 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
678 ok(hdib != NULL, "CreateDIBSection failed\n");
679 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
680 ok(dibsec.dsBmih.biClrUsed == 2, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
682 /* The colour table has already been grabbed from the dc, so we select back the
685 SelectPalette(hdc, oldpal, TRUE);
686 oldbm = SelectObject(hdcmem, hdib);
687 oldpal = SelectPalette(hdcmem, hpal, TRUE);
689 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
690 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
691 ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
692 rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
693 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
694 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
695 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
697 c0 = RGB(palent[0].peRed, palent[0].peGreen, palent[0].peBlue);
698 c1 = RGB(palent[1].peRed, palent[1].peGreen, palent[1].peBlue);
700 test_color(hdcmem, DIBINDEX(0), c0);
701 test_color(hdcmem, DIBINDEX(1), c1);
702 test_color(hdcmem, DIBINDEX(2), c0);
703 test_color(hdcmem, PALETTEINDEX(0), c0);
704 test_color(hdcmem, PALETTEINDEX(1), c1);
705 test_color(hdcmem, PALETTEINDEX(2), c0);
706 test_color(hdcmem, PALETTERGB(palent[0].peRed, palent[0].peGreen, palent[0].peBlue), c0);
707 test_color(hdcmem, PALETTERGB(palent[1].peRed, palent[1].peGreen, palent[1].peBlue), c1);
708 test_color(hdcmem, PALETTERGB(0, 0, 0), c1);
709 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0);
710 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0);
711 test_color(hdcmem, PALETTERGB(0, 1, 0), c1);
712 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1);
713 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0);
715 /* Bottom and 2nd row from top green, everything else magenta */
716 bits[0] = bits[1] = 0xff;
717 bits[13 * 4] = bits[13*4 + 1] = 0xff;
719 test_dib_info(hdib, bits, &pbmi->bmiHeader);
721 pbmi->bmiHeader.biBitCount = 32;
723 hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
724 ok(hdib2 != NULL, "CreateDIBSection failed\n");
725 hdcmem2 = CreateCompatibleDC(hdc);
726 oldbm2 = SelectObject(hdcmem2, hdib2);
728 BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
730 ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
731 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
733 SelectObject(hdcmem2, oldbm2);
734 test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
737 SelectObject(hdcmem, oldbm);
738 SelectPalette(hdcmem, oldpal, TRUE);
743 pbmi->bmiHeader.biBitCount = 8;
745 memset(plogpal, 0, sizeof(logpalbuf));
746 plogpal->palVersion = 0x300;
747 plogpal->palNumEntries = 256;
749 for (i = 0; i < 128; i++) {
750 palent[i].peRed = 255 - i * 2;
751 palent[i].peBlue = i * 2;
752 palent[i].peGreen = 0;
753 palent[255 - i].peRed = 0;
754 palent[255 - i].peGreen = i * 2;
755 palent[255 - i].peBlue = 255 - i * 2;
758 index = (WORD*)pbmi->bmiColors;
759 for (i = 0; i < 256; i++) {
763 hpal = CreatePalette(plogpal);
764 ok(hpal != NULL, "CreatePalette failed\n");
765 oldpal = SelectPalette(hdc, hpal, TRUE);
766 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
767 ok(hdib != NULL, "CreateDIBSection failed\n");
768 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
769 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
771 test_dib_info(hdib, bits, &pbmi->bmiHeader);
773 SelectPalette(hdc, oldpal, TRUE);
774 oldbm = SelectObject(hdcmem, hdib);
775 oldpal = SelectPalette(hdcmem, hpal, TRUE);
777 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
778 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
779 for (i = 0; i < 256; i++) {
780 ok(rgb[i].rgbRed == palent[i].peRed &&
781 rgb[i].rgbBlue == palent[i].peBlue &&
782 rgb[i].rgbGreen == palent[i].peGreen,
783 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
784 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
787 for (i = 0; i < 256; i++) {
788 test_color(hdcmem, DIBINDEX(i), RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
789 test_color(hdcmem, PALETTEINDEX(i), RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
790 test_color(hdcmem, PALETTERGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue),
791 RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
794 SelectPalette(hdcmem, oldpal, TRUE);
795 SelectObject(hdcmem, oldbm);
799 plogpal->palNumEntries = 37;
800 hpal = CreatePalette(plogpal);
801 ok(hpal != NULL, "CreatePalette failed\n");
802 oldpal = SelectPalette(hdc, hpal, TRUE);
803 pbmi->bmiHeader.biClrUsed = 142;
804 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
805 ok(hdib != NULL, "CreateDIBSection failed\n");
806 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
807 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
809 test_dib_info(hdib, bits, &pbmi->bmiHeader);
811 SelectPalette(hdc, oldpal, TRUE);
812 oldbm = SelectObject(hdcmem, hdib);
814 memset( rgb, 0xcc, sizeof(rgb) );
815 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
816 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
817 for (i = 0; i < 256; i++)
819 if (i < pbmi->bmiHeader.biClrUsed)
821 ok(rgb[i].rgbRed == palent[i % 37].peRed &&
822 rgb[i].rgbBlue == palent[i % 37].peBlue &&
823 rgb[i].rgbGreen == palent[i % 37].peGreen,
824 "GetDIBColorTable returns table %d: r %02x g %02x b %02x res%02x\n",
825 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
826 test_color(hdcmem, DIBINDEX(i),
827 RGB(palent[i % 37].peRed, palent[i % 37].peGreen, palent[i % 37].peBlue));
831 ok(rgb[i].rgbRed == 0 && rgb[i].rgbBlue == 0 && rgb[i].rgbGreen == 0,
832 "GetDIBColorTable returns table %d: r %02x g %02x b %02x res%02x\n",
833 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
834 test_color(hdcmem, DIBINDEX(i), 0 );
837 pbmi->bmiHeader.biClrUsed = 173;
838 memset( pbmi->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
839 GetDIBits( hdc, hdib, 0, 1, bits, pbmi, DIB_RGB_COLORS );
840 ok( pbmi->bmiHeader.biClrUsed == 0, "wrong colors %u\n", pbmi->bmiHeader.biClrUsed );
841 for (i = 0; i < 256; i++)
844 ok(colors[i].rgbRed == palent[i % 37].peRed &&
845 colors[i].rgbBlue == palent[i % 37].peBlue &&
846 colors[i].rgbGreen == palent[i % 37].peGreen,
847 "GetDIBits returns table %d: r %02x g %02x b %02x res%02x\n",
848 i, colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
850 ok(colors[i].rgbRed == 0 && colors[i].rgbBlue == 0 && colors[i].rgbGreen == 0,
851 "GetDIBits returns table %d: r %02x g %02x b %02x res%02x\n",
852 i, colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
855 SelectObject(hdcmem, oldbm);
859 /* ClrUsed ignored on > 8bpp */
860 pbmi->bmiHeader.biBitCount = 16;
861 pbmi->bmiHeader.biClrUsed = 37;
862 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
863 ok(hdib != NULL, "CreateDIBSection failed\n");
864 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
865 ok(dibsec.dsBmih.biClrUsed == 0, "created DIBSection: wrong biClrUsed field: %u\n", dibsec.dsBmih.biClrUsed);
866 oldbm = SelectObject(hdcmem, hdib);
867 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
868 ok(ret == 0, "GetDIBColorTable returned %d\n", ret);
869 SelectObject(hdcmem, oldbm);
877 static void test_dib_formats(void)
882 int planes, bpp, compr, format;
886 BOOL format_ok, expect_ok;
888 bi = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
890 memdc = CreateCompatibleDC( 0 );
891 hbmp = CreateCompatibleBitmap( hdc, 10, 10 );
893 memset( data, 0xaa, sizeof(data) );
895 for (bpp = 0; bpp <= 64; bpp++)
897 for (planes = 0; planes <= 64; planes++)
899 for (compr = 0; compr < 8; compr++)
901 for (format = DIB_RGB_COLORS; format <= DIB_PAL_COLORS; format++)
908 case 24: expect_ok = (compr == BI_RGB); break;
910 case 32: expect_ok = (compr == BI_RGB || compr == BI_BITFIELDS); break;
911 default: expect_ok = FALSE; break;
914 memset( bi, 0, sizeof(bi->bmiHeader) );
915 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
916 bi->bmiHeader.biWidth = 2;
917 bi->bmiHeader.biHeight = 2;
918 bi->bmiHeader.biPlanes = planes;
919 bi->bmiHeader.biBitCount = bpp;
920 bi->bmiHeader.biCompression = compr;
921 bi->bmiHeader.biSizeImage = 0;
922 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
923 ret = GetDIBits(hdc, hbmp, 0, 0, data, bi, format);
924 if (expect_ok || (!bpp && compr != BI_JPEG && compr != BI_PNG) ||
925 (bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8))
926 ok( ret, "GetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
928 ok( !ret || broken(!bpp && (compr == BI_JPEG || compr == BI_PNG)), /* nt4 */
929 "GetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
931 /* all functions check planes except GetDIBits with 0 lines */
932 format_ok = expect_ok;
933 if (!planes) expect_ok = FALSE;
934 memset( bi, 0, sizeof(bi->bmiHeader) );
935 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
936 bi->bmiHeader.biWidth = 2;
937 bi->bmiHeader.biHeight = 2;
938 bi->bmiHeader.biPlanes = planes;
939 bi->bmiHeader.biBitCount = bpp;
940 bi->bmiHeader.biCompression = compr;
941 bi->bmiHeader.biSizeImage = 0;
942 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
944 hdib = CreateDIBSection(hdc, bi, format, &bits, NULL, 0);
945 if (expect_ok && (planes == 1 || planes * bpp <= 16) &&
946 (compr != BI_BITFIELDS || format != DIB_PAL_COLORS))
947 ok( hdib != NULL, "CreateDIBSection failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
949 ok( hdib == NULL, "CreateDIBSection succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
950 if (hdib) DeleteObject( hdib );
952 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, data, bi, format );
953 /* no sanity checks in CreateDIBitmap except compression */
954 if (compr == BI_JPEG || compr == BI_PNG)
955 ok( hdib == NULL || broken(hdib != NULL), /* nt4 */
956 "CreateDIBitmap succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
958 ok( hdib != NULL, "CreateDIBitmap failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
959 if (hdib) DeleteObject( hdib );
961 /* RLE needs a size */
962 bi->bmiHeader.biSizeImage = 0;
963 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, format);
965 ok( ret, "SetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
968 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
969 "SetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
970 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, format );
972 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
975 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
976 "SetDIBitsToDevice succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
977 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, format, SRCCOPY );
979 ok( ret, "StretchDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
982 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
983 "StretchDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
985 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, format);
987 ok( ret, "GetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
989 ok( !ret, "GetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
990 ok( bi->bmiHeader.biBitCount == bpp, "GetDIBits modified bpp %u/%u\n",
991 bpp, bi->bmiHeader.biBitCount );
993 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
994 bi->bmiHeader.biWidth = 2;
995 bi->bmiHeader.biHeight = 2;
996 bi->bmiHeader.biPlanes = planes;
997 bi->bmiHeader.biBitCount = bpp;
998 bi->bmiHeader.biCompression = compr;
999 bi->bmiHeader.biSizeImage = 1;
1000 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
1001 /* RLE allowed with valid biSizeImage */
1002 if ((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)) expect_ok = TRUE;
1004 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, format);
1006 ok( ret, "SetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1008 ok( !ret, "SetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1009 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, format );
1011 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1013 ok( !ret, "SetDIBitsToDevice succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1014 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, format, SRCCOPY );
1016 ok( ret, "StretchDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1018 ok( !ret, "StretchDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1020 bi->bmiHeader.biSizeImage = 0;
1021 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, format);
1022 if (expect_ok || !bpp)
1023 ok( ret, "GetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1025 ok( !ret || broken(format_ok && !planes), /* nt4 */
1026 "GetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1032 memset( bi, 0, sizeof(bi->bmiHeader) );
1033 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1034 bi->bmiHeader.biWidth = 2;
1035 bi->bmiHeader.biHeight = 2;
1036 bi->bmiHeader.biPlanes = 1;
1037 bi->bmiHeader.biBitCount = 16;
1038 bi->bmiHeader.biCompression = BI_BITFIELDS;
1039 bi->bmiHeader.biSizeImage = 0;
1040 *(DWORD *)&bi->bmiColors[0] = 0;
1041 *(DWORD *)&bi->bmiColors[1] = 0;
1042 *(DWORD *)&bi->bmiColors[2] = 0;
1044 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1045 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1046 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1047 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1048 /* other functions don't check */
1049 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1050 ok( hdib != NULL, "CreateDIBitmap failed with null bitfields\n" );
1051 DeleteObject( hdib );
1052 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1053 ok( ret, "SetDIBitsToDevice failed with null bitfields\n" );
1054 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1055 ok( ret, "StretchDIBits failed with null bitfields\n" );
1056 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1057 ok( ret, "GetDIBits failed with null bitfields\n" );
1058 bi->bmiHeader.biPlanes = 1;
1059 bi->bmiHeader.biBitCount = 16;
1060 bi->bmiHeader.biCompression = BI_BITFIELDS;
1061 bi->bmiHeader.biSizeImage = 0;
1062 *(DWORD *)&bi->bmiColors[0] = 0;
1063 *(DWORD *)&bi->bmiColors[1] = 0;
1064 *(DWORD *)&bi->bmiColors[2] = 0;
1065 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1066 ok( ret, "GetDIBits failed with null bitfields\n" );
1068 /* all fields must be non-zero */
1069 *(DWORD *)&bi->bmiColors[0] = 3;
1070 *(DWORD *)&bi->bmiColors[1] = 0;
1071 *(DWORD *)&bi->bmiColors[2] = 7;
1072 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1073 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1074 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1075 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1077 /* garbage is ok though */
1078 *(DWORD *)&bi->bmiColors[0] = 0x55;
1079 *(DWORD *)&bi->bmiColors[1] = 0x44;
1080 *(DWORD *)&bi->bmiColors[2] = 0x33;
1081 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1082 ok( hdib != NULL, "CreateDIBSection failed with bad bitfields\n" );
1083 if (hdib) DeleteObject( hdib );
1084 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1085 ok( ret, "SetDIBits failed with bad bitfields\n" );
1087 bi->bmiHeader.biWidth = -2;
1088 bi->bmiHeader.biHeight = 2;
1089 bi->bmiHeader.biBitCount = 32;
1090 bi->bmiHeader.biCompression = BI_RGB;
1091 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1092 ok( hdib == NULL, "CreateDIBSection succeeded with negative width\n" );
1093 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1094 ok( hdib == NULL, "CreateDIBitmap succeeded with negative width\n" );
1095 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1096 ok( !ret, "SetDIBits succeeded with negative width\n" );
1097 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1098 ok( !ret, "SetDIBitsToDevice succeeded with negative width\n" );
1099 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1100 ok( !ret, "StretchDIBits succeeded with negative width\n" );
1101 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1102 ok( !ret, "GetDIBits succeeded with negative width\n" );
1103 bi->bmiHeader.biWidth = -2;
1104 bi->bmiHeader.biHeight = 2;
1105 bi->bmiHeader.biBitCount = 32;
1106 bi->bmiHeader.biCompression = BI_RGB;
1107 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1108 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with negative width\n" );
1110 bi->bmiHeader.biWidth = 0;
1111 bi->bmiHeader.biHeight = 2;
1112 bi->bmiHeader.biBitCount = 32;
1113 bi->bmiHeader.biCompression = BI_RGB;
1114 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1115 ok( hdib == NULL, "CreateDIBSection succeeded with zero width\n" );
1116 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1117 ok( hdib != NULL, "CreateDIBitmap failed with zero width\n" );
1118 DeleteObject( hdib );
1119 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1120 ok( !ret || broken(ret), /* nt4 */ "SetDIBits succeeded with zero width\n" );
1121 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1122 ok( !ret || broken(ret), /* nt4 */ "SetDIBitsToDevice succeeded with zero width\n" );
1123 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1124 ok( !ret || broken(ret), /* nt4 */ "StretchDIBits succeeded with zero width\n" );
1125 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1126 ok( !ret, "GetDIBits succeeded with zero width\n" );
1127 bi->bmiHeader.biWidth = 0;
1128 bi->bmiHeader.biHeight = 2;
1129 bi->bmiHeader.biBitCount = 32;
1130 bi->bmiHeader.biCompression = BI_RGB;
1131 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1132 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero width\n" );
1134 bi->bmiHeader.biWidth = 2;
1135 bi->bmiHeader.biHeight = 0;
1136 bi->bmiHeader.biBitCount = 32;
1137 bi->bmiHeader.biCompression = BI_RGB;
1138 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1139 ok( hdib == NULL, "CreateDIBSection succeeded with zero height\n" );
1140 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1141 ok( hdib != NULL, "CreateDIBitmap failed with zero height\n" );
1142 DeleteObject( hdib );
1143 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1144 ok( !ret, "SetDIBits succeeded with zero height\n" );
1145 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1146 ok( !ret, "SetDIBitsToDevice succeeded with zero height\n" );
1147 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1148 ok( !ret, "StretchDIBits succeeded with zero height\n" );
1149 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1150 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1151 bi->bmiHeader.biWidth = 2;
1152 bi->bmiHeader.biHeight = 0;
1153 bi->bmiHeader.biBitCount = 32;
1154 bi->bmiHeader.biCompression = BI_RGB;
1155 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1156 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1159 DeleteObject( hbmp );
1160 ReleaseDC( 0, hdc );
1161 HeapFree( GetProcessHeap(), 0, bi );
1164 static void test_mono_dibsection(void)
1167 HBITMAP old_bm, mono_ds;
1168 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
1169 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
1170 RGBQUAD *colors = pbmi->bmiColors;
1177 memdc = CreateCompatibleDC(hdc);
1179 memset(pbmi, 0, sizeof(bmibuf));
1180 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
1181 pbmi->bmiHeader.biHeight = 10;
1182 pbmi->bmiHeader.biWidth = 10;
1183 pbmi->bmiHeader.biBitCount = 1;
1184 pbmi->bmiHeader.biPlanes = 1;
1185 pbmi->bmiHeader.biCompression = BI_RGB;
1186 colors[0].rgbRed = 0xff;
1187 colors[0].rgbGreen = 0xff;
1188 colors[0].rgbBlue = 0xff;
1189 colors[1].rgbRed = 0x0;
1190 colors[1].rgbGreen = 0x0;
1191 colors[1].rgbBlue = 0x0;
1194 * First dib section is 'inverted' ie color[0] is white, color[1] is black
1197 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1198 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1199 old_bm = SelectObject(memdc, mono_ds);
1201 /* black border, white interior */
1202 Rectangle(memdc, 0, 0, 10, 10);
1203 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1204 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1206 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1208 memset(bits, 0, sizeof(bits));
1211 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1212 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1214 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1216 colors[0].rgbRed = 0x0;
1217 colors[0].rgbGreen = 0x0;
1218 colors[0].rgbBlue = 0x0;
1219 colors[1].rgbRed = 0xff;
1220 colors[1].rgbGreen = 0xff;
1221 colors[1].rgbBlue = 0xff;
1223 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1224 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1226 SelectObject(memdc, old_bm);
1227 DeleteObject(mono_ds);
1230 * Next dib section is 'normal' ie color[0] is black, color[1] is white
1233 colors[0].rgbRed = 0x0;
1234 colors[0].rgbGreen = 0x0;
1235 colors[0].rgbBlue = 0x0;
1236 colors[1].rgbRed = 0xff;
1237 colors[1].rgbGreen = 0xff;
1238 colors[1].rgbBlue = 0xff;
1240 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1241 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1242 old_bm = SelectObject(memdc, mono_ds);
1244 /* black border, white interior */
1245 Rectangle(memdc, 0, 0, 10, 10);
1246 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
1247 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
1249 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
1251 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1252 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1254 /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
1256 colors[0].rgbRed = 0xff;
1257 colors[0].rgbGreen = 0xff;
1258 colors[0].rgbBlue = 0xff;
1259 colors[1].rgbRed = 0x0;
1260 colors[1].rgbGreen = 0x0;
1261 colors[1].rgbBlue = 0x0;
1263 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1264 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1267 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
1270 colors[0].rgbRed = 0xff;
1271 colors[0].rgbGreen = 0xff;
1272 colors[0].rgbBlue = 0xff;
1273 colors[1].rgbRed = 0x0;
1274 colors[1].rgbGreen = 0x0;
1275 colors[1].rgbBlue = 0x0;
1276 num = SetDIBColorTable(memdc, 0, 2, colors);
1277 ok(num == 2, "num = %d\n", num);
1279 /* black border, white interior */
1280 Rectangle(memdc, 0, 0, 10, 10);
1281 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1282 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1284 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1286 memset(bits, 0, sizeof(bits));
1289 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1290 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1292 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1294 colors[0].rgbRed = 0x0;
1295 colors[0].rgbGreen = 0x0;
1296 colors[0].rgbBlue = 0x0;
1297 colors[1].rgbRed = 0xff;
1298 colors[1].rgbGreen = 0xff;
1299 colors[1].rgbBlue = 0xff;
1301 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1302 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1304 SelectObject(memdc, old_bm);
1305 DeleteObject(mono_ds);
1308 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
1311 colors[0].rgbRed = 0xff;
1312 colors[0].rgbGreen = 0x0;
1313 colors[0].rgbBlue = 0x0;
1314 colors[1].rgbRed = 0xfe;
1315 colors[1].rgbGreen = 0x0;
1316 colors[1].rgbBlue = 0x0;
1318 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1319 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1320 old_bm = SelectObject(memdc, mono_ds);
1322 /* black border, white interior */
1323 Rectangle(memdc, 0, 0, 10, 10);
1324 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1325 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1327 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1329 colors[0].rgbRed = 0x0;
1330 colors[0].rgbGreen = 0x0;
1331 colors[0].rgbBlue = 0x0;
1332 colors[1].rgbRed = 0xff;
1333 colors[1].rgbGreen = 0xff;
1334 colors[1].rgbBlue = 0xff;
1336 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1337 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1339 /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
1341 colors[0].rgbRed = 0xff;
1342 colors[0].rgbGreen = 0xff;
1343 colors[0].rgbBlue = 0xff;
1344 colors[1].rgbRed = 0x0;
1345 colors[1].rgbGreen = 0x0;
1346 colors[1].rgbBlue = 0x0;
1348 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1349 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1351 SelectObject(memdc, old_bm);
1352 DeleteObject(mono_ds);
1358 static void test_bitmap(void)
1360 char buf[256], buf_cmp[256];
1361 HBITMAP hbmp, hbmp_old;
1367 hdc = CreateCompatibleDC(0);
1370 SetLastError(0xdeadbeef);
1371 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1374 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1375 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1376 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1381 SetLastError(0xdeadbeef);
1382 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1385 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1386 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1387 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1392 SetLastError(0xdeadbeef);
1393 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1394 ok(!hbmp, "CreateBitmap should fail\n");
1396 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1397 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1401 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1402 assert(hbmp != NULL);
1404 ret = GetObject(hbmp, sizeof(bm), &bm);
1405 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1407 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1408 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1409 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1410 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1411 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1412 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1413 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1415 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1416 assert(sizeof(buf) == sizeof(buf_cmp));
1418 ret = GetBitmapBits(hbmp, 0, NULL);
1419 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1421 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1422 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1424 memset(buf, 0xAA, sizeof(buf));
1425 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1426 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1427 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1429 hbmp_old = SelectObject(hdc, hbmp);
1431 ret = GetObject(hbmp, sizeof(bm), &bm);
1432 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1434 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1435 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1436 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1437 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1438 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1439 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1440 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1442 memset(buf, 0xAA, sizeof(buf));
1443 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1444 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1445 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1447 hbmp_old = SelectObject(hdc, hbmp_old);
1448 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1450 /* test various buffer sizes for GetObject */
1451 ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
1452 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1454 ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1455 ok(ret == 0, "%d != 0\n", ret);
1457 ret = GetObject(hbmp, 0, &bm);
1458 ok(ret == 0, "%d != 0\n", ret);
1460 ret = GetObject(hbmp, 1, &bm);
1461 ok(ret == 0, "%d != 0\n", ret);
1467 static void test_bmBits(void)
1473 memset(bits, 0, sizeof(bits));
1474 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1475 ok(hbmp != NULL, "CreateBitmap failed\n");
1477 memset(&bmp, 0xFF, sizeof(bmp));
1478 ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1479 "GetObject failed or returned a wrong structure size\n");
1480 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1485 static void test_GetDIBits_selected_DIB(UINT bpp)
1492 UINT dib_size, dib32_size;
1499 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1500 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1502 /* Create a DIB section with a color table */
1504 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1505 info->bmiHeader.biWidth = 32;
1506 info->bmiHeader.biHeight = 32;
1507 info->bmiHeader.biPlanes = 1;
1508 info->bmiHeader.biBitCount = bpp;
1509 info->bmiHeader.biCompression = BI_RGB;
1510 info->bmiHeader.biXPelsPerMeter = 0;
1511 info->bmiHeader.biYPelsPerMeter = 0;
1512 info->bmiHeader.biClrUsed = 0;
1513 info->bmiHeader.biClrImportant = 0;
1515 for (i=0; i < (1u << bpp); i++)
1517 BYTE c = i * (1 << (8 - bpp));
1518 info->bmiColors[i].rgbRed = c;
1519 info->bmiColors[i].rgbGreen = c;
1520 info->bmiColors[i].rgbBlue = c;
1521 info->bmiColors[i].rgbReserved = 0;
1524 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1525 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1526 dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1528 /* Set the bits of the DIB section */
1529 for (i=0; i < dib_size; i++)
1531 ((BYTE *)bits)[i] = i % 256;
1534 /* Select the DIB into a DC */
1535 dib_dc = CreateCompatibleDC(NULL);
1536 old_bmp = SelectObject(dib_dc, dib);
1537 dc = CreateCompatibleDC(NULL);
1538 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
1540 /* Copy the DIB attributes but not the color table */
1541 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1543 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1544 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1546 /* Compare the color table and the bits */
1547 for (i=0; i < (1u << bpp); i++)
1548 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1549 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1550 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1551 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1552 "color table entry %d differs (bpp %d)\n", i, bpp );
1554 ok( !memcmp( bits, bits2, dib_size ), "bit mismatch (bpp %d)\n", bpp );
1556 /* Test various combinations of lines = 0 and bits2 = NULL */
1557 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1558 res = GetDIBits( dc, dib, 0, 0, bits2, info2, DIB_RGB_COLORS );
1559 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1560 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1561 "color table mismatch (bpp %d)\n", bpp );
1563 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1564 res = GetDIBits( dc, dib, 0, 0, NULL, info2, DIB_RGB_COLORS );
1565 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1566 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1567 "color table mismatch (bpp %d)\n", bpp );
1569 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1570 res = GetDIBits( dc, dib, 0, info->bmiHeader.biHeight, NULL, info2, DIB_RGB_COLORS );
1571 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1572 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1573 "color table mismatch (bpp %d)\n", bpp );
1575 /* Map into a 32bit-DIB */
1576 info2->bmiHeader.biBitCount = 32;
1577 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1578 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1580 /* Check if last pixel was set */
1581 pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
1582 ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
1584 HeapFree(GetProcessHeap(), 0, bits2);
1587 SelectObject(dib_dc, old_bmp);
1590 HeapFree(GetProcessHeap(), 0, info2);
1591 HeapFree(GetProcessHeap(), 0, info);
1594 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1608 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1609 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1611 width = height = 16;
1613 /* Create a DDB (device-dependent bitmap) */
1617 ddb = CreateBitmap(width, height, 1, 1, NULL);
1621 HDC screen_dc = GetDC(NULL);
1622 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1623 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1624 ReleaseDC(NULL, screen_dc);
1627 /* Set the pixels */
1628 ddb_dc = CreateCompatibleDC(NULL);
1629 old_bmp = SelectObject(ddb_dc, ddb);
1630 for (i = 0; i < width; i++)
1632 for (j=0; j < height; j++)
1634 BYTE c = (i * width + j) % 256;
1635 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1638 SelectObject(ddb_dc, old_bmp);
1640 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1641 info->bmiHeader.biWidth = width;
1642 info->bmiHeader.biHeight = height;
1643 info->bmiHeader.biPlanes = 1;
1644 info->bmiHeader.biBitCount = bpp;
1645 info->bmiHeader.biCompression = BI_RGB;
1647 dc = CreateCompatibleDC(NULL);
1649 /* Fill in biSizeImage */
1650 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1651 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1653 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1654 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1657 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1658 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1660 /* Copy the DIB attributes but not the color table */
1661 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1663 /* Select the DDB into another DC */
1664 old_bmp = SelectObject(ddb_dc, ddb);
1667 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1668 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1670 /* Compare the color table and the bits */
1673 for (i=0; i < (1u << bpp); i++)
1674 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1675 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1676 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1677 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1678 "color table entry %d differs (bpp %d)\n", i, bpp );
1681 ok( !memcmp( bits, bits2, info->bmiHeader.biSizeImage ), "bit mismatch (bpp %d)\n", bpp );
1683 /* Test the palette */
1684 if (info2->bmiHeader.biBitCount <= 8)
1686 WORD *colors = (WORD*)info2->bmiColors;
1688 /* Get the palette indices */
1689 res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1690 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1692 for (i = 0; i < (1 << info->bmiHeader.biBitCount); i++)
1693 ok( colors[i] == i, "%d: got %d (bpp %d)\n", i, colors[i], bpp );
1696 HeapFree(GetProcessHeap(), 0, bits2);
1697 HeapFree(GetProcessHeap(), 0, bits);
1700 SelectObject(ddb_dc, old_bmp);
1703 HeapFree(GetProcessHeap(), 0, info2);
1704 HeapFree(GetProcessHeap(), 0, info);
1707 static void test_GetDIBits(void)
1709 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1710 static const BYTE bmp_bits_1[16 * 2] =
1712 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1713 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1714 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1715 0xff,0xff, 0,0, 0xff,0xff, 0,0
1717 /* 4-bytes aligned 1-bit DIB data: 16x16 */
1718 static const BYTE dib_bits_1[16 * 4] =
1720 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1721 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1722 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1723 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1725 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1726 static const BYTE bmp_bits_24[16 * 16*3] =
1728 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1729 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1730 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1731 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1732 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1733 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1734 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1735 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1736 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1737 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1738 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1739 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1740 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1741 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1742 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1743 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1744 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1745 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1746 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1747 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1748 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1749 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1750 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1751 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1752 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1753 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1754 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1755 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1756 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1757 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1758 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1759 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1761 /* 4-bytes aligned 24-bit DIB data: 16x16 */
1762 static const BYTE dib_bits_24[16 * 16*3] =
1764 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1765 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1766 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1767 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1768 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1769 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1770 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1771 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1772 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1773 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1774 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1775 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1776 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1777 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1778 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1779 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1780 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1781 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1782 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1783 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1784 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1785 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1786 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1787 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1788 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1789 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1790 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1791 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1792 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1793 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1794 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1795 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1800 int i, bytes, lines;
1802 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1803 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1804 RGBQUAD *colors = bi->bmiColors;
1805 PALETTEENTRY pal_ents[20];
1809 /* 1-bit source bitmap data */
1810 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1811 ok(hbmp != 0, "CreateBitmap failed\n");
1813 memset(&bm, 0xAA, sizeof(bm));
1814 bytes = GetObject(hbmp, sizeof(bm), &bm);
1815 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1816 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1817 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1818 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1819 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1820 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1821 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1822 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1824 bytes = GetBitmapBits(hbmp, 0, NULL);
1825 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1826 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1827 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1828 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1830 /* retrieve 1-bit DIB data */
1831 memset(bi, 0, sizeof(*bi));
1832 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1833 bi->bmiHeader.biWidth = bm.bmWidth;
1834 bi->bmiHeader.biHeight = bm.bmHeight;
1835 bi->bmiHeader.biPlanes = 1;
1836 bi->bmiHeader.biBitCount = 1;
1837 bi->bmiHeader.biCompression = BI_RGB;
1838 bi->bmiHeader.biClrUsed = 37;
1839 bi->bmiHeader.biSizeImage = 0;
1840 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1841 SetLastError(0xdeadbeef);
1842 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1843 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1844 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1845 broken(GetLastError() == 0xdeadbeef), /* winnt */
1846 "wrong error %u\n", GetLastError());
1847 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1848 ok(bi->bmiHeader.biClrUsed == 37 || broken(bi->bmiHeader.biClrUsed == 0),
1849 "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
1851 memset(buf, 0xAA, sizeof(buf));
1852 SetLastError(0xdeadbeef);
1853 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1854 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1855 lines, bm.bmHeight, GetLastError());
1856 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1857 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
1859 /* the color table consists of black and white */
1860 ok(colors[0].rgbRed == 0 && colors[0].rgbGreen == 0 &&
1861 colors[0].rgbBlue == 0 && colors[0].rgbReserved == 0,
1862 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1863 colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue, colors[0].rgbReserved);
1864 ok(colors[1].rgbRed == 0xff && colors[1].rgbGreen == 0xff &&
1865 colors[1].rgbBlue == 0xff && colors[1].rgbReserved == 0,
1866 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1867 colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue, colors[1].rgbReserved);
1868 for (i = 2; i < 256; i++)
1870 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
1871 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
1872 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1873 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
1876 /* returned bits are DWORD aligned and upside down */
1877 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1879 /* Test the palette indices */
1880 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1881 SetLastError(0xdeadbeef);
1882 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1883 ok(((WORD*)colors)[0] == 0, "Color 0 is %d\n", ((WORD*)colors)[0]);
1884 ok(((WORD*)colors)[1] == 1, "Color 1 is %d\n", ((WORD*)colors)[1]);
1885 for (i = 2; i < 256; i++)
1886 ok(((WORD*)colors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)colors)[1]);
1888 /* retrieve 24-bit DIB data */
1889 memset(bi, 0, sizeof(*bi));
1890 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1891 bi->bmiHeader.biWidth = bm.bmWidth;
1892 bi->bmiHeader.biHeight = bm.bmHeight;
1893 bi->bmiHeader.biPlanes = 1;
1894 bi->bmiHeader.biBitCount = 24;
1895 bi->bmiHeader.biCompression = BI_RGB;
1896 bi->bmiHeader.biClrUsed = 37;
1897 bi->bmiHeader.biSizeImage = 0;
1898 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1899 memset(buf, 0xAA, sizeof(buf));
1900 SetLastError(0xdeadbeef);
1901 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1902 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1903 lines, bm.bmHeight, GetLastError());
1904 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1905 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
1907 /* the color table doesn't exist for 24-bit images */
1908 for (i = 0; i < 256; i++)
1910 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
1911 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
1912 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1913 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
1916 /* returned bits are DWORD aligned and upside down */
1917 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1920 /* 24-bit source bitmap data */
1921 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1922 ok(hbmp != 0, "CreateBitmap failed\n");
1923 SetLastError(0xdeadbeef);
1924 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1925 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1926 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1927 lines, bm.bmHeight, GetLastError());
1929 memset(&bm, 0xAA, sizeof(bm));
1930 bytes = GetObject(hbmp, sizeof(bm), &bm);
1931 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1932 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1933 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1934 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1935 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1936 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1937 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1938 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1940 bytes = GetBitmapBits(hbmp, 0, NULL);
1941 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
1942 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1943 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1944 bm.bmWidthBytes * bm.bmHeight, bytes);
1946 /* retrieve 1-bit DIB data */
1947 memset(bi, 0, sizeof(*bi));
1948 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1949 bi->bmiHeader.biWidth = bm.bmWidth;
1950 bi->bmiHeader.biHeight = bm.bmHeight;
1951 bi->bmiHeader.biPlanes = 1;
1952 bi->bmiHeader.biBitCount = 1;
1953 bi->bmiHeader.biCompression = BI_RGB;
1954 bi->bmiHeader.biClrUsed = 37;
1955 bi->bmiHeader.biSizeImage = 0;
1956 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1957 memset(buf, 0xAA, sizeof(buf));
1958 SetLastError(0xdeadbeef);
1959 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1960 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1961 lines, bm.bmHeight, GetLastError());
1962 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1963 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
1965 /* the color table consists of black and white */
1966 ok(colors[0].rgbRed == 0 && colors[0].rgbGreen == 0 &&
1967 colors[0].rgbBlue == 0 && colors[0].rgbReserved == 0,
1968 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1969 colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue, colors[0].rgbReserved);
1970 ok(colors[1].rgbRed == 0xff && colors[1].rgbGreen == 0xff &&
1971 colors[1].rgbBlue == 0xff && colors[1].rgbReserved == 0,
1972 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1973 colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue, colors[1].rgbReserved);
1974 for (i = 2; i < 256; i++)
1976 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
1977 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
1978 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1979 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
1982 /* returned bits are DWORD aligned and upside down */
1983 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1985 /* Test the palette indices */
1986 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1987 SetLastError(0xdeadbeef);
1988 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1989 ok(((WORD*)colors)[0] == 0, "Color 0 is %d\n", ((WORD*)colors)[0]);
1990 ok(((WORD*)colors)[1] == 1, "Color 1 is %d\n", ((WORD*)colors)[1]);
1991 for (i = 2; i < 256; i++)
1992 ok(((WORD*)colors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)colors)[i]);
1994 /* retrieve 4-bit DIB data */
1995 memset(bi, 0, sizeof(*bi));
1996 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1997 bi->bmiHeader.biWidth = bm.bmWidth;
1998 bi->bmiHeader.biHeight = bm.bmHeight;
1999 bi->bmiHeader.biPlanes = 1;
2000 bi->bmiHeader.biBitCount = 4;
2001 bi->bmiHeader.biCompression = BI_RGB;
2002 bi->bmiHeader.biClrUsed = 37;
2003 bi->bmiHeader.biSizeImage = 0;
2004 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2005 memset(buf, 0xAA, sizeof(buf));
2006 SetLastError(0xdeadbeef);
2007 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2008 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2009 lines, bm.bmHeight, GetLastError());
2010 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2012 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2014 for (i = 0; i < 16; i++)
2017 int entry = i < 8 ? i : i + 4;
2019 if(entry == 7) entry = 12;
2020 else if(entry == 12) entry = 7;
2022 expect.rgbRed = pal_ents[entry].peRed;
2023 expect.rgbGreen = pal_ents[entry].peGreen;
2024 expect.rgbBlue = pal_ents[entry].peBlue;
2025 expect.rgbReserved = 0;
2027 ok(!memcmp(colors + i, &expect, sizeof(expect)),
2028 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2029 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2030 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2033 /* retrieve 8-bit DIB data */
2034 memset(bi, 0, sizeof(*bi));
2035 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2036 bi->bmiHeader.biWidth = bm.bmWidth;
2037 bi->bmiHeader.biHeight = bm.bmHeight;
2038 bi->bmiHeader.biPlanes = 1;
2039 bi->bmiHeader.biBitCount = 8;
2040 bi->bmiHeader.biCompression = BI_RGB;
2041 bi->bmiHeader.biClrUsed = 37;
2042 bi->bmiHeader.biSizeImage = 0;
2043 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2044 memset(buf, 0xAA, sizeof(buf));
2045 SetLastError(0xdeadbeef);
2046 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2047 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2048 lines, bm.bmHeight, GetLastError());
2049 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2051 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2053 for (i = 0; i < 256; i++)
2057 if (i < 10 || i >= 246)
2059 int entry = i < 10 ? i : i - 236;
2060 expect.rgbRed = pal_ents[entry].peRed;
2061 expect.rgbGreen = pal_ents[entry].peGreen;
2062 expect.rgbBlue = pal_ents[entry].peBlue;
2066 expect.rgbRed = (i & 0x07) << 5;
2067 expect.rgbGreen = (i & 0x38) << 2;
2068 expect.rgbBlue = i & 0xc0;
2070 expect.rgbReserved = 0;
2072 ok(!memcmp(colors + i, &expect, sizeof(expect)),
2073 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2074 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2075 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2078 /* retrieve 24-bit DIB data */
2079 memset(bi, 0, sizeof(*bi));
2080 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2081 bi->bmiHeader.biWidth = bm.bmWidth;
2082 bi->bmiHeader.biHeight = bm.bmHeight;
2083 bi->bmiHeader.biPlanes = 1;
2084 bi->bmiHeader.biBitCount = 24;
2085 bi->bmiHeader.biCompression = BI_RGB;
2086 bi->bmiHeader.biClrUsed = 37;
2087 bi->bmiHeader.biSizeImage = 0;
2088 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2089 memset(buf, 0xAA, sizeof(buf));
2090 SetLastError(0xdeadbeef);
2091 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2092 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2093 lines, bm.bmHeight, GetLastError());
2094 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2095 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2097 /* the color table doesn't exist for 24-bit images */
2098 for (i = 0; i < 256; i++)
2100 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2101 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2102 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2103 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2106 /* returned bits are DWORD aligned and upside down */
2107 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2113 static void test_GetDIBits_BI_BITFIELDS(void)
2115 /* Try a screen resolution detection technique
2116 * from the September 1999 issue of Windows Developer's Journal
2117 * which seems to be in widespread use.
2118 * http://www.lesher.ws/highcolor.html
2119 * http://www.lesher.ws/vidfmt.c
2120 * It hinges on being able to retrieve the bitmaps
2121 * for the three primary colors in non-paletted 16 bit mode.
2123 char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
2125 LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
2126 DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
2132 memset(dibinfo, 0, sizeof(dibinfo_buf));
2133 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2136 ok(hdc != NULL, "GetDC failed?\n");
2137 hbm = CreateCompatibleBitmap(hdc, 1, 1);
2138 ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
2140 /* Call GetDIBits to fill in bmiHeader. */
2141 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2142 ok(ret == 1, "GetDIBits failed\n");
2143 if (dibinfo->bmiHeader.biBitCount > 8)
2145 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2146 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2147 "compression is %u (%d bpp)\n", dibinfo->bmiHeader.biCompression, dibinfo->bmiHeader.biBitCount );
2149 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2151 ok( !bitmasks[0], "red mask is set\n" );
2152 ok( !bitmasks[1], "green mask is set\n" );
2153 ok( !bitmasks[2], "blue mask is set\n" );
2155 /* test with NULL bits pointer and correct bpp */
2156 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2157 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2158 ok(ret == 1, "GetDIBits failed\n");
2160 ok( bitmasks[0] != 0, "red mask is not set\n" );
2161 ok( bitmasks[1] != 0, "green mask is not set\n" );
2162 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2163 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2165 /* test with valid bits pointer */
2166 memset(dibinfo, 0, sizeof(dibinfo_buf));
2167 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2168 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2169 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2170 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2171 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2172 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2174 ok( bitmasks[0] != 0, "red mask is not set\n" );
2175 ok( bitmasks[1] != 0, "green mask is not set\n" );
2176 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2177 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2179 /* now with bits and 0 lines */
2180 memset(dibinfo, 0, sizeof(dibinfo_buf));
2181 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2182 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2183 SetLastError(0xdeadbeef);
2184 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2185 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2187 ok( !bitmasks[0], "red mask is set\n" );
2188 ok( !bitmasks[1], "green mask is set\n" );
2189 ok( !bitmasks[2], "blue mask is set\n" );
2190 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2192 memset(bitmasks, 0, 3*sizeof(DWORD));
2193 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2194 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2195 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2197 ok( bitmasks[0] != 0, "red mask is not set\n" );
2198 ok( bitmasks[1] != 0, "green mask is not set\n" );
2199 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2200 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2203 else skip("bitmap in colortable mode, skipping BI_BITFIELDS tests\n");
2207 /* same thing now with a 32-bpp DIB section */
2209 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2210 dibinfo->bmiHeader.biWidth = 1;
2211 dibinfo->bmiHeader.biHeight = 1;
2212 dibinfo->bmiHeader.biPlanes = 1;
2213 dibinfo->bmiHeader.biBitCount = 32;
2214 dibinfo->bmiHeader.biCompression = BI_RGB;
2215 dibinfo->bmiHeader.biSizeImage = 0;
2216 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2217 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2218 dibinfo->bmiHeader.biClrUsed = 0;
2219 dibinfo->bmiHeader.biClrImportant = 0;
2220 bitmasks[0] = 0x0000ff;
2221 bitmasks[1] = 0x00ff00;
2222 bitmasks[2] = 0xff0000;
2223 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2224 ok( hbm != 0, "failed to create bitmap\n" );
2226 memset(dibinfo, 0, sizeof(dibinfo_buf));
2227 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2228 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2229 ok(ret == 1, "GetDIBits failed\n");
2230 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2232 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2233 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2234 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2235 ok( !bitmasks[0], "red mask is set\n" );
2236 ok( !bitmasks[1], "green mask is set\n" );
2237 ok( !bitmasks[2], "blue mask is set\n" );
2239 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2240 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2241 ok(ret == 1, "GetDIBits failed\n");
2242 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2243 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2244 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2245 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2246 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2248 ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
2249 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2250 ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
2252 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2256 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2257 dibinfo->bmiHeader.biWidth = 1;
2258 dibinfo->bmiHeader.biHeight = 1;
2259 dibinfo->bmiHeader.biPlanes = 1;
2260 dibinfo->bmiHeader.biBitCount = 32;
2261 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2262 dibinfo->bmiHeader.biSizeImage = 0;
2263 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2264 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2265 dibinfo->bmiHeader.biClrUsed = 0;
2266 dibinfo->bmiHeader.biClrImportant = 0;
2267 bitmasks[0] = 0x0000ff;
2268 bitmasks[1] = 0x00ff00;
2269 bitmasks[2] = 0xff0000;
2270 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2271 ok( hbm != 0, "failed to create bitmap\n" );
2275 memset(dibinfo, 0, sizeof(dibinfo_buf));
2276 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2277 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2278 ok(ret == 1, "GetDIBits failed\n");
2280 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
2281 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2282 ok( !bitmasks[0], "red mask is set\n" );
2283 ok( !bitmasks[1], "green mask is set\n" );
2284 ok( !bitmasks[2], "blue mask is set\n" );
2286 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2287 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2288 ok(ret == 1, "GetDIBits failed\n");
2289 ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
2290 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2291 ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
2292 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2297 /* 24-bpp DIB sections don't have bitfields */
2299 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2300 dibinfo->bmiHeader.biWidth = 1;
2301 dibinfo->bmiHeader.biHeight = 1;
2302 dibinfo->bmiHeader.biPlanes = 1;
2303 dibinfo->bmiHeader.biBitCount = 24;
2304 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2305 dibinfo->bmiHeader.biSizeImage = 0;
2306 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2307 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2308 dibinfo->bmiHeader.biClrUsed = 0;
2309 dibinfo->bmiHeader.biClrImportant = 0;
2310 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2311 ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
2312 dibinfo->bmiHeader.biCompression = BI_RGB;
2313 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2314 ok( hbm != 0, "failed to create bitmap\n" );
2316 memset(dibinfo, 0, sizeof(dibinfo_buf));
2317 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2318 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2319 ok(ret == 1, "GetDIBits failed\n");
2320 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2322 ok( dibinfo->bmiHeader.biCompression == BI_RGB,
2323 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2324 ok( !bitmasks[0], "red mask is set\n" );
2325 ok( !bitmasks[1], "green mask is set\n" );
2326 ok( !bitmasks[2], "blue mask is set\n" );
2328 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2329 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2330 ok(ret == 1, "GetDIBits failed\n");
2331 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2332 ok( !bitmasks[0], "red mask is set\n" );
2333 ok( !bitmasks[1], "green mask is set\n" );
2334 ok( !bitmasks[2], "blue mask is set\n" );
2335 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2338 ReleaseDC(NULL, hdc);
2341 static void test_select_object(void)
2344 HBITMAP hbm, hbm_old;
2346 DWORD depths[] = {8, 15, 16, 24, 32};
2351 ok(hdc != 0, "GetDC(0) failed\n");
2352 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2353 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2355 hbm_old = SelectObject(hdc, hbm);
2356 ok(hbm_old == 0, "SelectObject should fail\n");
2361 hdc = CreateCompatibleDC(0);
2362 ok(hdc != 0, "GetDC(0) failed\n");
2363 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2364 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2366 hbm_old = SelectObject(hdc, hbm);
2367 ok(hbm_old != 0, "SelectObject failed\n");
2368 hbm_old = SelectObject(hdc, hbm_old);
2369 ok(hbm_old == hbm, "SelectObject failed\n");
2373 /* test an 1-bpp bitmap */
2374 planes = GetDeviceCaps(hdc, PLANES);
2377 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
2378 ok(hbm != 0, "CreateBitmap failed\n");
2380 hbm_old = SelectObject(hdc, hbm);
2381 ok(hbm_old != 0, "SelectObject failed\n");
2382 hbm_old = SelectObject(hdc, hbm_old);
2383 ok(hbm_old == hbm, "SelectObject failed\n");
2387 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
2388 /* test a color bitmap to dc bpp matching */
2389 planes = GetDeviceCaps(hdc, PLANES);
2390 bpp = GetDeviceCaps(hdc, BITSPIXEL);
2392 hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
2393 ok(hbm != 0, "CreateBitmap failed\n");
2395 hbm_old = SelectObject(hdc, hbm);
2396 if(depths[i] == bpp ||
2397 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
2399 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
2400 SelectObject(hdc, hbm_old);
2402 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
2405 memset(&bm, 0xAA, sizeof(bm));
2406 bytes = GetObject(hbm, sizeof(bm), &bm);
2407 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2408 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2409 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
2410 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
2411 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2412 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
2413 if(depths[i] == 15) {
2414 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
2416 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2418 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2426 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
2431 ret = GetObjectType(hbmp);
2432 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
2434 ret = GetObject(hbmp, 0, 0);
2435 ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
2437 memset(&bm, 0xDA, sizeof(bm));
2438 SetLastError(0xdeadbeef);
2439 ret = GetObject(hbmp, sizeof(bm), &bm);
2440 if (!ret) /* XP, only for curObj2 */ return;
2441 ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
2442 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2443 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2444 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2445 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2446 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2447 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2448 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2451 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2453 static void test_CreateBitmap(void)
2456 HDC screenDC = GetDC(0);
2457 HDC hdc = CreateCompatibleDC(screenDC);
2460 /* all of these are the stock monochrome bitmap */
2461 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2462 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2463 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2464 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2465 HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2466 HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2468 /* these 2 are not the stock monochrome bitmap */
2469 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2470 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2472 HBITMAP old1 = SelectObject(hdc, bm2);
2473 HBITMAP old2 = SelectObject(screenDC, bm3);
2474 SelectObject(hdc, old1);
2475 SelectObject(screenDC, old2);
2477 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2478 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2479 bm, bm1, bm4, bm5, curObj1, old1);
2480 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2482 ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
2483 ok(old2 == 0, "old2 %p\n", old2);
2485 test_mono_1x1_bmp(bm);
2486 test_mono_1x1_bmp(bm1);
2487 test_mono_1x1_bmp(bm2);
2488 test_mono_1x1_bmp(bm3);
2489 test_mono_1x1_bmp(bm4);
2490 test_mono_1x1_bmp(bm5);
2491 test_mono_1x1_bmp(old1);
2492 test_mono_1x1_bmp(curObj1);
2502 ReleaseDC(0, screenDC);
2504 /* show that Windows ignores the provided bm.bmWidthBytes */
2508 bmp.bmWidthBytes = 28;
2510 bmp.bmBitsPixel = 1;
2512 bm = CreateBitmapIndirect(&bmp);
2513 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2514 test_mono_1x1_bmp(bm);
2517 /* Test how the bmBitsPixel field is treated */
2518 for(i = 1; i <= 33; i++) {
2522 bmp.bmWidthBytes = 28;
2524 bmp.bmBitsPixel = i;
2526 SetLastError(0xdeadbeef);
2527 bm = CreateBitmapIndirect(&bmp);
2529 DWORD error = GetLastError();
2530 ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
2531 ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2535 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2536 GetObject(bm, sizeof(bmp), &bmp);
2543 } else if(i <= 16) {
2545 } else if(i <= 24) {
2547 } else if(i <= 32) {
2550 ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2551 i, bmp.bmBitsPixel, expect);
2556 static void test_bitmapinfoheadersize(void)
2563 memset(&bmi, 0, sizeof(BITMAPINFO));
2564 bmi.bmiHeader.biHeight = 100;
2565 bmi.bmiHeader.biWidth = 512;
2566 bmi.bmiHeader.biBitCount = 24;
2567 bmi.bmiHeader.biPlanes = 1;
2569 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2571 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2572 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2574 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2576 SetLastError(0xdeadbeef);
2577 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2578 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2581 bmi.bmiHeader.biSize++;
2583 SetLastError(0xdeadbeef);
2584 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2586 broken(!hdib), /* Win98, WinMe */
2587 "CreateDIBSection error %d\n", GetLastError());
2590 bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2592 SetLastError(0xdeadbeef);
2593 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2595 broken(!hdib), /* Win98, WinMe */
2596 "CreateDIBSection error %d\n", GetLastError());
2599 bmi.bmiHeader.biSize++;
2601 SetLastError(0xdeadbeef);
2602 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2604 broken(!hdib), /* Win98, WinMe */
2605 "CreateDIBSection error %d\n", GetLastError());
2608 bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2610 SetLastError(0xdeadbeef);
2611 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2612 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2615 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2617 SetLastError(0xdeadbeef);
2618 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2620 broken(!hdib), /* Win95 */
2621 "CreateDIBSection error %d\n", GetLastError());
2624 memset(&bci, 0, sizeof(BITMAPCOREINFO));
2625 bci.bmciHeader.bcHeight = 100;
2626 bci.bmciHeader.bcWidth = 512;
2627 bci.bmciHeader.bcBitCount = 24;
2628 bci.bmciHeader.bcPlanes = 1;
2630 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2632 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2633 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2635 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2637 SetLastError(0xdeadbeef);
2638 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2639 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2642 bci.bmciHeader.bcSize++;
2644 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2645 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2647 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2649 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2650 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2655 static void test_get16dibits(void)
2657 BYTE bits[4 * (16 / sizeof(BYTE))];
2659 HDC screen_dc = GetDC(NULL);
2662 int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2664 int overwritten_bytes = 0;
2666 memset(bits, 0, sizeof(bits));
2667 hbmp = CreateBitmap(2, 2, 1, 16, bits);
2668 ok(hbmp != NULL, "CreateBitmap failed\n");
2670 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2673 memset(info, '!', info_len);
2674 memset(info, 0, sizeof(info->bmiHeader));
2676 info->bmiHeader.biSize = sizeof(info->bmiHeader);
2677 info->bmiHeader.biWidth = 2;
2678 info->bmiHeader.biHeight = 2;
2679 info->bmiHeader.biPlanes = 1;
2680 info->bmiHeader.biCompression = BI_RGB;
2682 ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2683 ok(ret != 0, "GetDIBits failed got %d\n", ret);
2685 for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2687 overwritten_bytes++;
2688 ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2690 HeapFree(GetProcessHeap(), 0, info);
2692 ReleaseDC(NULL, screen_dc);
2695 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2696 DWORD dwRop, UINT32 expected, int line)
2698 *srcBuffer = 0xFEDCBA98;
2699 *dstBuffer = 0x89ABCDEF;
2700 Rectangle(hdcSrc, 0, 0, 1, 1); /* A null operation to ensure dibs are coerced to X11 */
2701 BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
2702 ok(expected == *dstBuffer,
2703 "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2704 dwRop, expected, *dstBuffer, line);
2707 static void test_BitBlt(void)
2709 HBITMAP bmpDst, bmpSrc;
2710 HBITMAP oldDst, oldSrc;
2711 HDC hdcScreen, hdcDst, hdcSrc;
2712 UINT32 *dstBuffer, *srcBuffer;
2713 HBRUSH hBrush, hOldBrush;
2714 BITMAPINFO bitmapInfo;
2716 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2717 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2718 bitmapInfo.bmiHeader.biWidth = 1;
2719 bitmapInfo.bmiHeader.biHeight = 1;
2720 bitmapInfo.bmiHeader.biPlanes = 1;
2721 bitmapInfo.bmiHeader.biBitCount = 32;
2722 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2723 bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2725 hdcScreen = CreateCompatibleDC(0);
2726 hdcDst = CreateCompatibleDC(hdcScreen);
2727 hdcSrc = CreateCompatibleDC(hdcDst);
2729 /* Setup the destination dib section */
2730 bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
2732 oldDst = SelectObject(hdcDst, bmpDst);
2734 hBrush = CreateSolidBrush(0x012345678);
2735 hOldBrush = SelectObject(hdcDst, hBrush);
2737 /* Setup the source dib section */
2738 bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
2740 oldSrc = SelectObject(hdcSrc, bmpSrc);
2742 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2743 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2744 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2745 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2746 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2747 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2748 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2749 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2750 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2751 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2752 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2753 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2754 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2755 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2756 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2759 SelectObject(hdcSrc, oldSrc);
2760 DeleteObject(bmpSrc);
2763 SelectObject(hdcDst, hOldBrush);
2764 DeleteObject(hBrush);
2765 SelectObject(hdcDst, oldDst);
2766 DeleteObject(bmpDst);
2770 DeleteDC(hdcScreen);
2773 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2774 DWORD dwRop, UINT32 expected, int line)
2776 *srcBuffer = 0xFEDCBA98;
2777 *dstBuffer = 0x89ABCDEF;
2778 StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
2779 ok(expected == *dstBuffer,
2780 "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2781 dwRop, expected, *dstBuffer, line);
2784 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, BITMAPINFO *dst_info, UINT32 *dstBuffer, UINT32 *srcBuffer,
2785 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2786 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2787 UINT32 *expected, int line)
2789 int dst_size = get_dib_image_size( dst_info );
2791 memset(dstBuffer, 0, dst_size);
2792 StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2793 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
2794 ok(memcmp(dstBuffer, expected, dst_size) == 0,
2795 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2796 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2797 expected[0], expected[1], expected[2], expected[3],
2798 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2799 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2800 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2803 static void test_StretchBlt(void)
2805 HBITMAP bmpDst, bmpSrc;
2806 HBITMAP oldDst, oldSrc;
2807 HDC hdcScreen, hdcDst, hdcSrc;
2808 UINT32 *dstBuffer, *srcBuffer;
2809 HBRUSH hBrush, hOldBrush;
2810 BITMAPINFO biDst, biSrc;
2811 UINT32 expected[256];
2814 memset(&biDst, 0, sizeof(BITMAPINFO));
2815 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2816 biDst.bmiHeader.biWidth = 16;
2817 biDst.bmiHeader.biHeight = -16;
2818 biDst.bmiHeader.biPlanes = 1;
2819 biDst.bmiHeader.biBitCount = 32;
2820 biDst.bmiHeader.biCompression = BI_RGB;
2821 memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
2823 hdcScreen = CreateCompatibleDC(0);
2824 hdcDst = CreateCompatibleDC(hdcScreen);
2825 hdcSrc = CreateCompatibleDC(hdcDst);
2828 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2830 oldDst = SelectObject(hdcDst, bmpDst);
2832 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2834 oldSrc = SelectObject(hdcSrc, bmpSrc);
2836 hBrush = CreateSolidBrush(0x012345678);
2837 hOldBrush = SelectObject(hdcDst, hBrush);
2839 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2840 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2841 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2842 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2843 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2844 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2845 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2846 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2847 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2848 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2849 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2850 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2851 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2852 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2853 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2855 SelectObject(hdcDst, hOldBrush);
2856 DeleteObject(hBrush);
2858 /* Top-down to top-down tests */
2859 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2860 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2862 memset( expected, 0, get_dib_image_size( &biDst ) );
2863 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2864 expected[16] = 0xFEDCBA98, expected[17] = 0x76543210;
2865 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2866 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2868 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2869 expected[16] = 0x00000000, expected[17] = 0x00000000;
2870 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2871 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
2873 expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
2874 expected[16] = 0xCAFED00D, expected[17] = 0xCAFED00D;
2875 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2876 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
2878 /* This is an example of the dst width (height) == 1 exception, explored below */
2879 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2880 expected[16] = 0x00000000, expected[17] = 0x00000000;
2881 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2882 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
2884 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2885 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
2886 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2887 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2889 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2890 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
2891 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2892 1, 1, -2, -2, 0, 0, 2, 2, expected, __LINE__);
2894 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2895 expected[16] = 0x00000000, expected[17] = 0x00000000;
2896 todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2897 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
2899 expected[0] = 0x00000000, expected[1] = 0x00000000;
2900 expected[16] = 0x00000000, expected[17] = 0xCAFED00D, expected[18] = 0xFEEDFACE;
2901 expected[32] = 0x00000000, expected[33] = 0xFEDCBA98, expected[34] = 0x76543210;
2903 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2904 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2906 /* when dst width is 1 merge src width - 1 pixels */
2907 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
2908 srcBuffer[0] = 0x0000ff00, srcBuffer[1] = 0x0000f0f0, srcBuffer[2] = 0x0000cccc, srcBuffer[3] = 0x0000aaaa;
2909 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2911 memset( expected, 0, get_dib_image_size( &biDst ) );
2912 expected[0] = srcBuffer[0];
2913 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2914 0, 0, 1, 1, 0, 0, 2, 1, expected, __LINE__);
2916 expected[0] = srcBuffer[0] & srcBuffer[1];
2917 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2918 0, 0, 1, 1, 0, 0, 3, 1, expected, __LINE__);
2920 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
2921 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2922 0, 0, 1, 1, 0, 0, 4, 1, expected, __LINE__);
2924 /* this doesn't happen if the src width is -ve */
2925 expected[0] = srcBuffer[1] & srcBuffer[2];
2926 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2927 0, 0, 1, 1, 2, 0, -2, 1, expected, __LINE__);
2929 /* when dst width > 1 behaviour reverts to what one would expect */
2930 expected[0] = srcBuffer[0] & srcBuffer[1], expected[1] = srcBuffer[2] & srcBuffer[3];
2931 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2932 0, 0, 2, 1, 0, 0, 4, 1, expected, __LINE__);
2934 /* similarly in the vertical direction */
2935 memset( expected, 0, get_dib_image_size( &biDst ) );
2936 expected[0] = srcBuffer[0];
2937 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2938 0, 0, 1, 1, 0, 0, 1, 2, expected, __LINE__);
2940 /* check that it's the dst size in device units that needs to be 1 */
2941 SetMapMode( hdcDst, MM_ISOTROPIC );
2942 SetWindowExtEx( hdcDst, 200, 200, NULL );
2943 SetViewportExtEx( hdcDst, 100, 100, NULL );
2945 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
2946 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2947 0, 0, 2, 2, 0, 0, 4, 1, expected, __LINE__);
2948 SetMapMode( hdcDst, MM_TEXT );
2950 SelectObject(hdcDst, oldDst);
2951 DeleteObject(bmpDst);
2953 /* Top-down to bottom-up tests */
2954 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
2955 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2956 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2958 biDst.bmiHeader.biHeight = 16;
2959 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2961 oldDst = SelectObject(hdcDst, bmpDst);
2963 memset( expected, 0, get_dib_image_size( &biDst ) );
2965 expected[224] = 0xFEDCBA98, expected[225] = 0x76543210;
2966 expected[240] = 0xCAFED00D, expected[241] = 0xFEEDFACE;
2967 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2968 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2970 expected[224] = 0xFEEDFACE, expected[225] = 0xCAFED00D;
2971 expected[240] = 0x76543210, expected[241] = 0xFEDCBA98;
2972 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2973 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2975 SelectObject(hdcSrc, oldSrc);
2976 DeleteObject(bmpSrc);
2978 /* Bottom-up to bottom-up tests */
2979 biSrc.bmiHeader.biHeight = 16;
2980 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2982 srcBuffer[224] = 0xCAFED00D, srcBuffer[225] = 0xFEEDFACE;
2983 srcBuffer[240] = 0xFEDCBA98, srcBuffer[241] = 0x76543210;
2984 oldSrc = SelectObject(hdcSrc, bmpSrc);
2986 memset( expected, 0, get_dib_image_size( &biDst ) );
2988 expected[224] = 0xCAFED00D, expected[225] = 0xFEEDFACE;
2989 expected[240] = 0xFEDCBA98, expected[241] = 0x76543210;
2990 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2991 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2993 expected[224] = 0x76543210, expected[225] = 0xFEDCBA98;
2994 expected[240] = 0xFEEDFACE, expected[241] = 0xCAFED00D;
2995 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2996 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2998 SelectObject(hdcDst, oldDst);
2999 DeleteObject(bmpDst);
3001 /* Bottom-up to top-down tests */
3002 biDst.bmiHeader.biHeight = -16;
3003 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3005 oldDst = SelectObject(hdcDst, bmpDst);
3007 memset( expected, 0, get_dib_image_size( &biDst ) );
3008 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3009 expected[16] = 0xCAFED00D, expected[17] = 0xFEEDFACE;
3010 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3011 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3013 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3014 expected[16] = 0x76543210, expected[17] = 0xFEDCBA98;
3015 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3016 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3018 SelectObject(hdcSrc, oldSrc);
3019 DeleteObject(bmpSrc);
3021 biSrc.bmiHeader.biHeight = -2;
3022 biSrc.bmiHeader.biBitCount = 24;
3023 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
3024 oldSrc = SelectObject(hdcSrc, bmpSrc);
3026 memset( expected, 0, get_dib_image_size( &biDst ) );
3027 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3028 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
3029 memcpy(dstBuffer, expected, 4 * sizeof(*dstBuffer));
3030 StretchBlt(hdcSrc, 0, 0, 4, 1, hdcDst, 0, 0, 4, 1, SRCCOPY );
3031 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
3032 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3033 expected[0] = 0x00EDFACE, expected[1] = 0x00FED00D;
3034 expected[2] = 0x00543210, expected[3] = 0x00DCBA98;
3035 ok(!memcmp(dstBuffer, expected, 16),
3036 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3037 expected[0], expected[1], expected[2], expected[3],
3038 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3040 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3041 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
3042 memcpy(srcBuffer, expected, 4 * sizeof(*dstBuffer));
3043 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
3044 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3045 expected[0] = 0x00EDFACE, expected[1] = 0x00D00DFE;
3046 expected[2] = 0x0010CAFE, expected[3] = 0x00765432;
3047 ok(!memcmp(dstBuffer, expected, 16),
3048 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3049 expected[0], expected[1], expected[2], expected[3],
3050 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3052 SelectObject(hdcSrc, oldSrc);
3053 DeleteObject(bmpSrc);
3055 biSrc.bmiHeader.biBitCount = 1;
3056 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
3057 oldSrc = SelectObject(hdcSrc, bmpSrc);
3058 *((DWORD *)colors + 0) = 0x123456;
3059 *((DWORD *)colors + 1) = 0x335577;
3060 SetDIBColorTable( hdcSrc, 0, 2, colors );
3061 srcBuffer[0] = 0x55555555;
3062 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
3063 SetTextColor( hdcDst, 0 );
3064 SetBkColor( hdcDst, 0 );
3065 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3066 expected[0] = expected[2] = 0x00123456;
3067 expected[1] = expected[3] = 0x00335577;
3068 ok(!memcmp(dstBuffer, expected, 16),
3069 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3070 expected[0], expected[1], expected[2], expected[3],
3071 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3073 SelectObject(hdcSrc, oldSrc);
3074 DeleteObject(bmpSrc);
3076 bmpSrc = CreateBitmap( 16, 16, 1, 1, 0 );
3077 oldSrc = SelectObject(hdcSrc, bmpSrc);
3078 SetPixel( hdcSrc, 0, 0, 0 );
3079 SetPixel( hdcSrc, 1, 0, 0xffffff );
3080 SetPixel( hdcSrc, 2, 0, 0xffffff );
3081 SetPixel( hdcSrc, 3, 0, 0 );
3082 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
3083 SetTextColor( hdcDst, RGB(0x22,0x44,0x66) );
3084 SetBkColor( hdcDst, RGB(0x65,0x43,0x21) );
3085 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3086 expected[0] = expected[3] = 0x00224466;
3087 expected[1] = expected[2] = 0x00654321;
3088 ok(!memcmp(dstBuffer, expected, 16),
3089 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3090 expected[0], expected[1], expected[2], expected[3],
3091 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3093 SelectObject(hdcSrc, oldSrc);
3094 DeleteObject(bmpSrc);
3098 SelectObject(hdcDst, oldDst);
3099 DeleteObject(bmpDst);
3102 DeleteDC(hdcScreen);
3105 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3106 DWORD dwRop, UINT32 expected, int line)
3108 const UINT32 buffer[2] = { 0xFEDCBA98, 0 };
3109 BITMAPINFO bitmapInfo;
3111 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3112 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3113 bitmapInfo.bmiHeader.biWidth = 2;
3114 bitmapInfo.bmiHeader.biHeight = 1;
3115 bitmapInfo.bmiHeader.biPlanes = 1;
3116 bitmapInfo.bmiHeader.biBitCount = 32;
3117 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3118 bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer);
3120 *dstBuffer = 0x89ABCDEF;
3122 StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop);
3123 ok(expected == *dstBuffer,
3124 "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
3125 dwRop, expected, *dstBuffer, line);
3128 static void check_StretchDIBits_stretch(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3129 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
3130 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
3131 UINT32 expected[4], int line)
3133 BITMAPINFO bitmapInfo;
3135 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3136 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3137 bitmapInfo.bmiHeader.biWidth = 2;
3138 bitmapInfo.bmiHeader.biHeight = -2;
3139 bitmapInfo.bmiHeader.biPlanes = 1;
3140 bitmapInfo.bmiHeader.biBitCount = 32;
3141 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3143 memset(dstBuffer, 0, 16);
3144 StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
3145 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3146 srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
3147 ok(memcmp(dstBuffer, expected, 16) == 0,
3148 "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
3149 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
3150 expected[0], expected[1], expected[2], expected[3],
3151 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
3152 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3153 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
3156 static void test_StretchDIBits(void)
3160 HDC hdcScreen, hdcDst;
3161 UINT32 *dstBuffer, srcBuffer[4];
3162 HBRUSH hBrush, hOldBrush;
3166 memset(&biDst, 0, sizeof(BITMAPINFO));
3167 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3168 biDst.bmiHeader.biWidth = 2;
3169 biDst.bmiHeader.biHeight = -2;
3170 biDst.bmiHeader.biPlanes = 1;
3171 biDst.bmiHeader.biBitCount = 32;
3172 biDst.bmiHeader.biCompression = BI_RGB;
3174 hdcScreen = CreateCompatibleDC(0);
3175 hdcDst = CreateCompatibleDC(hdcScreen);
3178 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3180 oldDst = SelectObject(hdcDst, bmpDst);
3182 hBrush = CreateSolidBrush(0x012345678);
3183 hOldBrush = SelectObject(hdcDst, hBrush);
3185 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3186 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3187 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3188 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3189 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3190 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3191 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3192 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3193 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3194 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3195 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3196 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3197 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3198 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3199 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3201 SelectObject(hdcDst, hOldBrush);
3202 DeleteObject(hBrush);
3204 /* Top-down destination tests */
3205 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3206 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
3208 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
3209 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
3210 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3211 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3213 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3214 expected[2] = 0x00000000, expected[3] = 0x00000000;
3215 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3216 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
3218 expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
3219 expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
3220 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3221 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
3223 expected[0] = 0x42441000, expected[1] = 0x00000000;
3224 expected[2] = 0x00000000, expected[3] = 0x00000000;
3225 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3226 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
3228 expected[0] = 0x00000000, expected[1] = 0x00000000;
3229 expected[2] = 0x00000000, expected[3] = 0x00000000;
3230 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3231 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3233 expected[0] = 0x00000000, expected[1] = 0x00000000;
3234 expected[2] = 0x00000000, expected[3] = 0x00000000;
3235 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3236 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3238 expected[0] = 0x00000000, expected[1] = 0x00000000;
3239 expected[2] = 0x00000000, expected[3] = 0x00000000;
3240 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3241 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
3243 expected[0] = 0x00000000, expected[1] = 0x00000000;
3244 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
3245 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3246 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3248 SelectObject(hdcDst, oldDst);
3249 DeleteObject(bmpDst);
3251 /* Bottom up destination tests */
3252 biDst.bmiHeader.biHeight = 2;
3253 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3255 oldDst = SelectObject(hdcDst, bmpDst);
3257 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3258 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
3259 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3260 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3263 SelectObject(hdcDst, oldDst);
3264 DeleteObject(bmpDst);
3267 DeleteDC(hdcScreen);
3270 static void test_GdiAlphaBlend(void)
3282 BLENDFUNCTION blend;
3284 if (!pGdiAlphaBlend)
3286 win_skip("GdiAlphaBlend() is not implemented\n");
3290 hdcNull = GetDC(NULL);
3291 hdcDst = CreateCompatibleDC(hdcNull);
3292 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
3293 hdcSrc = CreateCompatibleDC(hdcNull);
3295 bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3296 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3297 bmi->bmiHeader.biHeight = 20;
3298 bmi->bmiHeader.biWidth = 20;
3299 bmi->bmiHeader.biBitCount = 32;
3300 bmi->bmiHeader.biPlanes = 1;
3301 bmi->bmiHeader.biCompression = BI_RGB;
3302 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3303 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3305 oldDst = SelectObject(hdcDst, bmpDst);
3306 oldSrc = SelectObject(hdcSrc, bmpSrc);
3308 blend.BlendOp = AC_SRC_OVER;
3309 blend.BlendFlags = 0;
3310 blend.SourceConstantAlpha = 128;
3311 blend.AlphaFormat = 0;
3313 SetLastError(0xdeadbeef);
3314 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3315 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3317 SetLastError(0xdeadbeef);
3318 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3319 ok( !ret, "GdiAlphaBlend succeeded\n" );
3320 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3322 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3323 ok( !ret, "GdiAlphaBlend succeeded\n" );
3324 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend);
3325 ok( !ret, "GdiAlphaBlend succeeded\n" );
3326 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3327 ok( !ret, "GdiAlphaBlend succeeded\n" );
3328 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3329 ok( !ret, "GdiAlphaBlend succeeded\n" );
3331 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
3332 SetLastError(0xdeadbeef);
3333 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3334 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3335 SetLastError(0xdeadbeef);
3336 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3337 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3338 SetMapMode(hdcSrc, MM_ANISOTROPIC);
3339 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
3340 SetLastError(0xdeadbeef);
3341 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend);
3342 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3343 SetLastError(0xdeadbeef);
3344 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend);
3345 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3347 SetLastError(0xdeadbeef);
3348 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend);
3349 ok( !ret, "GdiAlphaBlend succeeded\n" );
3350 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3352 /* overlapping source and dest not allowed */
3354 SetLastError(0xdeadbeef);
3355 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 19, 19, 20, 20, blend);
3356 ok( !ret, "GdiAlphaBlend succeeded\n" );
3357 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3359 SetLastError(0xdeadbeef);
3360 ret = pGdiAlphaBlend(hdcDst, 20, 20, 20, 20, hdcDst, 1, 1, 20, 20, blend);
3361 ok( !ret, "GdiAlphaBlend succeeded\n" );
3362 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3364 SetLastError(0xdeadbeef);
3365 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 20, 10, 20, 20, blend);
3366 ok( ret, "GdiAlphaBlend succeeded\n" );
3367 SetLastError(0xdeadbeef);
3368 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 10, 20, 20, 20, blend);
3369 ok( ret, "GdiAlphaBlend succeeded\n" );
3371 /* AC_SRC_ALPHA requires 32-bpp BI_RGB format */
3373 blend.AlphaFormat = AC_SRC_ALPHA;
3374 SetLastError(0xdeadbeef);
3375 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3376 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3378 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3379 ((DWORD *)bmi->bmiColors)[0] = 0xff0000;
3380 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3381 ((DWORD *)bmi->bmiColors)[2] = 0x0000ff;
3382 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3383 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3384 oldSrc = SelectObject(hdcSrc, bmpSrc);
3385 DeleteObject( oldSrc );
3387 SetLastError(0xdeadbeef);
3388 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3389 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3391 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3392 ((DWORD *)bmi->bmiColors)[0] = 0x0000ff;
3393 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3394 ((DWORD *)bmi->bmiColors)[2] = 0xff0000;
3395 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3396 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3397 oldSrc = SelectObject(hdcSrc, bmpSrc);
3398 DeleteObject( oldSrc );
3400 SetLastError(0xdeadbeef);
3401 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3402 ok( !ret, "GdiAlphaBlend succeeded\n" );
3403 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3405 bmi->bmiHeader.biBitCount = 24;
3406 bmi->bmiHeader.biCompression = BI_RGB;
3407 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3408 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3409 oldSrc = SelectObject(hdcSrc, bmpSrc);
3410 DeleteObject( oldSrc );
3412 SetLastError(0xdeadbeef);
3413 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3414 ok( !ret, "GdiAlphaBlend succeeded\n" );
3415 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3417 bmi->bmiHeader.biBitCount = 1;
3418 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3419 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3420 oldSrc = SelectObject(hdcSrc, bmpSrc);
3421 DeleteObject( oldSrc );
3423 SetLastError(0xdeadbeef);
3424 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3425 ok( !ret, "GdiAlphaBlend succeeded\n" );
3426 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3428 bmpSrc = CreateBitmap( 100, 100, 1, 1, NULL );
3429 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3430 oldSrc = SelectObject(hdcSrc, bmpSrc);
3431 DeleteObject( oldSrc );
3433 SetLastError(0xdeadbeef);
3434 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3435 ok( !ret, "GdiAlphaBlend succeeded\n" );
3436 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3438 SelectObject(hdcDst, oldDst);
3439 SelectObject(hdcSrc, oldSrc);
3440 DeleteObject(bmpSrc);
3441 DeleteObject(bmpDst);
3445 ReleaseDC(NULL, hdcNull);
3449 static void test_GdiGradientFill(void)
3456 GRADIENT_RECT rect[] = { { 0, 0 }, { 0, 1 }, { 2, 3 } };
3457 GRADIENT_TRIANGLE tri[] = { { 0, 0, 0 }, { 0, 1, 2 }, { 0, 2, 1 }, { 0, 1, 3 } };
3458 TRIVERTEX vt[3] = { { 2, 2, 0xff00, 0x0000, 0x0000, 0x8000 },
3459 { 10, 10, 0x0000, 0xff00, 0x0000, 0x8000 },
3460 { 20, 10, 0x0000, 0x0000, 0xff00, 0xff00 } };
3462 if (!pGdiGradientFill)
3464 win_skip( "GdiGradientFill is not implemented\n" );
3468 hdc = CreateCompatibleDC( NULL );
3469 bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3470 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3471 bmi->bmiHeader.biHeight = 20;
3472 bmi->bmiHeader.biWidth = 20;
3473 bmi->bmiHeader.biBitCount = 32;
3474 bmi->bmiHeader.biPlanes = 1;
3475 bmi->bmiHeader.biCompression = BI_RGB;
3476 bmp = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3477 ok( bmp != NULL, "couldn't create bitmap\n" );
3478 SelectObject( hdc, bmp );
3480 SetLastError( 0xdeadbeef );
3481 ret = pGdiGradientFill( hdc, vt, 3, rect, 1, GRADIENT_FILL_RECT_H );
3482 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3483 SetLastError( 0xdeadbeef );
3484 ret = pGdiGradientFill( hdc, vt, 3, rect, 1, 3 );
3485 ok( !ret, "GdiGradientFill succeeded\n" );
3486 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3487 SetLastError( 0xdeadbeef );
3488 ret = pGdiGradientFill( (HDC)0xdead, vt, 3, rect, 1, GRADIENT_FILL_RECT_H );
3489 ok( !ret, "GdiGradientFill succeeded\n" );
3490 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3491 SetLastError( 0xdeadbeef );
3492 ret = pGdiGradientFill( NULL, NULL, 0, rect, 1, GRADIENT_FILL_RECT_H );
3493 ok( !ret, "GdiGradientFill succeeded\n" );
3494 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3495 ret = pGdiGradientFill( hdc, NULL, 0, rect, 1, GRADIENT_FILL_RECT_H );
3496 ok( !ret, "GdiGradientFill succeeded\n" );
3497 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3498 SetLastError( 0xdeadbeef );
3499 ret = pGdiGradientFill( hdc, NULL, 3, rect, 1, GRADIENT_FILL_RECT_H );
3500 ok( !ret, "GdiGradientFill succeeded\n" );
3501 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3502 SetLastError( 0xdeadbeef );
3503 ret = pGdiGradientFill( hdc, vt, 3, NULL, 0, GRADIENT_FILL_RECT_H );
3504 ok( !ret, "GdiGradientFill succeeded\n" );
3505 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3506 SetLastError( 0xdeadbeef );
3507 ret = pGdiGradientFill( hdc, vt, 3, NULL, 1, GRADIENT_FILL_RECT_H );
3508 ok( !ret, "GdiGradientFill succeeded\n" );
3509 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3510 SetLastError( 0xdeadbeef );
3511 ret = pGdiGradientFill( hdc, vt, 3, rect, 0, GRADIENT_FILL_RECT_H );
3512 ok( !ret, "GdiGradientFill succeeded\n" );
3513 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3514 SetLastError( 0xdeadbeef );
3515 ret = pGdiGradientFill( hdc, vt, 3, rect, 3, GRADIENT_FILL_RECT_H );
3516 ok( !ret, "GdiGradientFill succeeded\n" );
3517 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3518 rect[2].UpperLeft = rect[2].LowerRight = 1;
3519 SetLastError( 0xdeadbeef );
3520 ret = pGdiGradientFill( hdc, vt, 3, rect, 3, GRADIENT_FILL_RECT_H );
3521 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3522 SetLastError( 0xdeadbeef );
3523 ret = pGdiGradientFill( hdc, vt, 1, rect, 1, GRADIENT_FILL_RECT_H );
3524 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3525 SetLastError( 0xdeadbeef );
3526 ret = pGdiGradientFill( hdc, vt, 1, tri, 0, GRADIENT_FILL_TRIANGLE );
3527 ok( !ret, "GdiGradientFill succeeded\n" );
3528 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3529 SetLastError( 0xdeadbeef );
3530 ret = pGdiGradientFill( hdc, vt, 1, tri, 1, GRADIENT_FILL_TRIANGLE );
3531 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3532 SetLastError( 0xdeadbeef );
3533 ret = pGdiGradientFill( hdc, vt, 3, tri, 2, GRADIENT_FILL_TRIANGLE );
3534 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3535 SetLastError( 0xdeadbeef );
3536 ret = pGdiGradientFill( hdc, vt, 3, tri, 3, GRADIENT_FILL_TRIANGLE );
3537 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3538 SetLastError( 0xdeadbeef );
3539 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3540 ok( !ret, "GdiGradientFill succeeded\n" );
3541 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3543 SetLastError( 0xdeadbeef );
3544 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3545 ok( !ret, "GdiGradientFill succeeded\n" );
3546 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3548 SetLastError( 0xdeadbeef );
3549 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3550 ok( !ret, "GdiGradientFill succeeded\n" );
3551 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3552 tri[3].Vertex1 = tri[3].Vertex2 = tri[3].Vertex3 = 1;
3553 SetLastError( 0xdeadbeef );
3554 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3555 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3558 DeleteObject( bmp );
3561 static void test_clipping(void)
3569 HDC hdcDst = CreateCompatibleDC( NULL );
3570 HDC hdcSrc = CreateCompatibleDC( NULL );
3572 BITMAPINFO bmpinfo={{0}};
3573 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3574 bmpinfo.bmiHeader.biWidth = 100;
3575 bmpinfo.bmiHeader.biHeight = 100;
3576 bmpinfo.bmiHeader.biPlanes = 1;
3577 bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3578 bmpinfo.bmiHeader.biCompression = BI_RGB;
3580 bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3581 ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3582 SelectObject( hdcDst, bmpDst );
3584 bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3585 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3586 SelectObject( hdcSrc, bmpSrc );
3588 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3589 ok(result, "BitBlt failed\n");
3591 hRgn = CreateRectRgn( 0,0,0,0 );
3592 SelectClipRgn( hdcDst, hRgn );
3594 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3595 ok(result, "BitBlt failed\n");
3597 DeleteObject( bmpDst );
3598 DeleteObject( bmpSrc );
3599 DeleteObject( hRgn );
3604 static void test_32bit_bitmap_blt(void)
3607 HBITMAP bmpSrc, bmpDst;
3608 HBITMAP oldSrc, oldDst;
3609 HDC hdcSrc, hdcDst, hdcScreen;
3611 DWORD colorSrc = 0x11223344;
3613 memset(&biDst, 0, sizeof(BITMAPINFO));
3614 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3615 biDst.bmiHeader.biWidth = 2;
3616 biDst.bmiHeader.biHeight = -2;
3617 biDst.bmiHeader.biPlanes = 1;
3618 biDst.bmiHeader.biBitCount = 32;
3619 biDst.bmiHeader.biCompression = BI_RGB;
3621 hdcScreen = CreateCompatibleDC(0);
3622 if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3624 DeleteDC(hdcScreen);
3625 trace("Skipping 32-bit DDB test\n");
3629 hdcSrc = CreateCompatibleDC(hdcScreen);
3630 bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3631 oldSrc = SelectObject(hdcSrc, bmpSrc);
3633 hdcDst = CreateCompatibleDC(hdcScreen);
3634 bmpDst = CreateDIBSection(hdcDst, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3635 oldDst = SelectObject(hdcDst, bmpDst);
3637 StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3638 ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3641 SelectObject(hdcDst, oldDst);
3642 DeleteObject(bmpDst);
3645 SelectObject(hdcSrc, oldSrc);
3646 DeleteObject(bmpSrc);
3649 DeleteDC(hdcScreen);
3653 * Used by test_GetDIBits_top_down to create the bitmap to test against.
3655 static void setup_picture(char *picture, int bpp)
3663 /*Set the first byte in each pixel to the index of that pixel.*/
3664 for (i = 0; i < 4; i++)
3665 picture[i * (bpp / 8)] = i;
3670 /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
3677 static void test_GetDIBits_top_down(int bpp)
3680 HBITMAP bmptb, bmpbt;
3686 memset( &bi, 0, sizeof(bi) );
3687 bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
3688 bi.bmiHeader.biWidth=2;
3689 bi.bmiHeader.biHeight=2;
3690 bi.bmiHeader.biPlanes=1;
3691 bi.bmiHeader.biBitCount=bpp;
3692 bi.bmiHeader.biCompression=BI_RGB;
3694 /*Get the device context for the screen.*/
3696 ok(hdc != NULL, "Could not get a handle to a device context.\n");
3698 /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
3699 bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3700 ok(bmpbt != NULL, "Could not create a DIB section.\n");
3701 /*Now that we have a pointer to the pixels, we write to them.*/
3702 setup_picture((char*)picture, bpp);
3703 /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
3704 bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
3705 bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3706 ok(bmptb != NULL, "Could not create a DIB section.\n");
3707 /*Write to this top to bottom bitmap.*/
3708 setup_picture((char*)picture, bpp);
3710 bi.bmiHeader.biWidth = 1;
3712 bi.bmiHeader.biHeight = 2;
3713 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3714 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3715 /*Check the first byte of the pixel.*/
3716 ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3717 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3718 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3719 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3720 /*Check second scanline.*/
3721 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3722 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3723 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3724 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3725 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3726 ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3727 /*Check both scanlines.*/
3728 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3729 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3730 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3731 ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3732 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3733 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3734 ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3735 ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3737 /*Make destination bitmap top-down.*/
3738 bi.bmiHeader.biHeight = -2;
3739 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3740 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3741 ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3742 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3743 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3744 ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3745 /*Check second scanline.*/
3746 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3747 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3748 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3749 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3750 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3751 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3752 /*Check both scanlines.*/
3753 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3754 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3755 ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3756 ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3757 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3758 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3759 ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3760 ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3762 DeleteObject(bmpbt);
3763 DeleteObject(bmptb);
3766 static void test_GetSetDIBits_rtl(void)
3769 HBITMAP bitmap, orig_bitmap;
3772 DWORD bits_1[8 * 8], bits_2[8 * 8];
3776 win_skip("Don't have SetLayout\n");
3780 hdc = GetDC( NULL );
3781 hdc_mem = CreateCompatibleDC( hdc );
3782 pSetLayout( hdc_mem, LAYOUT_LTR );
3784 bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
3785 orig_bitmap = SelectObject( hdc_mem, bitmap );
3786 SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
3787 SelectObject( hdc_mem, orig_bitmap );
3789 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3790 info.bmiHeader.biWidth = 8;
3791 info.bmiHeader.biHeight = 8;
3792 info.bmiHeader.biPlanes = 1;
3793 info.bmiHeader.biBitCount = 32;
3794 info.bmiHeader.biCompression = BI_RGB;
3796 /* First show that GetDIBits ignores the layout mode. */
3798 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3799 ok(ret == 8, "got %d\n", ret);
3800 ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
3802 pSetLayout( hdc_mem, LAYOUT_RTL );
3804 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3805 ok(ret == 8, "got %d\n", ret);
3807 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3809 /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
3810 followed by a GetDIBits and show that the bits remain unchanged. */
3812 pSetLayout( hdc_mem, LAYOUT_LTR );
3814 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3815 ok(ret == 8, "got %d\n", ret);
3816 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3817 ok(ret == 8, "got %d\n", ret);
3818 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3820 pSetLayout( hdc_mem, LAYOUT_RTL );
3822 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3823 ok(ret == 8, "got %d\n", ret);
3824 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3825 ok(ret == 8, "got %d\n", ret);
3826 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3828 DeleteObject( bitmap );
3829 DeleteDC( hdc_mem );
3830 ReleaseDC( NULL, hdc );
3833 static void test_GetDIBits_scanlines(void)
3837 HDC hdc = GetDC( NULL );
3839 DWORD data[128], inverted_bits[64];
3842 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
3844 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3845 info->bmiHeader.biWidth = 8;
3846 info->bmiHeader.biHeight = 8;
3847 info->bmiHeader.biPlanes = 1;
3848 info->bmiHeader.biBitCount = 32;
3849 info->bmiHeader.biCompression = BI_RGB;
3851 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3853 for (i = 0; i < 64; i++)
3856 inverted_bits[56 - (i & ~7) + (i & 7)] = i;
3861 memset( data, 0xaa, sizeof(data) );
3863 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3864 ok( ret == 8, "got %d\n", ret );
3865 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3866 memset( data, 0xaa, sizeof(data) );
3868 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3869 ok( ret == 5, "got %d\n", ret );
3870 ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
3871 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3872 memset( data, 0xaa, sizeof(data) );
3874 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3875 ok( ret == 7, "got %d\n", ret );
3876 ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
3877 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3878 memset( data, 0xaa, sizeof(data) );
3880 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3881 ok( ret == 1, "got %d\n", ret );
3882 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3883 memset( data, 0xaa, sizeof(data) );
3885 info->bmiHeader.biHeight = 16;
3886 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3887 ok( ret == 5, "got %d\n", ret );
3888 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3889 ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
3890 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3891 memset( data, 0xaa, sizeof(data) );
3893 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3894 ok( ret == 6, "got %d\n", ret );
3895 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3896 ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
3897 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3898 memset( data, 0xaa, sizeof(data) );
3900 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3901 ok( ret == 0, "got %d\n", ret );
3902 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3903 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3904 memset( data, 0xaa, sizeof(data) );
3906 info->bmiHeader.biHeight = 5;
3907 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3908 ok( ret == 2, "got %d\n", ret );
3909 ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
3910 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3911 memset( data, 0xaa, sizeof(data) );
3915 info->bmiHeader.biHeight = -8;
3916 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3917 ok( ret == 8, "got %d\n", ret );
3918 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3919 memset( data, 0xaa, sizeof(data) );
3921 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3922 ok( ret == 5, "got %d\n", ret );
3923 ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
3924 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3925 memset( data, 0xaa, sizeof(data) );
3927 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3928 ok( ret == 7, "got %d\n", ret );
3929 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3930 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3931 memset( data, 0xaa, sizeof(data) );
3933 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3934 ok( ret == 4, "got %d\n", ret );
3935 ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
3936 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3937 memset( data, 0xaa, sizeof(data) );
3939 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3940 ok( ret == 5, "got %d\n", ret );
3941 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3942 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3943 memset( data, 0xaa, sizeof(data) );
3945 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3946 ok( ret == 5, "got %d\n", ret );
3947 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3948 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3949 memset( data, 0xaa, sizeof(data) );
3951 info->bmiHeader.biHeight = -16;
3952 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3953 ok( ret == 8, "got %d\n", ret );
3954 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3955 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3956 memset( data, 0xaa, sizeof(data) );
3958 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3959 ok( ret == 5, "got %d\n", ret );
3960 ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
3961 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3962 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3963 memset( data, 0xaa, sizeof(data) );
3965 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3966 ok( ret == 8, "got %d\n", ret );
3967 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3968 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3969 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3970 memset( data, 0xaa, sizeof(data) );
3972 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3973 ok( ret == 8, "got %d\n", ret );
3974 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3975 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3976 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3977 memset( data, 0xaa, sizeof(data) );
3979 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3980 ok( ret == 7, "got %d\n", ret );
3981 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3982 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3983 memset( data, 0xaa, sizeof(data) );
3985 ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
3986 ok( ret == 1, "got %d\n", ret );
3987 for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3988 memset( data, 0xaa, sizeof(data) );
3990 info->bmiHeader.biHeight = -5;
3991 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3992 ok( ret == 2, "got %d\n", ret );
3993 ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
3994 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3995 memset( data, 0xaa, sizeof(data) );
3997 DeleteObject( dib );
3999 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4000 info->bmiHeader.biWidth = 8;
4001 info->bmiHeader.biHeight = -8;
4002 info->bmiHeader.biPlanes = 1;
4003 info->bmiHeader.biBitCount = 32;
4004 info->bmiHeader.biCompression = BI_RGB;
4006 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4008 for (i = 0; i < 64; i++) dib_bits[i] = i;
4012 info->bmiHeader.biHeight = -8;
4013 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4014 ok( ret == 8, "got %d\n", ret );
4015 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4016 memset( data, 0xaa, sizeof(data) );
4018 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4019 ok( ret == 5, "got %d\n", ret );
4020 ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
4021 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4022 memset( data, 0xaa, sizeof(data) );
4024 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4025 ok( ret == 7, "got %d\n", ret );
4026 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
4027 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4028 memset( data, 0xaa, sizeof(data) );
4030 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4031 ok( ret == 4, "got %d\n", ret );
4032 ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
4033 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4034 memset( data, 0xaa, sizeof(data) );
4036 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
4037 ok( ret == 5, "got %d\n", ret );
4038 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
4039 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4040 memset( data, 0xaa, sizeof(data) );
4042 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
4043 ok( ret == 5, "got %d\n", ret );
4044 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
4045 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4046 memset( data, 0xaa, sizeof(data) );
4048 info->bmiHeader.biHeight = -16;
4049 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
4050 ok( ret == 8, "got %d\n", ret );
4051 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4052 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4053 memset( data, 0xaa, sizeof(data) );
4055 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4056 ok( ret == 5, "got %d\n", ret );
4057 ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
4058 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4059 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4060 memset( data, 0xaa, sizeof(data) );
4062 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4063 ok( ret == 8, "got %d\n", ret );
4064 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4065 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4066 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4067 memset( data, 0xaa, sizeof(data) );
4069 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4070 ok( ret == 8, "got %d\n", ret );
4071 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4072 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4073 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4074 memset( data, 0xaa, sizeof(data) );
4076 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4077 ok( ret == 7, "got %d\n", ret );
4078 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
4079 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4080 memset( data, 0xaa, sizeof(data) );
4082 info->bmiHeader.biHeight = -5;
4083 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4084 ok( ret == 2, "got %d\n", ret );
4085 ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
4086 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4087 memset( data, 0xaa, sizeof(data) );
4092 info->bmiHeader.biHeight = 8;
4094 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4095 ok( ret == 8, "got %d\n", ret );
4096 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4097 memset( data, 0xaa, sizeof(data) );
4099 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4100 ok( ret == 5, "got %d\n", ret );
4101 ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
4102 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4103 memset( data, 0xaa, sizeof(data) );
4105 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4106 ok( ret == 7, "got %d\n", ret );
4107 ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
4108 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4109 memset( data, 0xaa, sizeof(data) );
4111 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4112 ok( ret == 1, "got %d\n", ret );
4113 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4114 memset( data, 0xaa, sizeof(data) );
4116 info->bmiHeader.biHeight = 16;
4117 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4118 ok( ret == 5, "got %d\n", ret );
4119 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4120 ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
4121 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4122 memset( data, 0xaa, sizeof(data) );
4124 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
4125 ok( ret == 6, "got %d\n", ret );
4126 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4127 ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
4128 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4129 memset( data, 0xaa, sizeof(data) );
4131 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
4132 ok( ret == 0, "got %d\n", ret );
4133 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4134 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4135 memset( data, 0xaa, sizeof(data) );
4137 info->bmiHeader.biHeight = 5;
4138 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4139 ok( ret == 2, "got %d\n", ret );
4140 ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
4141 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4142 memset( data, 0xaa, sizeof(data) );
4144 DeleteObject( dib );
4146 ReleaseDC( NULL, hdc );
4147 HeapFree( GetProcessHeap(), 0, info );
4151 static void test_SetDIBits(void)
4153 char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
4154 LOGPALETTE *pal = (LOGPALETTE *)palbuf;
4155 PALETTEENTRY *palent = pal->palPalEntry;
4159 HDC hdc = GetDC( NULL );
4160 DWORD data[128], inverted_data[128];
4164 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4166 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4167 info->bmiHeader.biWidth = 8;
4168 info->bmiHeader.biHeight = 8;
4169 info->bmiHeader.biPlanes = 1;
4170 info->bmiHeader.biBitCount = 32;
4171 info->bmiHeader.biCompression = BI_RGB;
4173 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4174 memset( dib_bits, 0xaa, 64 * 4 );
4176 for (i = 0; i < 128; i++)
4179 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4184 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4185 ok( ret == 8, "got %d\n", ret );
4186 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4187 memset( dib_bits, 0xaa, 64 * 4 );
4189 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4190 ok( ret == 5, "got %d\n", ret );
4191 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4192 ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
4193 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4194 memset( dib_bits, 0xaa, 64 * 4 );
4196 /* top of dst is aligned with startscans down for the top of the src.
4197 Then starting from the bottom of src, lines rows are copied across. */
4199 info->bmiHeader.biHeight = 16;
4200 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4201 ok( ret == 12, "got %d\n", ret );
4202 ok( !memcmp( dib_bits, data + 56, 40 * 4 ), "bits differ\n");
4203 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4204 memset( dib_bits, 0xaa, 64 * 4 );
4206 info->bmiHeader.biHeight = 5;
4207 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4208 ok( ret == 2, "got %d\n", ret );
4209 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4210 ok( !memcmp( dib_bits + 32, data, 16 * 4 ), "bits differ\n");
4211 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4212 memset( dib_bits, 0xaa, 64 * 4 );
4215 info->bmiHeader.biHeight = -8;
4216 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4217 ok( ret == 8, "got %d\n", ret );
4218 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4219 memset( dib_bits, 0xaa, 64 * 4 );
4221 /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
4222 we copy lines rows from the top of the src */
4224 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4225 ok( ret == 5, "got %d\n", ret );
4226 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4227 ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
4228 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4229 memset( dib_bits, 0xaa, 64 * 4 );
4231 info->bmiHeader.biHeight = -16;
4232 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4233 ok( ret == 12, "got %d\n", ret );
4234 ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
4235 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4236 memset( dib_bits, 0xaa, 64 * 4 );
4238 ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4239 ok( ret == 12, "got %d\n", ret );
4240 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4241 memset( dib_bits, 0xaa, 64 * 4 );
4243 ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4244 ok( ret == 12, "got %d\n", ret );
4245 ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
4246 memset( dib_bits, 0xaa, 64 * 4 );
4248 info->bmiHeader.biHeight = -5;
4249 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4250 ok( ret == 2, "got %d\n", ret );
4251 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4252 ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
4253 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4254 memset( dib_bits, 0xaa, 64 * 4 );
4256 DeleteObject( dib );
4258 info->bmiHeader.biHeight = -8;
4260 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4261 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4265 /* like the t-d -> b-u case. */
4267 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4268 ok( ret == 8, "got %d\n", ret );
4269 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4270 memset( dib_bits, 0xaa, 64 * 4 );
4272 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4273 ok( ret == 5, "got %d\n", ret );
4274 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4275 ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
4276 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4277 memset( dib_bits, 0xaa, 64 * 4 );
4279 info->bmiHeader.biHeight = -16;
4280 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4281 ok( ret == 12, "got %d\n", ret );
4282 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4283 ok( !memcmp( dib_bits + 24, data, 40 * 4 ), "bits differ\n");
4284 memset( dib_bits, 0xaa, 64 * 4 );
4286 info->bmiHeader.biHeight = -5;
4287 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4288 ok( ret == 2, "got %d\n", ret );
4289 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4290 ok( !memcmp( dib_bits + 16, data, 16 * 4 ), "bits differ\n");
4291 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4292 memset( dib_bits, 0xaa, 64 * 4 );
4295 /* like the b-u -> b-u case */
4297 info->bmiHeader.biHeight = 8;
4298 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4299 ok( ret == 8, "got %d\n", ret );
4300 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4301 memset( dib_bits, 0xaa, 64 * 4 );
4303 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4304 ok( ret == 5, "got %d\n", ret );
4305 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4306 ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
4307 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4308 memset( dib_bits, 0xaa, 64 * 4 );
4310 info->bmiHeader.biHeight = 16;
4311 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4312 ok( ret == 12, "got %d\n", ret );
4313 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4314 ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
4315 memset( dib_bits, 0xaa, 64 * 4 );
4317 info->bmiHeader.biHeight = 5;
4318 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4319 ok( ret == 2, "got %d\n", ret );
4320 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4321 ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
4322 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4323 memset( dib_bits, 0xaa, 64 * 4 );
4325 /* handling of partial color table */
4327 info->bmiHeader.biHeight = -8;
4328 info->bmiHeader.biBitCount = 8;
4329 info->bmiHeader.biClrUsed = 137;
4330 for (i = 0; i < 256; i++)
4332 info->bmiColors[i].rgbRed = 255 - i;
4333 info->bmiColors[i].rgbGreen = i * 2;
4334 info->bmiColors[i].rgbBlue = i;
4335 info->bmiColors[i].rgbReserved = 0;
4337 for (i = 0; i < 64; i++) ((BYTE *)data)[i] = i * 4 + 1;
4338 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4339 ok( ret == 8, "got %d\n", ret );
4340 for (i = 0; i < 64; i++)
4342 int idx = i * 4 + 1;
4343 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : (info->bmiColors[idx].rgbRed << 16 |
4344 info->bmiColors[idx].rgbGreen << 8 |
4345 info->bmiColors[idx].rgbBlue);
4346 ok( dib_bits[i] == expect, "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
4348 memset( dib_bits, 0xaa, 64 * 4 );
4350 /* handling of DIB_PAL_COLORS */
4352 pal->palVersion = 0x300;
4353 pal->palNumEntries = 137;
4354 info->bmiHeader.biClrUsed = 221;
4355 for (i = 0; i < 256; i++)
4357 palent[i].peRed = i * 2;
4358 palent[i].peGreen = 255 - i;
4359 palent[i].peBlue = i;
4361 palette = CreatePalette( pal );
4362 ok( palette != 0, "palette creation failed\n" );
4363 SelectPalette( hdc, palette, FALSE );
4364 for (i = 0; i < 256; i++) ((WORD *)info->bmiColors)[i] = 255 - i;
4365 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_PAL_COLORS );
4366 ok( ret == 8, "got %d\n", ret );
4367 for (i = 0; i < 64; i++)
4369 int idx = i * 4 + 1;
4370 int ent = (255 - idx) % pal->palNumEntries;
4371 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 :
4372 (palent[ent].peRed << 16 | palent[ent].peGreen << 8 | palent[ent].peBlue);
4373 ok( dib_bits[i] == expect || broken(dib_bits[i] == 0), /* various Windows versions get some values wrong */
4374 "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
4376 memset( dib_bits, 0xaa, 64 * 4 );
4378 ReleaseDC( NULL, hdc );
4379 DeleteObject( dib );
4380 DeleteObject( palette );
4381 HeapFree( GetProcessHeap(), 0, info );
4384 static void test_SetDIBits_RLE4(void)
4388 HDC hdc = GetDC( NULL );
4389 BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00, /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
4390 0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
4391 0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00, /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
4392 0x00, 0x02, 0x01, 0x02, 0x05, 0x87, /* dx=1, dy=2, 8, 7, 8, 7, 8 */
4393 0x00, 0x01 }; /* <eod> */
4396 DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
4397 0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
4398 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4399 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4400 0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
4401 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4402 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4403 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4405 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4407 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4408 info->bmiHeader.biWidth = 8;
4409 info->bmiHeader.biHeight = 8;
4410 info->bmiHeader.biPlanes = 1;
4411 info->bmiHeader.biBitCount = 32;
4412 info->bmiHeader.biCompression = BI_RGB;
4414 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4415 memset( dib_bits, 0xaa, 64 * 4 );
4417 info->bmiHeader.biBitCount = 4;
4418 info->bmiHeader.biCompression = BI_RLE4;
4419 info->bmiHeader.biSizeImage = sizeof(rle4_data);
4421 for (i = 0; i < 16; i++)
4423 info->bmiColors[i].rgbRed = i;
4424 info->bmiColors[i].rgbGreen = i;
4425 info->bmiColors[i].rgbBlue = i;
4426 info->bmiColors[i].rgbReserved = 0;
4429 ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
4430 ok( ret == 8, "got %d\n", ret );
4431 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
4432 memset( dib_bits, 0xaa, 64 * 4 );
4434 DeleteObject( dib );
4435 ReleaseDC( NULL, hdc );
4436 HeapFree( GetProcessHeap(), 0, info );
4439 static void test_SetDIBits_RLE8(void)
4443 HDC hdc = GetDC( NULL );
4444 BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00, /* 2, 2, 2, f0, f0, f0, f0, <eol> */
4445 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4446 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4447 0x00, 0x01 }; /* <eod> */
4450 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4451 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4452 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4453 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4454 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4455 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4456 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4457 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4458 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4459 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4460 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4461 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4462 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4463 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4464 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4465 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4467 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4469 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4470 info->bmiHeader.biWidth = 8;
4471 info->bmiHeader.biHeight = 8;
4472 info->bmiHeader.biPlanes = 1;
4473 info->bmiHeader.biBitCount = 32;
4474 info->bmiHeader.biCompression = BI_RGB;
4476 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4477 memset( dib_bits, 0xaa, 64 * 4 );
4479 info->bmiHeader.biBitCount = 8;
4480 info->bmiHeader.biCompression = BI_RLE8;
4481 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4483 for (i = 0; i < 256; i++)
4485 info->bmiColors[i].rgbRed = i;
4486 info->bmiColors[i].rgbGreen = i;
4487 info->bmiColors[i].rgbBlue = i;
4488 info->bmiColors[i].rgbReserved = 0;
4491 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4492 ok( ret == 8, "got %d\n", ret );
4493 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4494 memset( dib_bits, 0xaa, 64 * 4 );
4496 /* startscan and lines are ignored, unless lines == 0 */
4497 ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4498 ok( ret == 8, "got %d\n", ret );
4499 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4500 memset( dib_bits, 0xaa, 64 * 4 );
4502 ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4503 ok( ret == 8, "got %d\n", ret );
4504 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4505 memset( dib_bits, 0xaa, 64 * 4 );
4507 ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4508 ok( ret == 0, "got %d\n", ret );
4509 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4510 memset( dib_bits, 0xaa, 64 * 4 );
4512 /* reduce width to 4, left-hand side of dst is touched. */
4513 info->bmiHeader.biWidth = 4;
4514 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4515 ok( ret == 8, "got %d\n", ret );
4516 for (i = 0; i < 64; i++)
4518 DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4519 ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4521 memset( dib_bits, 0xaa, 64 * 4 );
4523 /* Show that the top lines are aligned by adjusting the height of the src */
4525 /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4526 info->bmiHeader.biWidth = 8;
4527 info->bmiHeader.biHeight = 4;
4528 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4529 ok( ret == 4, "got %d\n", ret );
4530 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4531 ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4532 memset( dib_bits, 0xaa, 64 * 4 );
4534 /* increase the height to 9 -> everything moves down one row. */
4535 info->bmiHeader.biHeight = 9;
4536 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4537 ok( ret == 9, "got %d\n", ret );
4538 ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4539 for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4540 memset( dib_bits, 0xaa, 64 * 4 );
4542 /* top-down compressed dibs are invalid */
4543 info->bmiHeader.biHeight = -8;
4544 SetLastError( 0xdeadbeef );
4545 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4546 ok( ret == 0, "got %d\n", ret );
4547 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4548 DeleteObject( dib );
4552 info->bmiHeader.biHeight = -8;
4553 info->bmiHeader.biBitCount = 32;
4554 info->bmiHeader.biCompression = BI_RGB;
4555 info->bmiHeader.biSizeImage = 0;
4557 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4558 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4560 info->bmiHeader.biHeight = 8;
4561 info->bmiHeader.biBitCount = 8;
4562 info->bmiHeader.biCompression = BI_RLE8;
4563 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4565 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4566 ok( ret == 8, "got %d\n", ret );
4567 ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4568 memset( dib_bits, 0xaa, 64 * 4 );
4570 info->bmiHeader.biHeight = 4;
4571 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4572 ok( ret == 4, "got %d\n", ret );
4573 ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4574 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4575 memset( dib_bits, 0xaa, 64 * 4 );
4577 info->bmiHeader.biHeight = 9;
4578 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4579 ok( ret == 9, "got %d\n", ret );
4580 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4581 ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4582 memset( dib_bits, 0xaa, 64 * 4 );
4584 DeleteObject( dib );
4585 ReleaseDC( NULL, hdc );
4586 HeapFree( GetProcessHeap(), 0, info );
4589 static void test_SetDIBitsToDevice(void)
4591 char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
4592 LOGPALETTE *pal = (LOGPALETTE *)palbuf;
4593 PALETTEENTRY *palent = pal->palPalEntry;
4597 HDC hdc = CreateCompatibleDC( 0 );
4598 DWORD data[128], inverted_data[128];
4602 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4604 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4605 info->bmiHeader.biWidth = 8;
4606 info->bmiHeader.biHeight = 8;
4607 info->bmiHeader.biPlanes = 1;
4608 info->bmiHeader.biBitCount = 32;
4609 info->bmiHeader.biCompression = BI_RGB;
4611 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4612 memset( dib_bits, 0xaa, 64 * 4 );
4613 SelectObject( hdc, dib );
4615 for (i = 0; i < 128; i++)
4618 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4623 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4624 ok( ret == 8, "got %d\n", ret );
4625 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4626 memset( dib_bits, 0xaa, 64 * 4 );
4628 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4629 ok( ret == 5, "got %d\n", ret );
4630 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4631 for (i = 8; i < 48; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4632 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4633 memset( dib_bits, 0xaa, 64 * 4 );
4635 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 3, 1, 5, data, info, DIB_RGB_COLORS );
4636 ok( ret == 5, "got %d\n", ret );
4637 for (i = 0; i < 24; i++) ok( dib_bits[i] == data[i + 16], "%d: got %08x\n", i, dib_bits[i] );
4638 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4639 memset( dib_bits, 0xaa, 64 * 4 );
4641 info->bmiHeader.biHeight = 16;
4642 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4643 ok( ret == 7, "got %d\n", ret );
4644 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4645 for (i = 8; i < 64; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4646 memset( dib_bits, 0xaa, 64 * 4 );
4648 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 8, 0, 6, 1, 12, data, info, DIB_RGB_COLORS );
4649 ok( ret == 12, "got %d\n", ret );
4650 for (i = 0; i < 40; i++) ok( dib_bits[i] == data[i + 56], "%d: got %08x\n", i, dib_bits[i] );
4651 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4652 memset( dib_bits, 0xaa, 64 * 4 );
4654 ret = SetDIBitsToDevice( hdc, 0, -4, 8, 8, 0, 3, 1, 12, data, info, DIB_RGB_COLORS );
4655 ok( ret == 10, "got %d\n", ret );
4656 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4657 for (i = 32; i < 64; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4658 memset( dib_bits, 0xaa, 64 * 4 );
4660 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, -3, 1, 12, data, info, DIB_RGB_COLORS );
4661 ok( ret == 4, "got %d\n", ret );
4662 for (i = 0; i < 32; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4663 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4664 memset( dib_bits, 0xaa, 64 * 4 );
4666 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 5, 0, -2, 1, 12, data, info, DIB_RGB_COLORS );
4667 ok( ret == 2, "got %d\n", ret );
4668 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4669 for (i = 32; i < 48; i++) ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4670 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4671 memset( dib_bits, 0xaa, 64 * 4 );
4673 info->bmiHeader.biHeight = 5;
4674 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 2, 2, data, info, DIB_RGB_COLORS );
4675 ok( ret == 2, "got %d\n", ret );
4676 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4677 for (i = 16; i < 32; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4678 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4679 memset( dib_bits, 0xaa, 64 * 4 );
4681 ret = SetDIBitsToDevice( hdc, 3, 3, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4682 ok( ret == 3, "got %d\n", ret );
4683 for (i = 0; i < 64; i++)
4684 if (i == 27 || i == 28 || i == 35 || i == 36)
4685 ok( dib_bits[i] == data[i - 18], "%d: got %08x\n", i, dib_bits[i] );
4687 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4688 memset( dib_bits, 0xaa, 64 * 4 );
4690 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4691 ok( ret == 5, "got %d\n", ret );
4692 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4693 memset( dib_bits, 0xaa, 64 * 4 );
4695 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4696 ok( ret == 0, "got %d\n", ret );
4697 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4698 memset( dib_bits, 0xaa, 64 * 4 );
4700 SetMapMode( hdc, MM_ANISOTROPIC );
4701 SetWindowExtEx( hdc, 3, 3, NULL );
4702 ret = SetDIBitsToDevice( hdc, 2, 2, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4703 ok( ret == 3, "got %d\n", ret );
4704 for (i = 0; i < 64; i++)
4705 if (i == 41 || i == 42 || i == 49 || i == 50)
4706 ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4708 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4709 memset( dib_bits, 0xaa, 64 * 4 );
4711 SetWindowExtEx( hdc, -1, -1, NULL );
4712 ret = SetDIBitsToDevice( hdc, 2, 2, 4, 4, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4713 ok( ret == 4, "got %d\n", ret );
4714 for (i = 0; i < 64; i++)
4715 if (i == 48 || i == 49 || i == 56 || i == 57)
4716 ok( dib_bits[i] == data[i - 37], "%d: got %08x\n", i, dib_bits[i] );
4718 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4719 memset( dib_bits, 0xaa, 64 * 4 );
4720 SetMapMode( hdc, MM_TEXT );
4724 pSetLayout( hdc, LAYOUT_RTL );
4725 ret = SetDIBitsToDevice( hdc, 1, 2, 3, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4726 ok( ret == 3, "got %d\n", ret );
4727 for (i = 0; i < 64; i++)
4728 if (i == 36 || i == 37 || i == 38 || i == 44 || i == 45 || i == 46)
4729 ok( dib_bits[i] == data[i - 27], "%d: got %08x\n", i, dib_bits[i] );
4731 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4732 memset( dib_bits, 0xaa, 64 * 4 );
4733 pSetLayout( hdc, LAYOUT_LTR );
4737 info->bmiHeader.biHeight = -8;
4738 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4739 ok( ret == 8, "got %d\n", ret );
4740 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4741 memset( dib_bits, 0xaa, 64 * 4 );
4743 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4744 ok( ret == 5, "got %d\n", ret );
4745 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4746 for (i = 8; i < 48; i++) ok( dib_bits[i] == inverted_data[i + 80], "%d: got %08x\n", i, dib_bits[i] );
4747 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4748 memset( dib_bits, 0xaa, 64 * 4 );
4750 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 4, 1, 5, data, info, DIB_RGB_COLORS );
4751 ok( ret == 5, "got %d\n", ret );
4752 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4753 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4754 memset( dib_bits, 0xaa, 64 * 4 );
4756 info->bmiHeader.biHeight = -16;
4757 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4758 ok( ret == 12, "got %d\n", ret );
4759 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4760 for (i = 8; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4761 memset( dib_bits, 0xaa, 64 * 4 );
4763 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, 7, 1, 12, data, info, DIB_RGB_COLORS );
4764 ok( ret == 12, "got %d\n", ret );
4765 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4766 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4767 memset( dib_bits, 0xaa, 64 * 4 );
4769 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 4, 12, data, info, DIB_RGB_COLORS );
4770 ok( ret == 12, "got %d\n", ret );
4771 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4772 for (i = 32; i < 64; i++) ok( dib_bits[i] == inverted_data[i], "%d: got %08x\n", i, dib_bits[i] );
4773 memset( dib_bits, 0xaa, 64 * 4 );
4775 ret = SetDIBitsToDevice( hdc, 0, -3, 8, 8, 0, 2, 4, 12, data, info, DIB_RGB_COLORS );
4776 ok( ret == 12, "got %d\n", ret );
4777 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4778 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4779 memset( dib_bits, 0xaa, 64 * 4 );
4781 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, -2, 4, 12, data, info, DIB_RGB_COLORS );
4782 ok( ret == 12, "got %d\n", ret );
4783 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4784 for (i = 24; i < 40; i++) ok( dib_bits[i] == inverted_data[i + 8], "%d: got %08x\n", i, dib_bits[i] );
4785 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4786 memset( dib_bits, 0xaa, 64 * 4 );
4788 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 5, 12, data, info, DIB_RGB_COLORS );
4789 ok( ret == 12, "got %d\n", ret );
4790 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4791 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4792 memset( dib_bits, 0xaa, 64 * 4 );
4794 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4795 ok( ret == 12, "got %d\n", ret );
4796 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4797 memset( dib_bits, 0xaa, 64 * 4 );
4799 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -2, -4, 0, 12, data, info, DIB_RGB_COLORS );
4800 ok( ret == 12, "got %d\n", ret );
4801 for (i = 0; i < 64; i++)
4802 if (i == 31 || i == 39 || i == 47 || i == 55 || i == 63)
4803 ok( dib_bits[i] == inverted_data[i + 1], "%d: got %08x\n", i, dib_bits[i] );
4805 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4806 memset( dib_bits, 0xaa, 64 * 4 );
4808 info->bmiHeader.biHeight = -5;
4809 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4810 ok( ret == 2, "got %d\n", ret );
4811 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4812 for (i = 8; i < 24; i++) ok( dib_bits[i] == inverted_data[i + 104], "%d: got %08x\n", i, dib_bits[i] );
4813 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4814 memset( dib_bits, 0xaa, 64 * 4 );
4816 ret = SetDIBitsToDevice( hdc, 5, 4, 2, 2, 6, 3, 1, 5, data, info, DIB_RGB_COLORS );
4817 ok( ret == 5, "got %d\n", ret );
4818 for (i = 0; i < 64; i++)
4819 if (i == 21 || i == 22 || i == 29 || i == 30)
4820 ok( dib_bits[i] == inverted_data[i + 89], "%d: got %08x\n", i, dib_bits[i] );
4822 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4823 memset( dib_bits, 0xaa, 64 * 4 );
4825 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4826 ok( ret == 5, "got %d\n", ret );
4827 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4828 memset( dib_bits, 0xaa, 64 * 4 );
4830 info->bmiHeader.biHeight = -8;
4832 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4833 DeleteObject( SelectObject( hdc, dib ));
4834 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4838 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4839 ok( ret == 8, "got %d\n", ret );
4840 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4841 memset( dib_bits, 0xaa, 64 * 4 );
4843 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4844 ok( ret == 5, "got %d\n", ret );
4845 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4846 for (i = 16; i < 56; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4847 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4848 memset( dib_bits, 0xaa, 64 * 4 );
4850 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 3, 0, 2, 1, 5, data, info, DIB_RGB_COLORS );
4851 ok( ret == 5, "got %d\n", ret );
4852 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4853 for (i = 24; i < 48; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4854 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4855 memset( dib_bits, 0xaa, 64 * 4 );
4857 info->bmiHeader.biHeight = -16;
4858 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4859 ok( ret == 12, "got %d\n", ret );
4860 for (i = 0; i < 56; i++) ok( dib_bits[i] == data[i + 40], "%d: got %08x\n", i, dib_bits[i] );
4861 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4862 memset( dib_bits, 0xaa, 64 * 4 );
4864 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -1, -8, 0, 12, data, info, DIB_RGB_COLORS );
4865 ok( ret == 12, "got %d\n", ret );
4866 for (i = 0; i < 64; i++)
4867 if (i == 6 || i == 7)
4868 ok( dib_bits[i] == data[i + 82], "%d: got %08x\n", i, dib_bits[i] );
4870 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4871 memset( dib_bits, 0xaa, 64 * 4 );
4873 info->bmiHeader.biHeight = -5;
4874 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4875 ok( ret == 2, "got %d\n", ret );
4876 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4877 for (i = 40; i < 56; i++) ok( dib_bits[i] == data[i - 40], "%d: got %08x\n", i, dib_bits[i] );
4878 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4879 memset( dib_bits, 0xaa, 64 * 4 );
4881 ret = SetDIBitsToDevice( hdc, 7, 2, 8, 8, 1, 0, 0, 5, data, info, DIB_RGB_COLORS );
4882 ok( ret == 5, "got %d\n", ret );
4883 for (i = 0; i < 64; i++)
4884 if (i == 47 || i == 55 || i == 63)
4885 ok( dib_bits[i] == data[i - 46], "%d: got %08x\n", i, dib_bits[i] );
4887 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4888 memset( dib_bits, 0xaa, 64 * 4 );
4890 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4891 ok( ret == 5, "got %d\n", ret );
4892 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4893 memset( dib_bits, 0xaa, 64 * 4 );
4897 info->bmiHeader.biHeight = 8;
4898 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4899 ok( ret == 8, "got %d\n", ret );
4900 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4901 memset( dib_bits, 0xaa, 64 * 4 );
4903 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4904 ok( ret == 5, "got %d\n", ret );
4905 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4906 for (i = 16; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4907 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4908 memset( dib_bits, 0xaa, 64 * 4 );
4910 info->bmiHeader.biHeight = 16;
4911 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4912 ok( ret == 7, "got %d\n", ret );
4913 for (i = 0; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4914 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4915 memset( dib_bits, 0xaa, 64 * 4 );
4917 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, 0, -4, 1, 12, data, info, DIB_RGB_COLORS );
4918 ok( ret == 3, "got %d\n", ret );
4919 for (i = 0; i < 64; i++)
4920 if ((i >= 36 && i <= 39) || (i >= 44 && i <= 47) || (i >= 52 && i <= 55))
4921 ok( dib_bits[i] == inverted_data[i + 68], "%d: got %08x\n", i, dib_bits[i] );
4923 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4924 memset( dib_bits, 0xaa, 64 * 4 );
4926 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, -30, -30, 1, 12, data, info, DIB_RGB_COLORS );
4927 ok( ret == 0, "got %d\n", ret );
4928 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4929 memset( dib_bits, 0xaa, 64 * 4 );
4931 ret = SetDIBitsToDevice( hdc, 5, -5, 8, 16, -2, -4, 4, 12, data, info, DIB_RGB_COLORS );
4932 ok( ret == 8, "got %d\n", ret );
4933 for (i = 0; i < 64; i++)
4934 if (i == 7 || i == 15 || i == 23)
4935 ok( dib_bits[i] == inverted_data[i + 97], "%d: got %08x\n", i, dib_bits[i] );
4937 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4938 memset( dib_bits, 0xaa, 64 * 4 );
4940 info->bmiHeader.biHeight = 5;
4941 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4942 ok( ret == 2, "got %d\n", ret );
4943 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4944 for (i = 40; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4945 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4946 memset( dib_bits, 0xaa, 64 * 4 );
4948 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4949 ok( ret == 5, "got %d\n", ret );
4950 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4951 memset( dib_bits, 0xaa, 64 * 4 );
4953 /* handling of partial color table */
4955 info->bmiHeader.biHeight = -8;
4956 info->bmiHeader.biBitCount = 8;
4957 info->bmiHeader.biClrUsed = 137;
4958 for (i = 0; i < 256; i++)
4960 info->bmiColors[i].rgbRed = 255 - i;
4961 info->bmiColors[i].rgbGreen = i * 2;
4962 info->bmiColors[i].rgbBlue = i;
4963 info->bmiColors[i].rgbReserved = 0;
4965 for (i = 0; i < 64; i++) ((BYTE *)data)[i] = i * 4 + 1;
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++)
4970 int idx = i * 4 + 1;
4971 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : (info->bmiColors[idx].rgbRed << 16 |
4972 info->bmiColors[idx].rgbGreen << 8 |
4973 info->bmiColors[idx].rgbBlue);
4974 ok( dib_bits[i] == expect, "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
4976 memset( dib_bits, 0xaa, 64 * 4 );
4978 /* handling of DIB_PAL_COLORS */
4980 pal->palVersion = 0x300;
4981 pal->palNumEntries = 137;
4982 info->bmiHeader.biClrUsed = 221;
4983 for (i = 0; i < 256; i++)
4985 palent[i].peRed = i * 2;
4986 palent[i].peGreen = 255 - i;
4987 palent[i].peBlue = i;
4989 palette = CreatePalette( pal );
4990 ok( palette != 0, "palette creation failed\n" );
4991 SelectPalette( hdc, palette, FALSE );
4992 for (i = 0; i < 256; i++) ((WORD *)info->bmiColors)[i] = 255 - i;
4993 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_PAL_COLORS );
4994 ok( ret == 8, "got %d\n", ret );
4995 for (i = 0; i < 64; i++)
4997 int idx = i * 4 + 1;
4998 int ent = (255 - idx) % pal->palNumEntries;
4999 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 :
5000 (palent[ent].peRed << 16 | palent[ent].peGreen << 8 | palent[ent].peBlue);
5001 ok( dib_bits[i] == expect || broken(dib_bits[i] == 0),
5002 "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
5004 memset( dib_bits, 0xaa, 64 * 4 );
5007 DeleteObject( dib );
5008 DeleteObject( palette );
5009 HeapFree( GetProcessHeap(), 0, info );
5012 static void test_SetDIBitsToDevice_RLE8(void)
5016 HDC hdc = CreateCompatibleDC( 0 );
5017 BYTE rle8_data[20] = { 0x04, 0x02, 0x03, 0xf0, 0x00, 0x00, /* 2, 2, 2, 2, f0, f0, f0, <eol> */
5018 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
5019 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
5020 0x00, 0x01 }; /* <eod> */
5023 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
5024 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5025 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5026 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
5027 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5028 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5029 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5030 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
5031 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5032 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5033 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5034 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5035 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
5036 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5037 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5038 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
5040 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
5042 info->bmiHeader.biSize = sizeof(info->bmiHeader);
5043 info->bmiHeader.biWidth = 8;
5044 info->bmiHeader.biHeight = 8;
5045 info->bmiHeader.biPlanes = 1;
5046 info->bmiHeader.biBitCount = 32;
5047 info->bmiHeader.biCompression = BI_RGB;
5049 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5050 memset( dib_bits, 0xaa, 64 * 4 );
5051 SelectObject( hdc, dib );
5053 info->bmiHeader.biBitCount = 8;
5054 info->bmiHeader.biCompression = BI_RLE8;
5055 info->bmiHeader.biSizeImage = sizeof(rle8_data);
5057 for (i = 0; i < 256; i++)
5059 info->bmiColors[i].rgbRed = i;
5060 info->bmiColors[i].rgbGreen = i;
5061 info->bmiColors[i].rgbBlue = i;
5062 info->bmiColors[i].rgbReserved = 0;
5065 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5066 ok( ret == 8, "got %d\n", ret );
5067 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5068 memset( dib_bits, 0xaa, 64 * 4 );
5070 /* startscan and lines are ignored, unless lines == 0 */
5071 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 8, rle8_data, info, DIB_RGB_COLORS );
5072 ok( ret == 8, "got %d\n", ret );
5073 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5074 memset( dib_bits, 0xaa, 64 * 4 );
5076 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 1, rle8_data, info, DIB_RGB_COLORS );
5077 ok( ret == 8, "got %d\n", ret );
5078 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5079 memset( dib_bits, 0xaa, 64 * 4 );
5081 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 0, rle8_data, info, DIB_RGB_COLORS );
5082 ok( ret == 0, "got %d\n", ret );
5083 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5084 memset( dib_bits, 0xaa, 64 * 4 );
5086 info->bmiHeader.biWidth = 2;
5087 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5088 ok( ret == 8, "got %d\n", ret );
5089 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5090 memset( dib_bits, 0xaa, 64 * 4 );
5092 info->bmiHeader.biWidth = 8;
5093 info->bmiHeader.biHeight = 2;
5094 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5095 ok( ret == 2, "got %d\n", ret );
5096 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5097 memset( dib_bits, 0xaa, 64 * 4 );
5099 info->bmiHeader.biHeight = 9;
5100 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5101 ok( ret == 9, "got %d\n", ret );
5102 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5103 memset( dib_bits, 0xaa, 64 * 4 );
5105 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5106 ok( ret == 9, "got %d\n", ret );
5107 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5108 memset( dib_bits, 0xaa, 64 * 4 );
5110 info->bmiHeader.biHeight = 8;
5111 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 9, rle8_data, info, DIB_RGB_COLORS );
5112 ok( ret == 8, "got %d\n", ret );
5113 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5114 memset( dib_bits, 0xaa, 64 * 4 );
5116 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5117 ok( ret == 8, "got %d\n", ret );
5118 for (i = 0; i < 40; i++) ok( dib_bits[i] == bottom_up[i + 24], "%d: got %08x\n", i, dib_bits[i] );
5119 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5120 memset( dib_bits, 0xaa, 64 * 4 );
5122 ret = SetDIBitsToDevice( hdc, 0, 3, 4, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5123 ok( ret == 8, "got %d\n", ret );
5124 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5125 for (i = 8; i < 40; i++)
5126 if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5127 else ok( dib_bits[i] == bottom_up[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, 3, 3, 8, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5132 ok( ret == 8, "got %d\n", ret );
5133 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5134 for (i = 8; i < 40; i++)
5135 if ((i & 7) < 3) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5136 else ok( dib_bits[i] == bottom_up[i - 11], "%d: got %08x\n", i, dib_bits[i] );
5137 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5138 memset( dib_bits, 0xaa, 64 * 4 );
5140 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 4, 2, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5141 ok( ret == 8, "got %d\n", ret );
5142 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5143 for (i = 8; i < 40; i++)
5144 if ((i & 7) < 2) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5145 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5146 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5147 memset( dib_bits, 0xaa, 64 * 4 );
5149 info->bmiHeader.biWidth = 37;
5150 info->bmiHeader.biHeight = 37;
5151 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
5152 ok( ret == 37, "got %d\n", ret );
5153 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5154 for (i = 24; i < 64; i++)
5155 if (i == 52) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
5156 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5157 else ok( dib_bits[i] == bottom_up[i - 20], "%d: got %08x\n", i, dib_bits[i] );
5158 memset( dib_bits, 0xaa, 64 * 4 );
5160 /* top-down compressed dibs are invalid */
5161 info->bmiHeader.biWidth = 8;
5162 info->bmiHeader.biHeight = -8;
5163 SetLastError( 0xdeadbeef );
5164 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5165 ok( ret == 0, "got %d\n", ret );
5166 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
5170 info->bmiHeader.biHeight = -8;
5171 info->bmiHeader.biBitCount = 32;
5172 info->bmiHeader.biCompression = BI_RGB;
5173 info->bmiHeader.biSizeImage = 0;
5175 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5176 memset( dib_bits, 0xaa, 16 * 16 * 4 );
5177 DeleteObject( SelectObject( hdc, dib ));
5179 info->bmiHeader.biHeight = 8;
5180 info->bmiHeader.biBitCount = 8;
5181 info->bmiHeader.biCompression = BI_RLE8;
5182 info->bmiHeader.biSizeImage = sizeof(rle8_data);
5184 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5185 ok( ret == 8, "got %d\n", ret );
5186 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5187 memset( dib_bits, 0xaa, 64 * 4 );
5189 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5190 ok( ret == 8, "got %d\n", ret );
5191 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5192 memset( dib_bits, 0xaa, 64 * 4 );
5194 info->bmiHeader.biHeight = 4;
5195 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5196 ok( ret == 4, "got %d\n", ret );
5197 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5198 memset( dib_bits, 0xaa, 64 * 4 );
5200 info->bmiHeader.biHeight = 9;
5201 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5202 ok( ret == 9, "got %d\n", ret );
5203 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5204 memset( dib_bits, 0xaa, 64 * 4 );
5206 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5207 ok( ret == 9, "got %d\n", ret );
5208 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5209 memset( dib_bits, 0xaa, 64 * 4 );
5211 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 6, 2, 2, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5212 ok( ret == 9, "got %d\n", ret );
5213 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5214 for (i = 24; i < 64; i++) ok( dib_bits[i] == top_down[i - 24], "%d: got %08x\n", i, dib_bits[i] );
5215 memset( dib_bits, 0xaa, 64 * 4 );
5217 info->bmiHeader.biWidth = 37;
5218 info->bmiHeader.biHeight = 37;
5219 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
5220 ok( ret == 37, "got %d\n", ret );
5221 for (i = 0; i < 40; i++)
5222 if (i == 12) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
5223 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5224 else ok( dib_bits[i] == top_down[i + 28], "%d: got %08x\n", i, dib_bits[i] );
5225 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5226 memset( dib_bits, 0xaa, 64 * 4 );
5229 DeleteObject( dib );
5230 HeapFree( GetProcessHeap(), 0, info );
5237 hdll = GetModuleHandle("gdi32.dll");
5238 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
5239 pGdiGradientFill = (void*)GetProcAddress(hdll, "GdiGradientFill");
5240 pSetLayout = (void*)GetProcAddress(hdll, "SetLayout");
5242 test_createdibitmap();
5245 test_mono_dibsection();
5248 test_GetDIBits_selected_DIB(1);
5249 test_GetDIBits_selected_DIB(4);
5250 test_GetDIBits_selected_DIB(8);
5251 test_GetDIBits_selected_DDB(TRUE);
5252 test_GetDIBits_selected_DDB(FALSE);
5254 test_GetDIBits_BI_BITFIELDS();
5255 test_select_object();
5256 test_CreateBitmap();
5259 test_StretchDIBits();
5260 test_GdiAlphaBlend();
5261 test_GdiGradientFill();
5262 test_32bit_bitmap_blt();
5263 test_bitmapinfoheadersize();
5266 test_GetDIBits_top_down(16);
5267 test_GetDIBits_top_down(24);
5268 test_GetDIBits_top_down(32);
5269 test_GetSetDIBits_rtl();
5270 test_GetDIBits_scanlines();
5272 test_SetDIBits_RLE4();
5273 test_SetDIBits_RLE8();
5274 test_SetDIBitsToDevice();
5275 test_SetDIBitsToDevice_RLE8();