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" );
1158 /* some functions accept DIB_PAL_COLORS+1, but not beyond */
1160 bi->bmiHeader.biWidth = 2;
1161 bi->bmiHeader.biHeight = 2;
1162 bi->bmiHeader.biBitCount = 1;
1163 bi->bmiHeader.biCompression = BI_RGB;
1164 hdib = CreateDIBSection(hdc, bi, DIB_PAL_COLORS+1, &bits, NULL, 0);
1165 ok( hdib == NULL, "CreateDIBSection succeeded with DIB_PAL_COLORS+1\n" );
1166 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_PAL_COLORS+1 );
1167 ok( hdib != NULL, "CreateDIBitmap failed with DIB_PAL_COLORS+1\n" );
1168 DeleteObject( hdib );
1169 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_PAL_COLORS+1);
1170 ok( !ret, "SetDIBits succeeded with DIB_PAL_COLORS+1\n" );
1171 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_PAL_COLORS+1 );
1172 ok( ret, "SetDIBitsToDevice failed with DIB_PAL_COLORS+1\n" );
1173 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_PAL_COLORS+1, SRCCOPY );
1174 ok( ret, "StretchDIBits failed with DIB_PAL_COLORS+1\n" );
1175 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_PAL_COLORS+1);
1176 ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+1\n" );
1177 bi->bmiHeader.biWidth = 2;
1178 bi->bmiHeader.biHeight = 2;
1179 bi->bmiHeader.biBitCount = 1;
1180 bi->bmiHeader.biCompression = BI_RGB;
1181 ret = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS+1);
1182 ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+1\n" );
1184 bi->bmiHeader.biWidth = 2;
1185 bi->bmiHeader.biHeight = 2;
1186 bi->bmiHeader.biBitCount = 1;
1187 bi->bmiHeader.biCompression = BI_RGB;
1188 hdib = CreateDIBSection(hdc, bi, DIB_PAL_COLORS+2, &bits, NULL, 0);
1189 ok( hdib == NULL, "CreateDIBSection succeeded with DIB_PAL_COLORS+2\n" );
1190 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_PAL_COLORS+2 );
1191 ok( hdib == NULL, "CreateDIBitmap succeeded with DIB_PAL_COLORS+2\n" );
1192 DeleteObject( hdib );
1193 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_PAL_COLORS+2);
1194 ok( !ret, "SetDIBits succeeded with DIB_PAL_COLORS+2\n" );
1195 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_PAL_COLORS+2 );
1196 ok( !ret, "SetDIBitsToDevice succeeded with DIB_PAL_COLORS+2\n" );
1197 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_PAL_COLORS+2, SRCCOPY );
1198 ok( !ret, "StretchDIBits succeeded with DIB_PAL_COLORS+2\n" );
1199 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_PAL_COLORS+2);
1200 ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+2\n" );
1201 bi->bmiHeader.biWidth = 2;
1202 bi->bmiHeader.biHeight = 2;
1203 bi->bmiHeader.biBitCount = 1;
1204 bi->bmiHeader.biCompression = BI_RGB;
1205 ret = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS+2);
1206 ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+2\n" );
1209 DeleteObject( hbmp );
1210 ReleaseDC( 0, hdc );
1211 HeapFree( GetProcessHeap(), 0, bi );
1214 static void test_mono_dibsection(void)
1217 HBITMAP old_bm, mono_ds;
1218 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
1219 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
1220 RGBQUAD *colors = pbmi->bmiColors;
1227 memdc = CreateCompatibleDC(hdc);
1229 memset(pbmi, 0, sizeof(bmibuf));
1230 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
1231 pbmi->bmiHeader.biHeight = 10;
1232 pbmi->bmiHeader.biWidth = 10;
1233 pbmi->bmiHeader.biBitCount = 1;
1234 pbmi->bmiHeader.biPlanes = 1;
1235 pbmi->bmiHeader.biCompression = BI_RGB;
1236 colors[0].rgbRed = 0xff;
1237 colors[0].rgbGreen = 0xff;
1238 colors[0].rgbBlue = 0xff;
1239 colors[1].rgbRed = 0x0;
1240 colors[1].rgbGreen = 0x0;
1241 colors[1].rgbBlue = 0x0;
1244 * First dib section is 'inverted' ie color[0] is white, color[1] is black
1247 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1248 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1249 old_bm = SelectObject(memdc, mono_ds);
1251 /* black border, white interior */
1252 Rectangle(memdc, 0, 0, 10, 10);
1253 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1254 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1256 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1258 memset(bits, 0, sizeof(bits));
1261 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1262 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1264 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1266 colors[0].rgbRed = 0x0;
1267 colors[0].rgbGreen = 0x0;
1268 colors[0].rgbBlue = 0x0;
1269 colors[1].rgbRed = 0xff;
1270 colors[1].rgbGreen = 0xff;
1271 colors[1].rgbBlue = 0xff;
1273 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1274 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1276 SelectObject(memdc, old_bm);
1277 DeleteObject(mono_ds);
1280 * Next dib section is 'normal' ie color[0] is black, color[1] is white
1283 colors[0].rgbRed = 0x0;
1284 colors[0].rgbGreen = 0x0;
1285 colors[0].rgbBlue = 0x0;
1286 colors[1].rgbRed = 0xff;
1287 colors[1].rgbGreen = 0xff;
1288 colors[1].rgbBlue = 0xff;
1290 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1291 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1292 old_bm = SelectObject(memdc, mono_ds);
1294 /* black border, white interior */
1295 Rectangle(memdc, 0, 0, 10, 10);
1296 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
1297 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
1299 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
1301 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1302 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1304 /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
1306 colors[0].rgbRed = 0xff;
1307 colors[0].rgbGreen = 0xff;
1308 colors[0].rgbBlue = 0xff;
1309 colors[1].rgbRed = 0x0;
1310 colors[1].rgbGreen = 0x0;
1311 colors[1].rgbBlue = 0x0;
1313 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1314 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1317 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
1320 colors[0].rgbRed = 0xff;
1321 colors[0].rgbGreen = 0xff;
1322 colors[0].rgbBlue = 0xff;
1323 colors[1].rgbRed = 0x0;
1324 colors[1].rgbGreen = 0x0;
1325 colors[1].rgbBlue = 0x0;
1326 num = SetDIBColorTable(memdc, 0, 2, colors);
1327 ok(num == 2, "num = %d\n", num);
1329 /* black border, white interior */
1330 Rectangle(memdc, 0, 0, 10, 10);
1331 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1332 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1334 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1336 memset(bits, 0, sizeof(bits));
1339 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1340 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1342 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1344 colors[0].rgbRed = 0x0;
1345 colors[0].rgbGreen = 0x0;
1346 colors[0].rgbBlue = 0x0;
1347 colors[1].rgbRed = 0xff;
1348 colors[1].rgbGreen = 0xff;
1349 colors[1].rgbBlue = 0xff;
1351 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1352 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1354 SelectObject(memdc, old_bm);
1355 DeleteObject(mono_ds);
1358 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
1361 colors[0].rgbRed = 0xff;
1362 colors[0].rgbGreen = 0x0;
1363 colors[0].rgbBlue = 0x0;
1364 colors[1].rgbRed = 0xfe;
1365 colors[1].rgbGreen = 0x0;
1366 colors[1].rgbBlue = 0x0;
1368 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1369 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1370 old_bm = SelectObject(memdc, mono_ds);
1372 /* black border, white interior */
1373 Rectangle(memdc, 0, 0, 10, 10);
1374 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1375 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1377 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1379 colors[0].rgbRed = 0x0;
1380 colors[0].rgbGreen = 0x0;
1381 colors[0].rgbBlue = 0x0;
1382 colors[1].rgbRed = 0xff;
1383 colors[1].rgbGreen = 0xff;
1384 colors[1].rgbBlue = 0xff;
1386 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1387 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1389 /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
1391 colors[0].rgbRed = 0xff;
1392 colors[0].rgbGreen = 0xff;
1393 colors[0].rgbBlue = 0xff;
1394 colors[1].rgbRed = 0x0;
1395 colors[1].rgbGreen = 0x0;
1396 colors[1].rgbBlue = 0x0;
1398 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1399 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1401 SelectObject(memdc, old_bm);
1402 DeleteObject(mono_ds);
1408 static void test_bitmap(void)
1410 char buf[256], buf_cmp[256];
1411 HBITMAP hbmp, hbmp_old;
1417 hdc = CreateCompatibleDC(0);
1420 SetLastError(0xdeadbeef);
1421 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1424 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1425 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1426 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1431 SetLastError(0xdeadbeef);
1432 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1435 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1436 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1437 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1442 SetLastError(0xdeadbeef);
1443 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1444 ok(!hbmp, "CreateBitmap should fail\n");
1446 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1447 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1451 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1452 assert(hbmp != NULL);
1454 ret = GetObject(hbmp, sizeof(bm), &bm);
1455 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1457 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1458 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1459 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1460 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1461 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1462 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1463 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1465 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1466 assert(sizeof(buf) == sizeof(buf_cmp));
1468 ret = GetBitmapBits(hbmp, 0, NULL);
1469 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1471 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1472 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1474 memset(buf, 0xAA, sizeof(buf));
1475 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1476 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1477 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1479 hbmp_old = SelectObject(hdc, hbmp);
1481 ret = GetObject(hbmp, sizeof(bm), &bm);
1482 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1484 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1485 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1486 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1487 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1488 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1489 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1490 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1492 memset(buf, 0xAA, sizeof(buf));
1493 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1494 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1495 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1497 hbmp_old = SelectObject(hdc, hbmp_old);
1498 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1500 /* test various buffer sizes for GetObject */
1501 ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
1502 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1504 ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1505 ok(ret == 0, "%d != 0\n", ret);
1507 ret = GetObject(hbmp, 0, &bm);
1508 ok(ret == 0, "%d != 0\n", ret);
1510 ret = GetObject(hbmp, 1, &bm);
1511 ok(ret == 0, "%d != 0\n", ret);
1517 static void test_bmBits(void)
1523 memset(bits, 0, sizeof(bits));
1524 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1525 ok(hbmp != NULL, "CreateBitmap failed\n");
1527 memset(&bmp, 0xFF, sizeof(bmp));
1528 ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1529 "GetObject failed or returned a wrong structure size\n");
1530 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1535 static void test_GetDIBits_selected_DIB(UINT bpp)
1542 UINT dib_size, dib32_size;
1549 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1550 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1552 /* Create a DIB section with a color table */
1554 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1555 info->bmiHeader.biWidth = 32;
1556 info->bmiHeader.biHeight = 32;
1557 info->bmiHeader.biPlanes = 1;
1558 info->bmiHeader.biBitCount = bpp;
1559 info->bmiHeader.biCompression = BI_RGB;
1560 info->bmiHeader.biXPelsPerMeter = 0;
1561 info->bmiHeader.biYPelsPerMeter = 0;
1562 info->bmiHeader.biClrUsed = 0;
1563 info->bmiHeader.biClrImportant = 0;
1565 for (i=0; i < (1u << bpp); i++)
1567 BYTE c = i * (1 << (8 - bpp));
1568 info->bmiColors[i].rgbRed = c;
1569 info->bmiColors[i].rgbGreen = c;
1570 info->bmiColors[i].rgbBlue = c;
1571 info->bmiColors[i].rgbReserved = 0;
1574 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1575 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1576 dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1578 /* Set the bits of the DIB section */
1579 for (i=0; i < dib_size; i++)
1581 ((BYTE *)bits)[i] = i % 256;
1584 /* Select the DIB into a DC */
1585 dib_dc = CreateCompatibleDC(NULL);
1586 old_bmp = SelectObject(dib_dc, dib);
1587 dc = CreateCompatibleDC(NULL);
1588 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
1590 /* Copy the DIB attributes but not the color table */
1591 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1593 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1594 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1596 /* Compare the color table and the bits */
1597 for (i=0; i < (1u << bpp); i++)
1598 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1599 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1600 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1601 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1602 "color table entry %d differs (bpp %d)\n", i, bpp );
1604 ok( !memcmp( bits, bits2, dib_size ), "bit mismatch (bpp %d)\n", bpp );
1606 /* Test various combinations of lines = 0 and bits2 = NULL */
1607 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1608 res = GetDIBits( dc, dib, 0, 0, bits2, info2, DIB_RGB_COLORS );
1609 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1610 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1611 "color table mismatch (bpp %d)\n", bpp );
1613 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1614 res = GetDIBits( dc, dib, 0, 0, NULL, info2, DIB_RGB_COLORS );
1615 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1616 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1617 "color table mismatch (bpp %d)\n", bpp );
1619 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1620 res = GetDIBits( dc, dib, 0, info->bmiHeader.biHeight, NULL, info2, DIB_RGB_COLORS );
1621 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1622 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1623 "color table mismatch (bpp %d)\n", bpp );
1625 /* Map into a 32bit-DIB */
1626 info2->bmiHeader.biBitCount = 32;
1627 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1628 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1630 /* Check if last pixel was set */
1631 pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
1632 ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
1634 HeapFree(GetProcessHeap(), 0, bits2);
1637 SelectObject(dib_dc, old_bmp);
1640 HeapFree(GetProcessHeap(), 0, info2);
1641 HeapFree(GetProcessHeap(), 0, info);
1644 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1658 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1659 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1661 width = height = 16;
1663 /* Create a DDB (device-dependent bitmap) */
1667 ddb = CreateBitmap(width, height, 1, 1, NULL);
1671 HDC screen_dc = GetDC(NULL);
1672 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1673 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1674 ReleaseDC(NULL, screen_dc);
1677 /* Set the pixels */
1678 ddb_dc = CreateCompatibleDC(NULL);
1679 old_bmp = SelectObject(ddb_dc, ddb);
1680 for (i = 0; i < width; i++)
1682 for (j=0; j < height; j++)
1684 BYTE c = (i * width + j) % 256;
1685 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1688 SelectObject(ddb_dc, old_bmp);
1690 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1691 info->bmiHeader.biWidth = width;
1692 info->bmiHeader.biHeight = height;
1693 info->bmiHeader.biPlanes = 1;
1694 info->bmiHeader.biBitCount = bpp;
1695 info->bmiHeader.biCompression = BI_RGB;
1697 dc = CreateCompatibleDC(NULL);
1699 /* Fill in biSizeImage */
1700 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1701 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1703 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1704 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1707 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1708 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1710 /* Copy the DIB attributes but not the color table */
1711 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1713 /* Select the DDB into another DC */
1714 old_bmp = SelectObject(ddb_dc, ddb);
1717 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1718 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1720 /* Compare the color table and the bits */
1723 for (i=0; i < (1u << bpp); i++)
1724 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1725 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1726 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1727 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1728 "color table entry %d differs (bpp %d)\n", i, bpp );
1731 ok( !memcmp( bits, bits2, info->bmiHeader.biSizeImage ), "bit mismatch (bpp %d)\n", bpp );
1733 /* Test the palette */
1734 if (info2->bmiHeader.biBitCount <= 8)
1736 WORD *colors = (WORD*)info2->bmiColors;
1738 /* Get the palette indices */
1739 res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1740 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1742 for (i = 0; i < (1 << info->bmiHeader.biBitCount); i++)
1743 ok( colors[i] == i, "%d: got %d (bpp %d)\n", i, colors[i], bpp );
1746 HeapFree(GetProcessHeap(), 0, bits2);
1747 HeapFree(GetProcessHeap(), 0, bits);
1750 SelectObject(ddb_dc, old_bmp);
1753 HeapFree(GetProcessHeap(), 0, info2);
1754 HeapFree(GetProcessHeap(), 0, info);
1757 static void test_GetDIBits(void)
1759 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1760 static const BYTE bmp_bits_1[16 * 2] =
1762 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1763 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1764 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1765 0xff,0xff, 0,0, 0xff,0xff, 0,0
1767 /* 4-bytes aligned 1-bit DIB data: 16x16 */
1768 static const BYTE dib_bits_1[16 * 4] =
1770 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1771 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1772 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1773 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1775 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1776 static const BYTE bmp_bits_24[16 * 16*3] =
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,
1796 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1797 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1798 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1799 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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1801 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1802 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1803 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1804 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1805 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1806 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1807 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1808 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1809 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1811 /* 4-bytes aligned 24-bit DIB data: 16x16 */
1812 static const BYTE dib_bits_24[16 * 16*3] =
1814 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1815 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1816 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1817 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1818 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1819 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1820 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1821 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1822 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1823 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1824 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1825 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1826 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1827 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1828 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1829 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1830 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1831 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1832 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1833 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1834 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1835 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1836 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1837 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1838 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1839 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1840 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1841 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1842 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1843 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1844 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1845 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1850 int i, bytes, lines;
1852 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1853 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1854 RGBQUAD *colors = bi->bmiColors;
1855 PALETTEENTRY pal_ents[20];
1859 /* 1-bit source bitmap data */
1860 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1861 ok(hbmp != 0, "CreateBitmap failed\n");
1863 memset(&bm, 0xAA, sizeof(bm));
1864 bytes = GetObject(hbmp, sizeof(bm), &bm);
1865 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1866 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1867 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1868 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1869 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1870 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1871 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1872 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1874 bytes = GetBitmapBits(hbmp, 0, NULL);
1875 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1876 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1877 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1878 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1880 /* retrieve 1-bit DIB data */
1881 memset(bi, 0, sizeof(*bi));
1882 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1883 bi->bmiHeader.biWidth = bm.bmWidth;
1884 bi->bmiHeader.biHeight = bm.bmHeight;
1885 bi->bmiHeader.biPlanes = 1;
1886 bi->bmiHeader.biBitCount = 1;
1887 bi->bmiHeader.biCompression = BI_RGB;
1888 bi->bmiHeader.biClrUsed = 37;
1889 bi->bmiHeader.biSizeImage = 0;
1890 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1891 SetLastError(0xdeadbeef);
1892 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1893 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1894 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1895 broken(GetLastError() == 0xdeadbeef), /* winnt */
1896 "wrong error %u\n", GetLastError());
1897 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1898 ok(bi->bmiHeader.biClrUsed == 37 || broken(bi->bmiHeader.biClrUsed == 0),
1899 "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
1901 memset(buf, 0xAA, sizeof(buf));
1902 SetLastError(0xdeadbeef);
1903 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1904 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1905 lines, bm.bmHeight, GetLastError());
1906 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1907 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
1909 /* the color table consists of black and white */
1910 ok(colors[0].rgbRed == 0 && colors[0].rgbGreen == 0 &&
1911 colors[0].rgbBlue == 0 && colors[0].rgbReserved == 0,
1912 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1913 colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue, colors[0].rgbReserved);
1914 ok(colors[1].rgbRed == 0xff && colors[1].rgbGreen == 0xff &&
1915 colors[1].rgbBlue == 0xff && colors[1].rgbReserved == 0,
1916 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1917 colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue, colors[1].rgbReserved);
1918 for (i = 2; i < 256; i++)
1920 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
1921 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
1922 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1923 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
1926 /* returned bits are DWORD aligned and upside down */
1927 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1929 /* Test the palette indices */
1930 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1931 SetLastError(0xdeadbeef);
1932 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1933 ok(((WORD*)colors)[0] == 0, "Color 0 is %d\n", ((WORD*)colors)[0]);
1934 ok(((WORD*)colors)[1] == 1, "Color 1 is %d\n", ((WORD*)colors)[1]);
1935 for (i = 2; i < 256; i++)
1936 ok(((WORD*)colors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)colors)[1]);
1938 /* retrieve 24-bit DIB data */
1939 memset(bi, 0, sizeof(*bi));
1940 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1941 bi->bmiHeader.biWidth = bm.bmWidth;
1942 bi->bmiHeader.biHeight = bm.bmHeight;
1943 bi->bmiHeader.biPlanes = 1;
1944 bi->bmiHeader.biBitCount = 24;
1945 bi->bmiHeader.biCompression = BI_RGB;
1946 bi->bmiHeader.biClrUsed = 37;
1947 bi->bmiHeader.biSizeImage = 0;
1948 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1949 memset(buf, 0xAA, sizeof(buf));
1950 SetLastError(0xdeadbeef);
1951 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1952 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1953 lines, bm.bmHeight, GetLastError());
1954 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1955 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
1957 /* the color table doesn't exist for 24-bit images */
1958 for (i = 0; i < 256; i++)
1960 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
1961 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
1962 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1963 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
1966 /* returned bits are DWORD aligned and upside down */
1967 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1970 /* 24-bit source bitmap data */
1971 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1972 ok(hbmp != 0, "CreateBitmap failed\n");
1973 SetLastError(0xdeadbeef);
1974 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1975 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1976 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1977 lines, bm.bmHeight, GetLastError());
1979 memset(&bm, 0xAA, sizeof(bm));
1980 bytes = GetObject(hbmp, sizeof(bm), &bm);
1981 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1982 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1983 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1984 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1985 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1986 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1987 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1988 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1990 bytes = GetBitmapBits(hbmp, 0, NULL);
1991 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
1992 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1993 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1994 bm.bmWidthBytes * bm.bmHeight, bytes);
1996 /* retrieve 1-bit DIB data */
1997 memset(bi, 0, sizeof(*bi));
1998 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1999 bi->bmiHeader.biWidth = bm.bmWidth;
2000 bi->bmiHeader.biHeight = bm.bmHeight;
2001 bi->bmiHeader.biPlanes = 1;
2002 bi->bmiHeader.biBitCount = 1;
2003 bi->bmiHeader.biCompression = BI_RGB;
2004 bi->bmiHeader.biClrUsed = 37;
2005 bi->bmiHeader.biSizeImage = 0;
2006 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2007 memset(buf, 0xAA, sizeof(buf));
2008 SetLastError(0xdeadbeef);
2009 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2010 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2011 lines, bm.bmHeight, GetLastError());
2012 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
2013 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2015 /* the color table consists of black and white */
2016 ok(colors[0].rgbRed == 0 && colors[0].rgbGreen == 0 &&
2017 colors[0].rgbBlue == 0 && colors[0].rgbReserved == 0,
2018 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
2019 colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue, colors[0].rgbReserved);
2020 ok(colors[1].rgbRed == 0xff && colors[1].rgbGreen == 0xff &&
2021 colors[1].rgbBlue == 0xff && colors[1].rgbReserved == 0,
2022 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
2023 colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue, colors[1].rgbReserved);
2024 for (i = 2; i < 256; i++)
2026 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2027 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2028 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2029 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2032 /* returned bits are DWORD aligned and upside down */
2033 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
2035 /* Test the palette indices */
2036 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2037 SetLastError(0xdeadbeef);
2038 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
2039 ok(((WORD*)colors)[0] == 0, "Color 0 is %d\n", ((WORD*)colors)[0]);
2040 ok(((WORD*)colors)[1] == 1, "Color 1 is %d\n", ((WORD*)colors)[1]);
2041 for (i = 2; i < 256; i++)
2042 ok(((WORD*)colors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)colors)[i]);
2044 /* retrieve 4-bit DIB data */
2045 memset(bi, 0, sizeof(*bi));
2046 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2047 bi->bmiHeader.biWidth = bm.bmWidth;
2048 bi->bmiHeader.biHeight = bm.bmHeight;
2049 bi->bmiHeader.biPlanes = 1;
2050 bi->bmiHeader.biBitCount = 4;
2051 bi->bmiHeader.biCompression = BI_RGB;
2052 bi->bmiHeader.biClrUsed = 37;
2053 bi->bmiHeader.biSizeImage = 0;
2054 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2055 memset(buf, 0xAA, sizeof(buf));
2056 SetLastError(0xdeadbeef);
2057 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2058 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2059 lines, bm.bmHeight, GetLastError());
2060 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2062 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2064 for (i = 0; i < 16; i++)
2067 int entry = i < 8 ? i : i + 4;
2069 if(entry == 7) entry = 12;
2070 else if(entry == 12) entry = 7;
2072 expect.rgbRed = pal_ents[entry].peRed;
2073 expect.rgbGreen = pal_ents[entry].peGreen;
2074 expect.rgbBlue = pal_ents[entry].peBlue;
2075 expect.rgbReserved = 0;
2077 ok(!memcmp(colors + i, &expect, sizeof(expect)),
2078 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2079 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2080 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2083 /* retrieve 8-bit DIB data */
2084 memset(bi, 0, sizeof(*bi));
2085 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2086 bi->bmiHeader.biWidth = bm.bmWidth;
2087 bi->bmiHeader.biHeight = bm.bmHeight;
2088 bi->bmiHeader.biPlanes = 1;
2089 bi->bmiHeader.biBitCount = 8;
2090 bi->bmiHeader.biCompression = BI_RGB;
2091 bi->bmiHeader.biClrUsed = 37;
2092 bi->bmiHeader.biSizeImage = 0;
2093 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2094 memset(buf, 0xAA, sizeof(buf));
2095 SetLastError(0xdeadbeef);
2096 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2097 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2098 lines, bm.bmHeight, GetLastError());
2099 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2101 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2103 for (i = 0; i < 256; i++)
2107 if (i < 10 || i >= 246)
2109 int entry = i < 10 ? i : i - 236;
2110 expect.rgbRed = pal_ents[entry].peRed;
2111 expect.rgbGreen = pal_ents[entry].peGreen;
2112 expect.rgbBlue = pal_ents[entry].peBlue;
2116 expect.rgbRed = (i & 0x07) << 5;
2117 expect.rgbGreen = (i & 0x38) << 2;
2118 expect.rgbBlue = i & 0xc0;
2120 expect.rgbReserved = 0;
2122 ok(!memcmp(colors + i, &expect, sizeof(expect)),
2123 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2124 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2125 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2128 /* retrieve 24-bit DIB data */
2129 memset(bi, 0, sizeof(*bi));
2130 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2131 bi->bmiHeader.biWidth = bm.bmWidth;
2132 bi->bmiHeader.biHeight = bm.bmHeight;
2133 bi->bmiHeader.biPlanes = 1;
2134 bi->bmiHeader.biBitCount = 24;
2135 bi->bmiHeader.biCompression = BI_RGB;
2136 bi->bmiHeader.biClrUsed = 37;
2137 bi->bmiHeader.biSizeImage = 0;
2138 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2139 memset(buf, 0xAA, sizeof(buf));
2140 SetLastError(0xdeadbeef);
2141 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2142 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2143 lines, bm.bmHeight, GetLastError());
2144 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2145 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2147 /* the color table doesn't exist for 24-bit images */
2148 for (i = 0; i < 256; i++)
2150 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2151 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2152 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2153 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2156 /* returned bits are DWORD aligned and upside down */
2157 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2163 static void test_GetDIBits_BI_BITFIELDS(void)
2165 /* Try a screen resolution detection technique
2166 * from the September 1999 issue of Windows Developer's Journal
2167 * which seems to be in widespread use.
2168 * http://www.lesher.ws/highcolor.html
2169 * http://www.lesher.ws/vidfmt.c
2170 * It hinges on being able to retrieve the bitmaps
2171 * for the three primary colors in non-paletted 16 bit mode.
2173 char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
2175 LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
2176 DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
2182 memset(dibinfo, 0, sizeof(dibinfo_buf));
2183 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2186 ok(hdc != NULL, "GetDC failed?\n");
2187 hbm = CreateCompatibleBitmap(hdc, 1, 1);
2188 ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
2190 /* Call GetDIBits to fill in bmiHeader. */
2191 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2192 ok(ret == 1, "GetDIBits failed\n");
2193 if (dibinfo->bmiHeader.biBitCount > 8)
2195 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2196 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2197 "compression is %u (%d bpp)\n", dibinfo->bmiHeader.biCompression, dibinfo->bmiHeader.biBitCount );
2199 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2201 ok( !bitmasks[0], "red mask is set\n" );
2202 ok( !bitmasks[1], "green mask is set\n" );
2203 ok( !bitmasks[2], "blue mask is set\n" );
2205 /* test with NULL bits pointer and correct bpp */
2206 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2207 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2208 ok(ret == 1, "GetDIBits failed\n");
2210 ok( bitmasks[0] != 0, "red mask is not set\n" );
2211 ok( bitmasks[1] != 0, "green mask is not set\n" );
2212 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2213 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2215 /* test with valid bits pointer */
2216 memset(dibinfo, 0, sizeof(dibinfo_buf));
2217 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2218 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2219 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2220 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2221 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2222 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2224 ok( bitmasks[0] != 0, "red mask is not set\n" );
2225 ok( bitmasks[1] != 0, "green mask is not set\n" );
2226 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2227 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2229 /* now with bits and 0 lines */
2230 memset(dibinfo, 0, sizeof(dibinfo_buf));
2231 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2232 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2233 SetLastError(0xdeadbeef);
2234 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2235 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2237 ok( !bitmasks[0], "red mask is set\n" );
2238 ok( !bitmasks[1], "green mask is set\n" );
2239 ok( !bitmasks[2], "blue mask is set\n" );
2240 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2242 memset(bitmasks, 0, 3*sizeof(DWORD));
2243 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2244 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2245 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2247 ok( bitmasks[0] != 0, "red mask is not set\n" );
2248 ok( bitmasks[1] != 0, "green mask is not set\n" );
2249 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2250 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2253 else skip("bitmap in colortable mode, skipping BI_BITFIELDS tests\n");
2257 /* same thing now with a 32-bpp DIB section */
2259 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2260 dibinfo->bmiHeader.biWidth = 1;
2261 dibinfo->bmiHeader.biHeight = 1;
2262 dibinfo->bmiHeader.biPlanes = 1;
2263 dibinfo->bmiHeader.biBitCount = 32;
2264 dibinfo->bmiHeader.biCompression = BI_RGB;
2265 dibinfo->bmiHeader.biSizeImage = 0;
2266 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2267 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2268 dibinfo->bmiHeader.biClrUsed = 0;
2269 dibinfo->bmiHeader.biClrImportant = 0;
2270 bitmasks[0] = 0x0000ff;
2271 bitmasks[1] = 0x00ff00;
2272 bitmasks[2] = 0xff0000;
2273 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2274 ok( hbm != 0, "failed to create bitmap\n" );
2276 memset(dibinfo, 0, sizeof(dibinfo_buf));
2277 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2278 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2279 ok(ret == 1, "GetDIBits failed\n");
2280 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2282 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2283 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2284 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2285 ok( !bitmasks[0], "red mask is set\n" );
2286 ok( !bitmasks[1], "green mask is set\n" );
2287 ok( !bitmasks[2], "blue mask is set\n" );
2289 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2290 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2291 ok(ret == 1, "GetDIBits failed\n");
2292 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2293 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2294 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2295 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2296 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2298 ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
2299 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2300 ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
2302 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2306 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2307 dibinfo->bmiHeader.biWidth = 1;
2308 dibinfo->bmiHeader.biHeight = 1;
2309 dibinfo->bmiHeader.biPlanes = 1;
2310 dibinfo->bmiHeader.biBitCount = 32;
2311 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2312 dibinfo->bmiHeader.biSizeImage = 0;
2313 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2314 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2315 dibinfo->bmiHeader.biClrUsed = 0;
2316 dibinfo->bmiHeader.biClrImportant = 0;
2317 bitmasks[0] = 0x0000ff;
2318 bitmasks[1] = 0x00ff00;
2319 bitmasks[2] = 0xff0000;
2320 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2321 ok( hbm != 0, "failed to create bitmap\n" );
2325 memset(dibinfo, 0, sizeof(dibinfo_buf));
2326 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2327 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2328 ok(ret == 1, "GetDIBits failed\n");
2330 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
2331 "compression is %u\n", dibinfo->bmiHeader.biCompression );
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" );
2336 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2337 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2338 ok(ret == 1, "GetDIBits failed\n");
2339 ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
2340 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2341 ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
2342 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2347 /* 24-bpp DIB sections don't have bitfields */
2349 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2350 dibinfo->bmiHeader.biWidth = 1;
2351 dibinfo->bmiHeader.biHeight = 1;
2352 dibinfo->bmiHeader.biPlanes = 1;
2353 dibinfo->bmiHeader.biBitCount = 24;
2354 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2355 dibinfo->bmiHeader.biSizeImage = 0;
2356 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2357 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2358 dibinfo->bmiHeader.biClrUsed = 0;
2359 dibinfo->bmiHeader.biClrImportant = 0;
2360 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2361 ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
2362 dibinfo->bmiHeader.biCompression = BI_RGB;
2363 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2364 ok( hbm != 0, "failed to create bitmap\n" );
2366 memset(dibinfo, 0, sizeof(dibinfo_buf));
2367 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2368 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2369 ok(ret == 1, "GetDIBits failed\n");
2370 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2372 ok( dibinfo->bmiHeader.biCompression == BI_RGB,
2373 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2374 ok( !bitmasks[0], "red mask is set\n" );
2375 ok( !bitmasks[1], "green mask is set\n" );
2376 ok( !bitmasks[2], "blue mask is set\n" );
2378 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2379 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2380 ok(ret == 1, "GetDIBits failed\n");
2381 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2382 ok( !bitmasks[0], "red mask is set\n" );
2383 ok( !bitmasks[1], "green mask is set\n" );
2384 ok( !bitmasks[2], "blue mask is set\n" );
2385 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2388 ReleaseDC(NULL, hdc);
2391 static void test_select_object(void)
2394 HBITMAP hbm, hbm_old;
2396 DWORD depths[] = {8, 15, 16, 24, 32};
2401 ok(hdc != 0, "GetDC(0) failed\n");
2402 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2403 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2405 hbm_old = SelectObject(hdc, hbm);
2406 ok(hbm_old == 0, "SelectObject should fail\n");
2411 hdc = CreateCompatibleDC(0);
2412 ok(hdc != 0, "GetDC(0) failed\n");
2413 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2414 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2416 hbm_old = SelectObject(hdc, hbm);
2417 ok(hbm_old != 0, "SelectObject failed\n");
2418 hbm_old = SelectObject(hdc, hbm_old);
2419 ok(hbm_old == hbm, "SelectObject failed\n");
2423 /* test an 1-bpp bitmap */
2424 planes = GetDeviceCaps(hdc, PLANES);
2427 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
2428 ok(hbm != 0, "CreateBitmap failed\n");
2430 hbm_old = SelectObject(hdc, hbm);
2431 ok(hbm_old != 0, "SelectObject failed\n");
2432 hbm_old = SelectObject(hdc, hbm_old);
2433 ok(hbm_old == hbm, "SelectObject failed\n");
2437 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
2438 /* test a color bitmap to dc bpp matching */
2439 planes = GetDeviceCaps(hdc, PLANES);
2440 bpp = GetDeviceCaps(hdc, BITSPIXEL);
2442 hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
2443 ok(hbm != 0, "CreateBitmap failed\n");
2445 hbm_old = SelectObject(hdc, hbm);
2446 if(depths[i] == bpp ||
2447 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
2449 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
2450 SelectObject(hdc, hbm_old);
2452 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
2455 memset(&bm, 0xAA, sizeof(bm));
2456 bytes = GetObject(hbm, sizeof(bm), &bm);
2457 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2458 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2459 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
2460 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
2461 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2462 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
2463 if(depths[i] == 15) {
2464 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
2466 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2468 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2476 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
2481 ret = GetObjectType(hbmp);
2482 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
2484 ret = GetObject(hbmp, 0, 0);
2485 ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
2487 memset(&bm, 0xDA, sizeof(bm));
2488 SetLastError(0xdeadbeef);
2489 ret = GetObject(hbmp, sizeof(bm), &bm);
2490 if (!ret) /* XP, only for curObj2 */ return;
2491 ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
2492 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2493 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2494 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2495 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2496 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2497 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2498 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2501 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2503 static void test_CreateBitmap(void)
2506 HDC screenDC = GetDC(0);
2507 HDC hdc = CreateCompatibleDC(screenDC);
2510 /* all of these are the stock monochrome bitmap */
2511 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2512 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2513 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2514 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2515 HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2516 HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2518 /* these 2 are not the stock monochrome bitmap */
2519 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2520 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2522 HBITMAP old1 = SelectObject(hdc, bm2);
2523 HBITMAP old2 = SelectObject(screenDC, bm3);
2524 SelectObject(hdc, old1);
2525 SelectObject(screenDC, old2);
2527 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2528 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2529 bm, bm1, bm4, bm5, curObj1, old1);
2530 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2532 ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
2533 ok(old2 == 0, "old2 %p\n", old2);
2535 test_mono_1x1_bmp(bm);
2536 test_mono_1x1_bmp(bm1);
2537 test_mono_1x1_bmp(bm2);
2538 test_mono_1x1_bmp(bm3);
2539 test_mono_1x1_bmp(bm4);
2540 test_mono_1x1_bmp(bm5);
2541 test_mono_1x1_bmp(old1);
2542 test_mono_1x1_bmp(curObj1);
2552 ReleaseDC(0, screenDC);
2554 /* show that Windows ignores the provided bm.bmWidthBytes */
2558 bmp.bmWidthBytes = 28;
2560 bmp.bmBitsPixel = 1;
2562 bm = CreateBitmapIndirect(&bmp);
2563 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2564 test_mono_1x1_bmp(bm);
2567 /* Test how the bmBitsPixel field is treated */
2568 for(i = 1; i <= 33; i++) {
2572 bmp.bmWidthBytes = 28;
2574 bmp.bmBitsPixel = i;
2576 SetLastError(0xdeadbeef);
2577 bm = CreateBitmapIndirect(&bmp);
2579 DWORD error = GetLastError();
2580 ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
2581 ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2585 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2586 GetObject(bm, sizeof(bmp), &bmp);
2593 } else if(i <= 16) {
2595 } else if(i <= 24) {
2597 } else if(i <= 32) {
2600 ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2601 i, bmp.bmBitsPixel, expect);
2606 static void test_bitmapinfoheadersize(void)
2613 memset(&bmi, 0, sizeof(BITMAPINFO));
2614 bmi.bmiHeader.biHeight = 100;
2615 bmi.bmiHeader.biWidth = 512;
2616 bmi.bmiHeader.biBitCount = 24;
2617 bmi.bmiHeader.biPlanes = 1;
2619 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2621 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2622 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2624 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2626 SetLastError(0xdeadbeef);
2627 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2628 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2631 bmi.bmiHeader.biSize++;
2633 SetLastError(0xdeadbeef);
2634 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2636 broken(!hdib), /* Win98, WinMe */
2637 "CreateDIBSection error %d\n", GetLastError());
2640 bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2642 SetLastError(0xdeadbeef);
2643 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2645 broken(!hdib), /* Win98, WinMe */
2646 "CreateDIBSection error %d\n", GetLastError());
2649 bmi.bmiHeader.biSize++;
2651 SetLastError(0xdeadbeef);
2652 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2654 broken(!hdib), /* Win98, WinMe */
2655 "CreateDIBSection error %d\n", GetLastError());
2658 bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2660 SetLastError(0xdeadbeef);
2661 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2662 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2665 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2667 SetLastError(0xdeadbeef);
2668 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2670 broken(!hdib), /* Win95 */
2671 "CreateDIBSection error %d\n", GetLastError());
2674 memset(&bci, 0, sizeof(BITMAPCOREINFO));
2675 bci.bmciHeader.bcHeight = 100;
2676 bci.bmciHeader.bcWidth = 512;
2677 bci.bmciHeader.bcBitCount = 24;
2678 bci.bmciHeader.bcPlanes = 1;
2680 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2682 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2683 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2685 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2687 SetLastError(0xdeadbeef);
2688 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2689 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2692 bci.bmciHeader.bcSize++;
2694 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2695 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2697 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2699 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2700 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2705 static void test_get16dibits(void)
2707 BYTE bits[4 * (16 / sizeof(BYTE))];
2709 HDC screen_dc = GetDC(NULL);
2712 int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2714 int overwritten_bytes = 0;
2716 memset(bits, 0, sizeof(bits));
2717 hbmp = CreateBitmap(2, 2, 1, 16, bits);
2718 ok(hbmp != NULL, "CreateBitmap failed\n");
2720 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2723 memset(info, '!', info_len);
2724 memset(info, 0, sizeof(info->bmiHeader));
2726 info->bmiHeader.biSize = sizeof(info->bmiHeader);
2727 info->bmiHeader.biWidth = 2;
2728 info->bmiHeader.biHeight = 2;
2729 info->bmiHeader.biPlanes = 1;
2730 info->bmiHeader.biCompression = BI_RGB;
2732 ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2733 ok(ret != 0, "GetDIBits failed got %d\n", ret);
2735 for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2737 overwritten_bytes++;
2738 ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2740 HeapFree(GetProcessHeap(), 0, info);
2742 ReleaseDC(NULL, screen_dc);
2745 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2746 DWORD dwRop, UINT32 expected, int line)
2748 *srcBuffer = 0xFEDCBA98;
2749 *dstBuffer = 0x89ABCDEF;
2750 BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
2751 ok(expected == *dstBuffer,
2752 "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2753 dwRop, expected, *dstBuffer, line);
2756 static void test_BitBlt(void)
2758 HBITMAP bmpDst, bmpSrc;
2759 HBITMAP oldDst, oldSrc;
2760 HDC hdcScreen, hdcDst, hdcSrc;
2761 UINT32 *dstBuffer, *srcBuffer;
2762 HBRUSH hBrush, hOldBrush;
2763 BITMAPINFO bitmapInfo;
2765 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2766 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2767 bitmapInfo.bmiHeader.biWidth = 1;
2768 bitmapInfo.bmiHeader.biHeight = 1;
2769 bitmapInfo.bmiHeader.biPlanes = 1;
2770 bitmapInfo.bmiHeader.biBitCount = 32;
2771 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2772 bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2774 hdcScreen = CreateCompatibleDC(0);
2775 hdcDst = CreateCompatibleDC(hdcScreen);
2776 hdcSrc = CreateCompatibleDC(hdcDst);
2778 /* Setup the destination dib section */
2779 bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
2781 oldDst = SelectObject(hdcDst, bmpDst);
2783 hBrush = CreateSolidBrush(0x12345678);
2784 hOldBrush = SelectObject(hdcDst, hBrush);
2786 /* Setup the source dib section */
2787 bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
2789 oldSrc = SelectObject(hdcSrc, bmpSrc);
2791 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2792 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2793 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2794 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2795 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2796 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2797 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2798 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2799 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2800 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2801 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2802 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2803 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2804 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2805 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2808 SelectObject(hdcSrc, oldSrc);
2809 DeleteObject(bmpSrc);
2812 SelectObject(hdcDst, hOldBrush);
2813 DeleteObject(hBrush);
2814 SelectObject(hdcDst, oldDst);
2815 DeleteObject(bmpDst);
2819 DeleteDC(hdcScreen);
2822 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2823 DWORD dwRop, UINT32 expected, int line)
2825 *srcBuffer = 0xFEDCBA98;
2826 *dstBuffer = 0x89ABCDEF;
2827 StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
2828 ok(expected == *dstBuffer,
2829 "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2830 dwRop, expected, *dstBuffer, line);
2833 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, BITMAPINFO *dst_info, UINT32 *dstBuffer, UINT32 *srcBuffer,
2834 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2835 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2836 UINT32 *expected, int line)
2838 int dst_size = get_dib_image_size( dst_info );
2840 memset(dstBuffer, 0, dst_size);
2841 StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2842 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
2843 ok(memcmp(dstBuffer, expected, dst_size) == 0,
2844 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2845 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2846 expected[0], expected[1], expected[2], expected[3],
2847 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2848 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2849 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2852 static void test_StretchBlt(void)
2854 HBITMAP bmpDst, bmpSrc;
2855 HBITMAP oldDst, oldSrc;
2856 HDC hdcScreen, hdcDst, hdcSrc;
2857 UINT32 *dstBuffer, *srcBuffer;
2858 HBRUSH hBrush, hOldBrush;
2859 BITMAPINFO biDst, biSrc;
2860 UINT32 expected[256];
2863 memset(&biDst, 0, sizeof(BITMAPINFO));
2864 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2865 biDst.bmiHeader.biWidth = 16;
2866 biDst.bmiHeader.biHeight = -16;
2867 biDst.bmiHeader.biPlanes = 1;
2868 biDst.bmiHeader.biBitCount = 32;
2869 biDst.bmiHeader.biCompression = BI_RGB;
2870 memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
2872 hdcScreen = CreateCompatibleDC(0);
2873 hdcDst = CreateCompatibleDC(hdcScreen);
2874 hdcSrc = CreateCompatibleDC(hdcDst);
2877 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2879 oldDst = SelectObject(hdcDst, bmpDst);
2881 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2883 oldSrc = SelectObject(hdcSrc, bmpSrc);
2885 hBrush = CreateSolidBrush(0x012345678);
2886 hOldBrush = SelectObject(hdcDst, hBrush);
2888 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2889 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2890 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2891 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2892 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2893 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2894 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2895 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2896 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2897 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2898 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2899 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2900 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2901 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2902 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2904 SelectObject(hdcDst, hOldBrush);
2905 DeleteObject(hBrush);
2907 /* Top-down to top-down tests */
2908 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2909 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2911 memset( expected, 0, get_dib_image_size( &biDst ) );
2912 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2913 expected[16] = 0xFEDCBA98, expected[17] = 0x76543210;
2914 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2915 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2917 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2918 expected[16] = 0x00000000, expected[17] = 0x00000000;
2919 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2920 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
2922 expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
2923 expected[16] = 0xCAFED00D, expected[17] = 0xCAFED00D;
2924 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2925 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
2927 /* This is an example of the dst width (height) == 1 exception, explored below */
2928 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2929 expected[16] = 0x00000000, expected[17] = 0x00000000;
2930 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2931 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
2933 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2934 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
2935 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2936 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2938 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2939 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
2940 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2941 1, 1, -2, -2, 0, 0, 2, 2, expected, __LINE__);
2943 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2944 expected[16] = 0x00000000, expected[17] = 0x00000000;
2945 todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2946 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
2948 expected[0] = 0x00000000, expected[1] = 0x00000000;
2949 expected[16] = 0x00000000, expected[17] = 0xCAFED00D, expected[18] = 0xFEEDFACE;
2950 expected[32] = 0x00000000, expected[33] = 0xFEDCBA98, expected[34] = 0x76543210;
2952 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2953 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2955 /* when dst width is 1 merge src width - 1 pixels */
2956 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
2957 srcBuffer[0] = 0x0000ff00, srcBuffer[1] = 0x0000f0f0, srcBuffer[2] = 0x0000cccc, srcBuffer[3] = 0x0000aaaa;
2958 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2960 memset( expected, 0, get_dib_image_size( &biDst ) );
2961 expected[0] = srcBuffer[0];
2962 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2963 0, 0, 1, 1, 0, 0, 2, 1, expected, __LINE__);
2965 expected[0] = srcBuffer[0] & srcBuffer[1];
2966 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2967 0, 0, 1, 1, 0, 0, 3, 1, expected, __LINE__);
2969 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
2970 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2971 0, 0, 1, 1, 0, 0, 4, 1, expected, __LINE__);
2973 /* this doesn't happen if the src width is -ve */
2974 expected[0] = srcBuffer[1] & srcBuffer[2];
2975 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2976 0, 0, 1, 1, 2, 0, -2, 1, expected, __LINE__);
2978 /* when dst width > 1 behaviour reverts to what one would expect */
2979 expected[0] = srcBuffer[0] & srcBuffer[1], expected[1] = srcBuffer[2] & srcBuffer[3];
2980 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2981 0, 0, 2, 1, 0, 0, 4, 1, expected, __LINE__);
2983 /* similarly in the vertical direction */
2984 memset( expected, 0, get_dib_image_size( &biDst ) );
2985 expected[0] = srcBuffer[0];
2986 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2987 0, 0, 1, 1, 0, 0, 1, 2, expected, __LINE__);
2989 /* check that it's the dst size in device units that needs to be 1 */
2990 SetMapMode( hdcDst, MM_ISOTROPIC );
2991 SetWindowExtEx( hdcDst, 200, 200, NULL );
2992 SetViewportExtEx( hdcDst, 100, 100, NULL );
2994 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
2995 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2996 0, 0, 2, 2, 0, 0, 4, 1, expected, __LINE__);
2997 SetMapMode( hdcDst, MM_TEXT );
2999 SelectObject(hdcDst, oldDst);
3000 DeleteObject(bmpDst);
3002 /* Top-down to bottom-up tests */
3003 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
3004 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3005 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
3007 biDst.bmiHeader.biHeight = 16;
3008 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3010 oldDst = SelectObject(hdcDst, bmpDst);
3012 memset( expected, 0, get_dib_image_size( &biDst ) );
3014 expected[224] = 0xFEDCBA98, expected[225] = 0x76543210;
3015 expected[240] = 0xCAFED00D, expected[241] = 0xFEEDFACE;
3016 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3017 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3019 expected[224] = 0xFEEDFACE, expected[225] = 0xCAFED00D;
3020 expected[240] = 0x76543210, expected[241] = 0xFEDCBA98;
3021 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3022 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3024 SelectObject(hdcSrc, oldSrc);
3025 DeleteObject(bmpSrc);
3027 /* Bottom-up to bottom-up tests */
3028 biSrc.bmiHeader.biHeight = 16;
3029 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
3031 srcBuffer[224] = 0xCAFED00D, srcBuffer[225] = 0xFEEDFACE;
3032 srcBuffer[240] = 0xFEDCBA98, srcBuffer[241] = 0x76543210;
3033 oldSrc = SelectObject(hdcSrc, bmpSrc);
3035 memset( expected, 0, get_dib_image_size( &biDst ) );
3037 expected[224] = 0xCAFED00D, expected[225] = 0xFEEDFACE;
3038 expected[240] = 0xFEDCBA98, expected[241] = 0x76543210;
3039 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3040 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3042 expected[224] = 0x76543210, expected[225] = 0xFEDCBA98;
3043 expected[240] = 0xFEEDFACE, expected[241] = 0xCAFED00D;
3044 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3045 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3047 SelectObject(hdcDst, oldDst);
3048 DeleteObject(bmpDst);
3050 /* Bottom-up to top-down tests */
3051 biDst.bmiHeader.biHeight = -16;
3052 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3054 oldDst = SelectObject(hdcDst, bmpDst);
3056 memset( expected, 0, get_dib_image_size( &biDst ) );
3057 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3058 expected[16] = 0xCAFED00D, expected[17] = 0xFEEDFACE;
3059 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3060 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3062 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3063 expected[16] = 0x76543210, expected[17] = 0xFEDCBA98;
3064 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3065 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3067 SelectObject(hdcSrc, oldSrc);
3068 DeleteObject(bmpSrc);
3070 biSrc.bmiHeader.biHeight = -2;
3071 biSrc.bmiHeader.biBitCount = 24;
3072 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
3073 oldSrc = SelectObject(hdcSrc, bmpSrc);
3075 memset( expected, 0, get_dib_image_size( &biDst ) );
3076 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3077 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
3078 memcpy(dstBuffer, expected, 4 * sizeof(*dstBuffer));
3079 StretchBlt(hdcSrc, 0, 0, 4, 1, hdcDst, 0, 0, 4, 1, SRCCOPY );
3080 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
3081 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3082 expected[0] = 0x00EDFACE, expected[1] = 0x00FED00D;
3083 expected[2] = 0x00543210, expected[3] = 0x00DCBA98;
3084 ok(!memcmp(dstBuffer, expected, 16),
3085 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3086 expected[0], expected[1], expected[2], expected[3],
3087 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3089 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3090 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
3091 memcpy(srcBuffer, expected, 4 * sizeof(*dstBuffer));
3092 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
3093 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3094 expected[0] = 0x00EDFACE, expected[1] = 0x00D00DFE;
3095 expected[2] = 0x0010CAFE, expected[3] = 0x00765432;
3096 ok(!memcmp(dstBuffer, expected, 16),
3097 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3098 expected[0], expected[1], expected[2], expected[3],
3099 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3101 SelectObject(hdcSrc, oldSrc);
3102 DeleteObject(bmpSrc);
3104 biSrc.bmiHeader.biBitCount = 1;
3105 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
3106 oldSrc = SelectObject(hdcSrc, bmpSrc);
3107 *((DWORD *)colors + 0) = 0x123456;
3108 *((DWORD *)colors + 1) = 0x335577;
3109 SetDIBColorTable( hdcSrc, 0, 2, colors );
3110 srcBuffer[0] = 0x55555555;
3111 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
3112 SetTextColor( hdcDst, 0 );
3113 SetBkColor( hdcDst, 0 );
3114 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3115 expected[0] = expected[2] = 0x00123456;
3116 expected[1] = expected[3] = 0x00335577;
3117 ok(!memcmp(dstBuffer, expected, 16),
3118 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3119 expected[0], expected[1], expected[2], expected[3],
3120 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3122 SelectObject(hdcSrc, oldSrc);
3123 DeleteObject(bmpSrc);
3125 bmpSrc = CreateBitmap( 16, 16, 1, 1, 0 );
3126 oldSrc = SelectObject(hdcSrc, bmpSrc);
3127 SetPixel( hdcSrc, 0, 0, 0 );
3128 SetPixel( hdcSrc, 1, 0, 0xffffff );
3129 SetPixel( hdcSrc, 2, 0, 0xffffff );
3130 SetPixel( hdcSrc, 3, 0, 0 );
3131 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
3132 SetTextColor( hdcDst, RGB(0x22,0x44,0x66) );
3133 SetBkColor( hdcDst, RGB(0x65,0x43,0x21) );
3134 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3135 expected[0] = expected[3] = 0x00224466;
3136 expected[1] = expected[2] = 0x00654321;
3137 ok(!memcmp(dstBuffer, expected, 16),
3138 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3139 expected[0], expected[1], expected[2], expected[3],
3140 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3142 SelectObject(hdcSrc, oldSrc);
3143 DeleteObject(bmpSrc);
3147 SelectObject(hdcDst, oldDst);
3148 DeleteObject(bmpDst);
3151 DeleteDC(hdcScreen);
3154 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3155 DWORD dwRop, UINT32 expected, int line)
3157 const UINT32 buffer[2] = { 0xFEDCBA98, 0 };
3158 BITMAPINFO bitmapInfo;
3160 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3161 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3162 bitmapInfo.bmiHeader.biWidth = 2;
3163 bitmapInfo.bmiHeader.biHeight = 1;
3164 bitmapInfo.bmiHeader.biPlanes = 1;
3165 bitmapInfo.bmiHeader.biBitCount = 32;
3166 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3167 bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer);
3169 *dstBuffer = 0x89ABCDEF;
3171 StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop);
3172 ok(expected == *dstBuffer,
3173 "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
3174 dwRop, expected, *dstBuffer, line);
3177 static void check_StretchDIBits_stretch(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3178 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
3179 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
3180 UINT32 expected[4], int line)
3182 BITMAPINFO bitmapInfo;
3184 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3185 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3186 bitmapInfo.bmiHeader.biWidth = 2;
3187 bitmapInfo.bmiHeader.biHeight = -2;
3188 bitmapInfo.bmiHeader.biPlanes = 1;
3189 bitmapInfo.bmiHeader.biBitCount = 32;
3190 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3192 memset(dstBuffer, 0, 16);
3193 StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
3194 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3195 srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
3196 ok(memcmp(dstBuffer, expected, 16) == 0,
3197 "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
3198 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
3199 expected[0], expected[1], expected[2], expected[3],
3200 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
3201 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3202 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
3205 static void test_StretchDIBits(void)
3209 HDC hdcScreen, hdcDst;
3210 UINT32 *dstBuffer, srcBuffer[4];
3211 HBRUSH hBrush, hOldBrush;
3215 memset(&biDst, 0, sizeof(BITMAPINFO));
3216 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3217 biDst.bmiHeader.biWidth = 2;
3218 biDst.bmiHeader.biHeight = -2;
3219 biDst.bmiHeader.biPlanes = 1;
3220 biDst.bmiHeader.biBitCount = 32;
3221 biDst.bmiHeader.biCompression = BI_RGB;
3223 hdcScreen = CreateCompatibleDC(0);
3224 hdcDst = CreateCompatibleDC(hdcScreen);
3227 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3229 oldDst = SelectObject(hdcDst, bmpDst);
3231 hBrush = CreateSolidBrush(0x012345678);
3232 hOldBrush = SelectObject(hdcDst, hBrush);
3234 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3235 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3236 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3237 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3238 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3239 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3240 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3241 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3242 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3243 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3244 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3245 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3246 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3247 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3248 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3250 SelectObject(hdcDst, hOldBrush);
3251 DeleteObject(hBrush);
3253 /* Top-down destination tests */
3254 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3255 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
3257 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
3258 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
3259 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3260 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3262 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3263 expected[2] = 0x00000000, expected[3] = 0x00000000;
3264 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3265 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
3267 expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
3268 expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
3269 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3270 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
3272 expected[0] = 0x42441000, expected[1] = 0x00000000;
3273 expected[2] = 0x00000000, expected[3] = 0x00000000;
3274 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3275 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
3277 expected[0] = 0x00000000, expected[1] = 0x00000000;
3278 expected[2] = 0x00000000, expected[3] = 0x00000000;
3279 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3280 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3282 expected[0] = 0x00000000, expected[1] = 0x00000000;
3283 expected[2] = 0x00000000, expected[3] = 0x00000000;
3284 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3285 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3287 expected[0] = 0x00000000, expected[1] = 0x00000000;
3288 expected[2] = 0x00000000, expected[3] = 0x00000000;
3289 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3290 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
3292 expected[0] = 0x00000000, expected[1] = 0x00000000;
3293 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
3294 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3295 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3297 SelectObject(hdcDst, oldDst);
3298 DeleteObject(bmpDst);
3300 /* Bottom up destination tests */
3301 biDst.bmiHeader.biHeight = 2;
3302 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3304 oldDst = SelectObject(hdcDst, bmpDst);
3306 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3307 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
3308 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3309 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3312 SelectObject(hdcDst, oldDst);
3313 DeleteObject(bmpDst);
3316 DeleteDC(hdcScreen);
3319 static void test_GdiAlphaBlend(void)
3331 BLENDFUNCTION blend;
3333 if (!pGdiAlphaBlend)
3335 win_skip("GdiAlphaBlend() is not implemented\n");
3339 hdcNull = GetDC(NULL);
3340 hdcDst = CreateCompatibleDC(hdcNull);
3341 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
3342 hdcSrc = CreateCompatibleDC(hdcNull);
3344 bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3345 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3346 bmi->bmiHeader.biHeight = 20;
3347 bmi->bmiHeader.biWidth = 20;
3348 bmi->bmiHeader.biBitCount = 32;
3349 bmi->bmiHeader.biPlanes = 1;
3350 bmi->bmiHeader.biCompression = BI_RGB;
3351 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3352 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3354 oldDst = SelectObject(hdcDst, bmpDst);
3355 oldSrc = SelectObject(hdcSrc, bmpSrc);
3357 blend.BlendOp = AC_SRC_OVER;
3358 blend.BlendFlags = 0;
3359 blend.SourceConstantAlpha = 128;
3360 blend.AlphaFormat = 0;
3362 SetLastError(0xdeadbeef);
3363 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3364 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3366 SetLastError(0xdeadbeef);
3367 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3368 ok( !ret, "GdiAlphaBlend succeeded\n" );
3369 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3371 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3372 ok( !ret, "GdiAlphaBlend succeeded\n" );
3373 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend);
3374 ok( !ret, "GdiAlphaBlend succeeded\n" );
3375 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3376 ok( !ret, "GdiAlphaBlend succeeded\n" );
3377 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3378 ok( !ret, "GdiAlphaBlend succeeded\n" );
3380 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
3381 SetLastError(0xdeadbeef);
3382 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3383 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3384 SetLastError(0xdeadbeef);
3385 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3386 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3387 SetMapMode(hdcSrc, MM_ANISOTROPIC);
3388 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
3389 SetLastError(0xdeadbeef);
3390 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend);
3391 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3392 SetLastError(0xdeadbeef);
3393 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend);
3394 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3396 SetMapMode(hdcDst, MM_ANISOTROPIC);
3397 SetViewportExtEx(hdcDst, -1, -1, NULL);
3398 SetLastError(0xdeadbeef);
3399 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 50, 50, blend);
3400 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3401 SetLastError(0xdeadbeef);
3402 ret = pGdiAlphaBlend(hdcDst, -20, -20, 20, 20, hdcSrc, 0, -1, 50, 50, blend);
3403 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3404 SetLastError(0xdeadbeef);
3405 ret = pGdiAlphaBlend(hdcDst, -20, -20, -20, -20, hdcSrc, 0, -1, 50, 50, blend);
3406 ok( !ret, "GdiAlphaBlend succeeded\n" );
3407 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3408 SetLastError(0xdeadbeef);
3409 ret = pGdiAlphaBlend(hdcDst, -20, 0, -20, 20, hdcSrc, 0, -1, 50, 50, blend);
3410 ok( !ret, "GdiAlphaBlend succeeded\n" );
3411 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3412 SetLastError(0xdeadbeef);
3413 ret = pGdiAlphaBlend(hdcDst, 0, -20, 20, -20, hdcSrc, 0, -1, 50, 50, blend);
3414 ok( !ret, "GdiAlphaBlend succeeded\n" );
3415 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3416 SetMapMode(hdcDst, MM_TEXT);
3418 SetViewportExtEx(hdcSrc, -1, -1, NULL);
3419 SetLastError(0xdeadbeef);
3420 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, -30, -30, blend);
3421 ok( !ret, "GdiAlphaBlend succeeded\n" );
3422 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3423 SetLastError(0xdeadbeef);
3424 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, 30, -30, blend);
3425 ok( !ret, "GdiAlphaBlend succeeded\n" );
3426 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3427 SetLastError(0xdeadbeef);
3428 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, -30, 30, blend);
3429 ok( !ret, "GdiAlphaBlend succeeded\n" );
3430 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3431 SetLastError(0xdeadbeef);
3432 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, 30, 30, blend);
3433 ok( !ret, "GdiAlphaBlend succeeded\n" );
3434 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3435 SetLastError(0xdeadbeef);
3436 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 20, 20, 30, 30, blend);
3437 ok( !ret, "GdiAlphaBlend succeeded\n" );
3438 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3439 SetLastError(0xdeadbeef);
3440 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -60, -60, 30, 30, blend);
3441 ok( !ret, "GdiAlphaBlend succeeded\n" );
3442 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3443 SetViewportExtEx(hdcSrc, 1, 1, NULL);
3445 SetLastError(0xdeadbeef);
3446 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend);
3447 ok( !ret, "GdiAlphaBlend succeeded\n" );
3448 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3450 /* overlapping source and dest not allowed */
3452 SetLastError(0xdeadbeef);
3453 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 19, 19, 20, 20, blend);
3454 ok( !ret, "GdiAlphaBlend succeeded\n" );
3455 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3457 SetLastError(0xdeadbeef);
3458 ret = pGdiAlphaBlend(hdcDst, 20, 20, 20, 20, hdcDst, 1, 1, 20, 20, blend);
3459 ok( !ret, "GdiAlphaBlend succeeded\n" );
3460 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3462 SetLastError(0xdeadbeef);
3463 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 20, 10, 20, 20, blend);
3464 ok( ret, "GdiAlphaBlend succeeded\n" );
3465 SetLastError(0xdeadbeef);
3466 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 10, 20, 20, 20, blend);
3467 ok( ret, "GdiAlphaBlend succeeded\n" );
3469 /* AC_SRC_ALPHA requires 32-bpp BI_RGB format */
3471 blend.AlphaFormat = AC_SRC_ALPHA;
3472 SetLastError(0xdeadbeef);
3473 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3474 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3476 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3477 ((DWORD *)bmi->bmiColors)[0] = 0xff0000;
3478 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3479 ((DWORD *)bmi->bmiColors)[2] = 0x0000ff;
3480 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3481 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3482 oldSrc = SelectObject(hdcSrc, bmpSrc);
3483 DeleteObject( oldSrc );
3485 SetLastError(0xdeadbeef);
3486 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3487 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3489 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3490 ((DWORD *)bmi->bmiColors)[0] = 0x0000ff;
3491 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3492 ((DWORD *)bmi->bmiColors)[2] = 0xff0000;
3493 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3494 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3495 oldSrc = SelectObject(hdcSrc, bmpSrc);
3496 DeleteObject( oldSrc );
3498 SetLastError(0xdeadbeef);
3499 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3500 ok( !ret, "GdiAlphaBlend succeeded\n" );
3501 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3503 bmi->bmiHeader.biBitCount = 24;
3504 bmi->bmiHeader.biCompression = BI_RGB;
3505 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3506 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3507 oldSrc = SelectObject(hdcSrc, bmpSrc);
3508 DeleteObject( oldSrc );
3510 SetLastError(0xdeadbeef);
3511 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3512 ok( !ret, "GdiAlphaBlend succeeded\n" );
3513 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3515 bmi->bmiHeader.biBitCount = 1;
3516 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3517 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3518 oldSrc = SelectObject(hdcSrc, bmpSrc);
3519 DeleteObject( oldSrc );
3521 SetLastError(0xdeadbeef);
3522 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3523 ok( !ret, "GdiAlphaBlend succeeded\n" );
3524 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3526 bmpSrc = CreateBitmap( 100, 100, 1, 1, NULL );
3527 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3528 oldSrc = SelectObject(hdcSrc, bmpSrc);
3529 DeleteObject( oldSrc );
3531 SetLastError(0xdeadbeef);
3532 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3533 ok( !ret, "GdiAlphaBlend succeeded\n" );
3534 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3536 SelectObject(hdcDst, oldDst);
3537 SelectObject(hdcSrc, oldSrc);
3538 DeleteObject(bmpSrc);
3539 DeleteObject(bmpDst);
3543 ReleaseDC(NULL, hdcNull);
3547 static void test_GdiGradientFill(void)
3554 GRADIENT_RECT rect[] = { { 0, 0 }, { 0, 1 }, { 2, 3 } };
3555 GRADIENT_TRIANGLE tri[] = { { 0, 0, 0 }, { 0, 1, 2 }, { 0, 2, 1 }, { 0, 1, 3 } };
3556 TRIVERTEX vt[3] = { { 2, 2, 0xff00, 0x0000, 0x0000, 0x8000 },
3557 { 10, 10, 0x0000, 0xff00, 0x0000, 0x8000 },
3558 { 20, 10, 0x0000, 0x0000, 0xff00, 0xff00 } };
3560 if (!pGdiGradientFill)
3562 win_skip( "GdiGradientFill is not implemented\n" );
3566 hdc = CreateCompatibleDC( NULL );
3567 bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3568 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3569 bmi->bmiHeader.biHeight = 20;
3570 bmi->bmiHeader.biWidth = 20;
3571 bmi->bmiHeader.biBitCount = 32;
3572 bmi->bmiHeader.biPlanes = 1;
3573 bmi->bmiHeader.biCompression = BI_RGB;
3574 bmp = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3575 ok( bmp != NULL, "couldn't create bitmap\n" );
3576 SelectObject( hdc, bmp );
3578 SetLastError( 0xdeadbeef );
3579 ret = pGdiGradientFill( hdc, vt, 3, rect, 1, GRADIENT_FILL_RECT_H );
3580 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3581 SetLastError( 0xdeadbeef );
3582 ret = pGdiGradientFill( hdc, vt, 3, rect, 1, 3 );
3583 ok( !ret, "GdiGradientFill succeeded\n" );
3584 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3585 SetLastError( 0xdeadbeef );
3586 ret = pGdiGradientFill( (HDC)0xdead, vt, 3, rect, 1, GRADIENT_FILL_RECT_H );
3587 ok( !ret, "GdiGradientFill succeeded\n" );
3588 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3589 SetLastError( 0xdeadbeef );
3590 ret = pGdiGradientFill( NULL, NULL, 0, rect, 1, GRADIENT_FILL_RECT_H );
3591 ok( !ret, "GdiGradientFill succeeded\n" );
3592 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3593 ret = pGdiGradientFill( hdc, NULL, 0, rect, 1, GRADIENT_FILL_RECT_H );
3594 ok( !ret, "GdiGradientFill succeeded\n" );
3595 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3596 SetLastError( 0xdeadbeef );
3597 ret = pGdiGradientFill( hdc, NULL, 3, rect, 1, GRADIENT_FILL_RECT_H );
3598 ok( !ret, "GdiGradientFill succeeded\n" );
3599 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3600 SetLastError( 0xdeadbeef );
3601 ret = pGdiGradientFill( hdc, vt, 3, NULL, 0, GRADIENT_FILL_RECT_H );
3602 ok( !ret, "GdiGradientFill succeeded\n" );
3603 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3604 SetLastError( 0xdeadbeef );
3605 ret = pGdiGradientFill( hdc, vt, 3, NULL, 1, GRADIENT_FILL_RECT_H );
3606 ok( !ret, "GdiGradientFill succeeded\n" );
3607 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3608 SetLastError( 0xdeadbeef );
3609 ret = pGdiGradientFill( hdc, vt, 3, rect, 0, GRADIENT_FILL_RECT_H );
3610 ok( !ret, "GdiGradientFill succeeded\n" );
3611 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3612 SetLastError( 0xdeadbeef );
3613 ret = pGdiGradientFill( hdc, vt, 3, rect, 3, GRADIENT_FILL_RECT_H );
3614 ok( !ret, "GdiGradientFill succeeded\n" );
3615 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3616 rect[2].UpperLeft = rect[2].LowerRight = 1;
3617 SetLastError( 0xdeadbeef );
3618 ret = pGdiGradientFill( hdc, vt, 3, rect, 3, GRADIENT_FILL_RECT_H );
3619 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3620 SetLastError( 0xdeadbeef );
3621 ret = pGdiGradientFill( hdc, vt, 1, rect, 1, GRADIENT_FILL_RECT_H );
3622 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3623 SetLastError( 0xdeadbeef );
3624 ret = pGdiGradientFill( hdc, vt, 1, tri, 0, GRADIENT_FILL_TRIANGLE );
3625 ok( !ret, "GdiGradientFill succeeded\n" );
3626 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3627 SetLastError( 0xdeadbeef );
3628 ret = pGdiGradientFill( hdc, vt, 1, tri, 1, GRADIENT_FILL_TRIANGLE );
3629 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3630 SetLastError( 0xdeadbeef );
3631 ret = pGdiGradientFill( hdc, vt, 3, tri, 2, GRADIENT_FILL_TRIANGLE );
3632 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3633 SetLastError( 0xdeadbeef );
3634 ret = pGdiGradientFill( hdc, vt, 3, tri, 3, GRADIENT_FILL_TRIANGLE );
3635 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3636 SetLastError( 0xdeadbeef );
3637 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3638 ok( !ret, "GdiGradientFill succeeded\n" );
3639 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3641 SetLastError( 0xdeadbeef );
3642 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3643 ok( !ret, "GdiGradientFill succeeded\n" );
3644 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3646 SetLastError( 0xdeadbeef );
3647 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3648 ok( !ret, "GdiGradientFill succeeded\n" );
3649 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3650 tri[3].Vertex1 = tri[3].Vertex2 = tri[3].Vertex3 = 1;
3651 SetLastError( 0xdeadbeef );
3652 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3653 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3656 DeleteObject( bmp );
3659 static void test_clipping(void)
3667 HDC hdcDst = CreateCompatibleDC( NULL );
3668 HDC hdcSrc = CreateCompatibleDC( NULL );
3670 BITMAPINFO bmpinfo={{0}};
3671 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3672 bmpinfo.bmiHeader.biWidth = 100;
3673 bmpinfo.bmiHeader.biHeight = 100;
3674 bmpinfo.bmiHeader.biPlanes = 1;
3675 bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3676 bmpinfo.bmiHeader.biCompression = BI_RGB;
3678 bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3679 ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3680 SelectObject( hdcDst, bmpDst );
3682 bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3683 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3684 SelectObject( hdcSrc, bmpSrc );
3686 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3687 ok(result, "BitBlt failed\n");
3689 hRgn = CreateRectRgn( 0,0,0,0 );
3690 SelectClipRgn( hdcDst, hRgn );
3692 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3693 ok(result, "BitBlt failed\n");
3695 DeleteObject( bmpDst );
3696 DeleteObject( bmpSrc );
3697 DeleteObject( hRgn );
3702 static void test_32bit_ddb(void)
3704 char buffer[sizeof(BITMAPINFOHEADER) + sizeof(DWORD)];
3705 BITMAPINFO *biDst = (BITMAPINFO *)buffer;
3706 HBITMAP bmpSrc, bmpDst;
3707 HBITMAP oldSrc, oldDst;
3708 HDC hdcSrc, hdcDst, hdcScreen;
3710 DWORD *dstBuffer, *data;
3711 DWORD colorSrc = 0x40201008;
3713 memset(biDst, 0, sizeof(BITMAPINFOHEADER));
3714 biDst->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3715 biDst->bmiHeader.biWidth = 1;
3716 biDst->bmiHeader.biHeight = -1;
3717 biDst->bmiHeader.biPlanes = 1;
3718 biDst->bmiHeader.biBitCount = 32;
3719 biDst->bmiHeader.biCompression = BI_RGB;
3721 hdcScreen = CreateCompatibleDC(0);
3722 if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3724 DeleteDC(hdcScreen);
3725 trace("Skipping 32-bit DDB test\n");
3729 hdcSrc = CreateCompatibleDC(hdcScreen);
3730 bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3731 oldSrc = SelectObject(hdcSrc, bmpSrc);
3733 hdcDst = CreateCompatibleDC(hdcScreen);
3734 bmpDst = CreateDIBSection(hdcDst, biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3735 oldDst = SelectObject(hdcDst, bmpDst);
3737 StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3738 ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3742 BLENDFUNCTION blend;
3745 blend.BlendOp = AC_SRC_OVER;
3746 blend.BlendFlags = 0;
3747 blend.SourceConstantAlpha = 128;
3748 blend.AlphaFormat = 0;
3749 dstBuffer[0] = 0x80808080;
3750 ret = pGdiAlphaBlend( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, blend );
3751 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3752 ok(dstBuffer[0] == 0x60504844, "wrong color %x\n", dstBuffer[0]);
3753 blend.AlphaFormat = AC_SRC_ALPHA;
3754 dstBuffer[0] = 0x80808080;
3755 ret = pGdiAlphaBlend( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, blend );
3756 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3757 ok(dstBuffer[0] == 0x90807874, "wrong color %x\n", dstBuffer[0]);
3760 data = (DWORD *)biDst->bmiColors;
3761 data[0] = 0x20304050;
3762 brush = CreateDIBPatternBrushPt( biDst, DIB_RGB_COLORS );
3763 ok( brush != 0, "brush creation failed\n" );
3764 SelectObject( hdcSrc, brush );
3765 PatBlt( hdcSrc, 0, 0, 1, 1, PATCOPY );
3766 BitBlt( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, SRCCOPY );
3767 ok(dstBuffer[0] == data[0], "Expected color=%x, received color=%x\n", data[0], dstBuffer[0]);
3768 SelectObject( hdcSrc, GetStockObject(BLACK_BRUSH) );
3769 DeleteObject( brush );
3771 biDst->bmiHeader.biBitCount = 24;
3772 brush = CreateDIBPatternBrushPt( biDst, DIB_RGB_COLORS );
3773 ok( brush != 0, "brush creation failed\n" );
3774 SelectObject( hdcSrc, brush );
3775 PatBlt( hdcSrc, 0, 0, 1, 1, PATCOPY );
3776 BitBlt( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, SRCCOPY );
3777 ok(dstBuffer[0] == (data[0] & ~0xff000000),
3778 "Expected color=%x, received color=%x\n", data[0] & 0xff000000, dstBuffer[0]);
3779 SelectObject( hdcSrc, GetStockObject(BLACK_BRUSH) );
3780 DeleteObject( brush );
3783 SelectObject(hdcDst, oldDst);
3784 DeleteObject(bmpDst);
3787 SelectObject(hdcSrc, oldSrc);
3788 DeleteObject(bmpSrc);
3791 DeleteDC(hdcScreen);
3795 * Used by test_GetDIBits_top_down to create the bitmap to test against.
3797 static void setup_picture(char *picture, int bpp)
3805 /*Set the first byte in each pixel to the index of that pixel.*/
3806 for (i = 0; i < 4; i++)
3807 picture[i * (bpp / 8)] = i;
3812 /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
3819 static void test_GetDIBits_top_down(int bpp)
3822 HBITMAP bmptb, bmpbt;
3828 memset( &bi, 0, sizeof(bi) );
3829 bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
3830 bi.bmiHeader.biWidth=2;
3831 bi.bmiHeader.biHeight=2;
3832 bi.bmiHeader.biPlanes=1;
3833 bi.bmiHeader.biBitCount=bpp;
3834 bi.bmiHeader.biCompression=BI_RGB;
3836 /*Get the device context for the screen.*/
3838 ok(hdc != NULL, "Could not get a handle to a device context.\n");
3840 /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
3841 bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3842 ok(bmpbt != NULL, "Could not create a DIB section.\n");
3843 /*Now that we have a pointer to the pixels, we write to them.*/
3844 setup_picture((char*)picture, bpp);
3845 /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
3846 bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
3847 bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3848 ok(bmptb != NULL, "Could not create a DIB section.\n");
3849 /*Write to this top to bottom bitmap.*/
3850 setup_picture((char*)picture, bpp);
3852 bi.bmiHeader.biWidth = 1;
3854 bi.bmiHeader.biHeight = 2;
3855 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3856 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3857 /*Check the first byte of the pixel.*/
3858 ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3859 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3860 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3861 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3862 /*Check second scanline.*/
3863 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3864 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3865 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3866 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3867 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3868 ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3869 /*Check both scanlines.*/
3870 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3871 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3872 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3873 ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3874 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3875 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3876 ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3877 ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3879 /*Make destination bitmap top-down.*/
3880 bi.bmiHeader.biHeight = -2;
3881 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3882 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3883 ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3884 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3885 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3886 ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3887 /*Check second scanline.*/
3888 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3889 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3890 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3891 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3892 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3893 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3894 /*Check both scanlines.*/
3895 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3896 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3897 ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3898 ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3899 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3900 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3901 ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3902 ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3904 DeleteObject(bmpbt);
3905 DeleteObject(bmptb);
3908 static void test_GetSetDIBits_rtl(void)
3911 HBITMAP bitmap, orig_bitmap;
3914 DWORD bits_1[8 * 8], bits_2[8 * 8];
3918 win_skip("Don't have SetLayout\n");
3922 hdc = GetDC( NULL );
3923 hdc_mem = CreateCompatibleDC( hdc );
3924 pSetLayout( hdc_mem, LAYOUT_LTR );
3926 bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
3927 orig_bitmap = SelectObject( hdc_mem, bitmap );
3928 SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
3929 SelectObject( hdc_mem, orig_bitmap );
3931 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3932 info.bmiHeader.biWidth = 8;
3933 info.bmiHeader.biHeight = 8;
3934 info.bmiHeader.biPlanes = 1;
3935 info.bmiHeader.biBitCount = 32;
3936 info.bmiHeader.biCompression = BI_RGB;
3938 /* First show that GetDIBits ignores the layout mode. */
3940 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3941 ok(ret == 8, "got %d\n", ret);
3942 ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
3944 pSetLayout( hdc_mem, LAYOUT_RTL );
3946 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3947 ok(ret == 8, "got %d\n", ret);
3949 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3951 /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
3952 followed by a GetDIBits and show that the bits remain unchanged. */
3954 pSetLayout( hdc_mem, LAYOUT_LTR );
3956 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3957 ok(ret == 8, "got %d\n", ret);
3958 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3959 ok(ret == 8, "got %d\n", ret);
3960 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3962 pSetLayout( hdc_mem, LAYOUT_RTL );
3964 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3965 ok(ret == 8, "got %d\n", ret);
3966 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3967 ok(ret == 8, "got %d\n", ret);
3968 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3970 DeleteObject( bitmap );
3971 DeleteDC( hdc_mem );
3972 ReleaseDC( NULL, hdc );
3975 static void test_GetDIBits_scanlines(void)
3979 HDC hdc = GetDC( NULL );
3981 DWORD data[128], inverted_bits[64];
3984 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
3986 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3987 info->bmiHeader.biWidth = 8;
3988 info->bmiHeader.biHeight = 8;
3989 info->bmiHeader.biPlanes = 1;
3990 info->bmiHeader.biBitCount = 32;
3991 info->bmiHeader.biCompression = BI_RGB;
3993 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3995 for (i = 0; i < 64; i++)
3998 inverted_bits[56 - (i & ~7) + (i & 7)] = i;
4003 memset( data, 0xaa, sizeof(data) );
4005 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4006 ok( ret == 8, "got %d\n", ret );
4007 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4008 memset( data, 0xaa, sizeof(data) );
4010 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4011 ok( ret == 5, "got %d\n", ret );
4012 ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
4013 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4014 memset( data, 0xaa, sizeof(data) );
4016 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4017 ok( ret == 7, "got %d\n", ret );
4018 ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
4019 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4020 memset( data, 0xaa, sizeof(data) );
4022 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4023 ok( ret == 1, "got %d\n", ret );
4024 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4025 memset( data, 0xaa, sizeof(data) );
4027 info->bmiHeader.biHeight = 16;
4028 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4029 ok( ret == 5, "got %d\n", ret );
4030 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4031 ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
4032 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4033 memset( data, 0xaa, sizeof(data) );
4035 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
4036 ok( ret == 6, "got %d\n", ret );
4037 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4038 ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
4039 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4040 memset( data, 0xaa, sizeof(data) );
4042 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
4043 ok( ret == 0, "got %d\n", ret );
4044 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4045 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4046 memset( data, 0xaa, sizeof(data) );
4048 info->bmiHeader.biHeight = 5;
4049 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4050 ok( ret == 2, "got %d\n", ret );
4051 ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
4052 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4053 memset( data, 0xaa, sizeof(data) );
4057 info->bmiHeader.biHeight = -8;
4058 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4059 ok( ret == 8, "got %d\n", ret );
4060 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4061 memset( data, 0xaa, sizeof(data) );
4063 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4064 ok( ret == 5, "got %d\n", ret );
4065 ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
4066 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4067 memset( data, 0xaa, sizeof(data) );
4069 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4070 ok( ret == 7, "got %d\n", ret );
4071 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
4072 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4073 memset( data, 0xaa, sizeof(data) );
4075 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4076 ok( ret == 4, "got %d\n", ret );
4077 ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
4078 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4079 memset( data, 0xaa, sizeof(data) );
4081 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
4082 ok( ret == 5, "got %d\n", ret );
4083 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
4084 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4085 memset( data, 0xaa, sizeof(data) );
4087 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
4088 ok( ret == 5, "got %d\n", ret );
4089 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
4090 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4091 memset( data, 0xaa, sizeof(data) );
4093 info->bmiHeader.biHeight = -16;
4094 ret = GetDIBits( hdc, dib, 0, 16, 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 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4098 memset( data, 0xaa, sizeof(data) );
4100 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4101 ok( ret == 5, "got %d\n", ret );
4102 ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
4103 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4104 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4105 memset( data, 0xaa, sizeof(data) );
4107 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4108 ok( ret == 8, "got %d\n", ret );
4109 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4110 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4111 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4112 memset( data, 0xaa, sizeof(data) );
4114 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4115 ok( ret == 8, "got %d\n", ret );
4116 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4117 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4118 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4119 memset( data, 0xaa, sizeof(data) );
4121 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4122 ok( ret == 7, "got %d\n", ret );
4123 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
4124 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4125 memset( data, 0xaa, sizeof(data) );
4127 ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
4128 ok( ret == 1, "got %d\n", ret );
4129 for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4130 memset( data, 0xaa, sizeof(data) );
4132 info->bmiHeader.biHeight = -5;
4133 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4134 ok( ret == 2, "got %d\n", ret );
4135 ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
4136 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4137 memset( data, 0xaa, sizeof(data) );
4139 DeleteObject( dib );
4141 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4142 info->bmiHeader.biWidth = 8;
4143 info->bmiHeader.biHeight = -8;
4144 info->bmiHeader.biPlanes = 1;
4145 info->bmiHeader.biBitCount = 32;
4146 info->bmiHeader.biCompression = BI_RGB;
4148 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4150 for (i = 0; i < 64; i++) dib_bits[i] = i;
4154 info->bmiHeader.biHeight = -8;
4155 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4156 ok( ret == 8, "got %d\n", ret );
4157 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4158 memset( data, 0xaa, sizeof(data) );
4160 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4161 ok( ret == 5, "got %d\n", ret );
4162 ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
4163 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4164 memset( data, 0xaa, sizeof(data) );
4166 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4167 ok( ret == 7, "got %d\n", ret );
4168 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
4169 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4170 memset( data, 0xaa, sizeof(data) );
4172 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4173 ok( ret == 4, "got %d\n", ret );
4174 ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
4175 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4176 memset( data, 0xaa, sizeof(data) );
4178 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
4179 ok( ret == 5, "got %d\n", ret );
4180 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
4181 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4182 memset( data, 0xaa, sizeof(data) );
4184 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
4185 ok( ret == 5, "got %d\n", ret );
4186 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
4187 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4188 memset( data, 0xaa, sizeof(data) );
4190 info->bmiHeader.biHeight = -16;
4191 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
4192 ok( ret == 8, "got %d\n", ret );
4193 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4194 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4195 memset( data, 0xaa, sizeof(data) );
4197 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4198 ok( ret == 5, "got %d\n", ret );
4199 ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
4200 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4201 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4202 memset( data, 0xaa, sizeof(data) );
4204 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4205 ok( ret == 8, "got %d\n", ret );
4206 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4207 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4208 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4209 memset( data, 0xaa, sizeof(data) );
4211 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4212 ok( ret == 8, "got %d\n", ret );
4213 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4214 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4215 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4216 memset( data, 0xaa, sizeof(data) );
4218 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4219 ok( ret == 7, "got %d\n", ret );
4220 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
4221 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4222 memset( data, 0xaa, sizeof(data) );
4224 info->bmiHeader.biHeight = -5;
4225 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4226 ok( ret == 2, "got %d\n", ret );
4227 ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
4228 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4229 memset( data, 0xaa, sizeof(data) );
4234 info->bmiHeader.biHeight = 8;
4236 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4237 ok( ret == 8, "got %d\n", ret );
4238 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4239 memset( data, 0xaa, sizeof(data) );
4241 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4242 ok( ret == 5, "got %d\n", ret );
4243 ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
4244 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4245 memset( data, 0xaa, sizeof(data) );
4247 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4248 ok( ret == 7, "got %d\n", ret );
4249 ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
4250 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4251 memset( data, 0xaa, sizeof(data) );
4253 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4254 ok( ret == 1, "got %d\n", ret );
4255 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4256 memset( data, 0xaa, sizeof(data) );
4258 info->bmiHeader.biHeight = 16;
4259 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4260 ok( ret == 5, "got %d\n", ret );
4261 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4262 ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
4263 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4264 memset( data, 0xaa, sizeof(data) );
4266 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
4267 ok( ret == 6, "got %d\n", ret );
4268 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4269 ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
4270 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4271 memset( data, 0xaa, sizeof(data) );
4273 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
4274 ok( ret == 0, "got %d\n", ret );
4275 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4276 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4277 memset( data, 0xaa, sizeof(data) );
4279 info->bmiHeader.biHeight = 5;
4280 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4281 ok( ret == 2, "got %d\n", ret );
4282 ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
4283 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4284 memset( data, 0xaa, sizeof(data) );
4286 DeleteObject( dib );
4288 ReleaseDC( NULL, hdc );
4289 HeapFree( GetProcessHeap(), 0, info );
4293 static void test_SetDIBits(void)
4295 char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
4296 LOGPALETTE *pal = (LOGPALETTE *)palbuf;
4297 PALETTEENTRY *palent = pal->palPalEntry;
4301 HDC hdc = GetDC( NULL );
4302 DWORD data[128], inverted_data[128];
4306 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4308 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4309 info->bmiHeader.biWidth = 8;
4310 info->bmiHeader.biHeight = 8;
4311 info->bmiHeader.biPlanes = 1;
4312 info->bmiHeader.biBitCount = 32;
4313 info->bmiHeader.biCompression = BI_RGB;
4315 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4316 memset( dib_bits, 0xaa, 64 * 4 );
4318 for (i = 0; i < 128; i++)
4321 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4326 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4327 ok( ret == 8, "got %d\n", ret );
4328 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4329 memset( dib_bits, 0xaa, 64 * 4 );
4331 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4332 ok( ret == 5, "got %d\n", ret );
4333 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4334 ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
4335 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4336 memset( dib_bits, 0xaa, 64 * 4 );
4338 /* top of dst is aligned with startscans down for the top of the src.
4339 Then starting from the bottom of src, lines rows are copied across. */
4341 info->bmiHeader.biHeight = 16;
4342 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4343 ok( ret == 12, "got %d\n", ret );
4344 ok( !memcmp( dib_bits, data + 56, 40 * 4 ), "bits differ\n");
4345 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4346 memset( dib_bits, 0xaa, 64 * 4 );
4348 info->bmiHeader.biHeight = 5;
4349 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4350 ok( ret == 2, "got %d\n", ret );
4351 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4352 ok( !memcmp( dib_bits + 32, data, 16 * 4 ), "bits differ\n");
4353 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4354 memset( dib_bits, 0xaa, 64 * 4 );
4357 info->bmiHeader.biHeight = -8;
4358 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4359 ok( ret == 8, "got %d\n", ret );
4360 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4361 memset( dib_bits, 0xaa, 64 * 4 );
4363 /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
4364 we copy lines rows from the top of the src */
4366 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4367 ok( ret == 5, "got %d\n", ret );
4368 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4369 ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
4370 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4371 memset( dib_bits, 0xaa, 64 * 4 );
4373 info->bmiHeader.biHeight = -16;
4374 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4375 ok( ret == 12, "got %d\n", ret );
4376 ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
4377 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4378 memset( dib_bits, 0xaa, 64 * 4 );
4380 ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4381 ok( ret == 12, "got %d\n", ret );
4382 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4383 memset( dib_bits, 0xaa, 64 * 4 );
4385 ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4386 ok( ret == 12, "got %d\n", ret );
4387 ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
4388 memset( dib_bits, 0xaa, 64 * 4 );
4390 info->bmiHeader.biHeight = -5;
4391 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4392 ok( ret == 2, "got %d\n", ret );
4393 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4394 ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
4395 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4396 memset( dib_bits, 0xaa, 64 * 4 );
4398 DeleteObject( dib );
4400 info->bmiHeader.biHeight = -8;
4402 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4403 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4407 /* like the t-d -> b-u case. */
4409 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4410 ok( ret == 8, "got %d\n", ret );
4411 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4412 memset( dib_bits, 0xaa, 64 * 4 );
4414 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4415 ok( ret == 5, "got %d\n", ret );
4416 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4417 ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
4418 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4419 memset( dib_bits, 0xaa, 64 * 4 );
4421 info->bmiHeader.biHeight = -16;
4422 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4423 ok( ret == 12, "got %d\n", ret );
4424 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4425 ok( !memcmp( dib_bits + 24, data, 40 * 4 ), "bits differ\n");
4426 memset( dib_bits, 0xaa, 64 * 4 );
4428 info->bmiHeader.biHeight = -5;
4429 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4430 ok( ret == 2, "got %d\n", ret );
4431 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4432 ok( !memcmp( dib_bits + 16, data, 16 * 4 ), "bits differ\n");
4433 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4434 memset( dib_bits, 0xaa, 64 * 4 );
4437 /* like the b-u -> b-u case */
4439 info->bmiHeader.biHeight = 8;
4440 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4441 ok( ret == 8, "got %d\n", ret );
4442 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4443 memset( dib_bits, 0xaa, 64 * 4 );
4445 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4446 ok( ret == 5, "got %d\n", ret );
4447 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4448 ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
4449 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4450 memset( dib_bits, 0xaa, 64 * 4 );
4452 info->bmiHeader.biHeight = 16;
4453 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4454 ok( ret == 12, "got %d\n", ret );
4455 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4456 ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
4457 memset( dib_bits, 0xaa, 64 * 4 );
4459 info->bmiHeader.biHeight = 5;
4460 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4461 ok( ret == 2, "got %d\n", ret );
4462 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4463 ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
4464 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4465 memset( dib_bits, 0xaa, 64 * 4 );
4467 /* handling of partial color table */
4469 info->bmiHeader.biHeight = -8;
4470 info->bmiHeader.biBitCount = 8;
4471 info->bmiHeader.biClrUsed = 137;
4472 for (i = 0; i < 256; i++)
4474 info->bmiColors[i].rgbRed = 255 - i;
4475 info->bmiColors[i].rgbGreen = i * 2;
4476 info->bmiColors[i].rgbBlue = i;
4477 info->bmiColors[i].rgbReserved = 0;
4479 for (i = 0; i < 64; i++) ((BYTE *)data)[i] = i * 4 + 1;
4480 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4481 ok( ret == 8, "got %d\n", ret );
4482 for (i = 0; i < 64; i++)
4484 int idx = i * 4 + 1;
4485 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : (info->bmiColors[idx].rgbRed << 16 |
4486 info->bmiColors[idx].rgbGreen << 8 |
4487 info->bmiColors[idx].rgbBlue);
4488 ok( dib_bits[i] == expect, "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
4490 memset( dib_bits, 0xaa, 64 * 4 );
4492 /* handling of DIB_PAL_COLORS */
4494 pal->palVersion = 0x300;
4495 pal->palNumEntries = 137;
4496 info->bmiHeader.biClrUsed = 221;
4497 for (i = 0; i < 256; i++)
4499 palent[i].peRed = i * 2;
4500 palent[i].peGreen = 255 - i;
4501 palent[i].peBlue = i;
4503 palette = CreatePalette( pal );
4504 ok( palette != 0, "palette creation failed\n" );
4505 SelectPalette( hdc, palette, FALSE );
4506 for (i = 0; i < 256; i++) ((WORD *)info->bmiColors)[i] = 255 - i;
4507 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_PAL_COLORS );
4508 ok( ret == 8, "got %d\n", ret );
4509 for (i = 0; i < 64; i++)
4511 int idx = i * 4 + 1;
4512 int ent = (255 - idx) % pal->palNumEntries;
4513 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 :
4514 (palent[ent].peRed << 16 | palent[ent].peGreen << 8 | palent[ent].peBlue);
4515 ok( dib_bits[i] == expect || broken(dib_bits[i] == 0), /* various Windows versions get some values wrong */
4516 "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
4518 memset( dib_bits, 0xaa, 64 * 4 );
4520 ReleaseDC( NULL, hdc );
4521 DeleteObject( dib );
4522 DeleteObject( palette );
4523 HeapFree( GetProcessHeap(), 0, info );
4526 static void test_SetDIBits_RLE4(void)
4530 HDC hdc = GetDC( NULL );
4531 BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00, /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
4532 0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
4533 0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00, /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
4534 0x00, 0x02, 0x01, 0x02, 0x05, 0x87, /* dx=1, dy=2, 8, 7, 8, 7, 8 */
4535 0x00, 0x01 }; /* <eod> */
4538 DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
4539 0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
4540 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4541 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4542 0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
4543 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4544 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4545 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4547 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4549 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4550 info->bmiHeader.biWidth = 8;
4551 info->bmiHeader.biHeight = 8;
4552 info->bmiHeader.biPlanes = 1;
4553 info->bmiHeader.biBitCount = 32;
4554 info->bmiHeader.biCompression = BI_RGB;
4556 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4557 memset( dib_bits, 0xaa, 64 * 4 );
4559 info->bmiHeader.biBitCount = 4;
4560 info->bmiHeader.biCompression = BI_RLE4;
4561 info->bmiHeader.biSizeImage = sizeof(rle4_data);
4563 for (i = 0; i < 16; i++)
4565 info->bmiColors[i].rgbRed = i;
4566 info->bmiColors[i].rgbGreen = i;
4567 info->bmiColors[i].rgbBlue = i;
4568 info->bmiColors[i].rgbReserved = 0;
4571 ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
4572 ok( ret == 8, "got %d\n", ret );
4573 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
4574 memset( dib_bits, 0xaa, 64 * 4 );
4576 DeleteObject( dib );
4577 ReleaseDC( NULL, hdc );
4578 HeapFree( GetProcessHeap(), 0, info );
4581 static void test_SetDIBits_RLE8(void)
4585 HDC hdc = GetDC( NULL );
4586 BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00, /* 2, 2, 2, f0, f0, f0, f0, <eol> */
4587 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4588 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4589 0x00, 0x01 }; /* <eod> */
4592 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4593 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4594 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4595 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4596 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4597 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4598 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4599 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4600 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4601 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4602 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4603 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4604 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4605 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4606 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4607 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4609 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4611 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4612 info->bmiHeader.biWidth = 8;
4613 info->bmiHeader.biHeight = 8;
4614 info->bmiHeader.biPlanes = 1;
4615 info->bmiHeader.biBitCount = 32;
4616 info->bmiHeader.biCompression = BI_RGB;
4618 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4619 memset( dib_bits, 0xaa, 64 * 4 );
4621 info->bmiHeader.biBitCount = 8;
4622 info->bmiHeader.biCompression = BI_RLE8;
4623 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4625 for (i = 0; i < 256; i++)
4627 info->bmiColors[i].rgbRed = i;
4628 info->bmiColors[i].rgbGreen = i;
4629 info->bmiColors[i].rgbBlue = i;
4630 info->bmiColors[i].rgbReserved = 0;
4633 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4634 ok( ret == 8, "got %d\n", ret );
4635 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4636 memset( dib_bits, 0xaa, 64 * 4 );
4638 /* startscan and lines are ignored, unless lines == 0 */
4639 ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4640 ok( ret == 8, "got %d\n", ret );
4641 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4642 memset( dib_bits, 0xaa, 64 * 4 );
4644 ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4645 ok( ret == 8, "got %d\n", ret );
4646 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4647 memset( dib_bits, 0xaa, 64 * 4 );
4649 ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4650 ok( ret == 0, "got %d\n", ret );
4651 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4652 memset( dib_bits, 0xaa, 64 * 4 );
4654 /* reduce width to 4, left-hand side of dst is touched. */
4655 info->bmiHeader.biWidth = 4;
4656 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4657 ok( ret == 8, "got %d\n", ret );
4658 for (i = 0; i < 64; i++)
4660 DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4661 ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4663 memset( dib_bits, 0xaa, 64 * 4 );
4665 /* Show that the top lines are aligned by adjusting the height of the src */
4667 /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4668 info->bmiHeader.biWidth = 8;
4669 info->bmiHeader.biHeight = 4;
4670 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4671 ok( ret == 4, "got %d\n", ret );
4672 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4673 ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4674 memset( dib_bits, 0xaa, 64 * 4 );
4676 /* increase the height to 9 -> everything moves down one row. */
4677 info->bmiHeader.biHeight = 9;
4678 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4679 ok( ret == 9, "got %d\n", ret );
4680 ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4681 for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4682 memset( dib_bits, 0xaa, 64 * 4 );
4684 /* top-down compressed dibs are invalid */
4685 info->bmiHeader.biHeight = -8;
4686 SetLastError( 0xdeadbeef );
4687 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4688 ok( ret == 0, "got %d\n", ret );
4689 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4690 DeleteObject( dib );
4694 info->bmiHeader.biHeight = -8;
4695 info->bmiHeader.biBitCount = 32;
4696 info->bmiHeader.biCompression = BI_RGB;
4697 info->bmiHeader.biSizeImage = 0;
4699 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4700 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4702 info->bmiHeader.biHeight = 8;
4703 info->bmiHeader.biBitCount = 8;
4704 info->bmiHeader.biCompression = BI_RLE8;
4705 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4707 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4708 ok( ret == 8, "got %d\n", ret );
4709 ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4710 memset( dib_bits, 0xaa, 64 * 4 );
4712 info->bmiHeader.biHeight = 4;
4713 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4714 ok( ret == 4, "got %d\n", ret );
4715 ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4716 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4717 memset( dib_bits, 0xaa, 64 * 4 );
4719 info->bmiHeader.biHeight = 9;
4720 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4721 ok( ret == 9, "got %d\n", ret );
4722 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4723 ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4724 memset( dib_bits, 0xaa, 64 * 4 );
4726 DeleteObject( dib );
4727 ReleaseDC( NULL, hdc );
4728 HeapFree( GetProcessHeap(), 0, info );
4731 static void test_SetDIBitsToDevice(void)
4733 char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
4734 LOGPALETTE *pal = (LOGPALETTE *)palbuf;
4735 PALETTEENTRY *palent = pal->palPalEntry;
4739 HDC hdc = CreateCompatibleDC( 0 );
4740 DWORD data[128], inverted_data[128];
4744 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4746 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4747 info->bmiHeader.biWidth = 8;
4748 info->bmiHeader.biHeight = 8;
4749 info->bmiHeader.biPlanes = 1;
4750 info->bmiHeader.biBitCount = 32;
4751 info->bmiHeader.biCompression = BI_RGB;
4753 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4754 memset( dib_bits, 0xaa, 64 * 4 );
4755 SelectObject( hdc, dib );
4757 for (i = 0; i < 128; i++)
4760 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4765 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4766 ok( ret == 8, "got %d\n", ret );
4767 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4768 memset( dib_bits, 0xaa, 64 * 4 );
4770 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4771 ok( ret == 5, "got %d\n", ret );
4772 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4773 for (i = 8; i < 48; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4774 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4775 memset( dib_bits, 0xaa, 64 * 4 );
4777 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 3, 1, 5, data, info, DIB_RGB_COLORS );
4778 ok( ret == 5, "got %d\n", ret );
4779 for (i = 0; i < 24; i++) ok( dib_bits[i] == data[i + 16], "%d: got %08x\n", i, dib_bits[i] );
4780 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4781 memset( dib_bits, 0xaa, 64 * 4 );
4783 info->bmiHeader.biHeight = 16;
4784 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4785 ok( ret == 7, "got %d\n", ret );
4786 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4787 for (i = 8; i < 64; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4788 memset( dib_bits, 0xaa, 64 * 4 );
4790 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 8, 0, 6, 1, 12, data, info, DIB_RGB_COLORS );
4791 ok( ret == 12, "got %d\n", ret );
4792 for (i = 0; i < 40; i++) ok( dib_bits[i] == data[i + 56], "%d: got %08x\n", i, dib_bits[i] );
4793 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4794 memset( dib_bits, 0xaa, 64 * 4 );
4796 ret = SetDIBitsToDevice( hdc, 0, -4, 8, 8, 0, 3, 1, 12, data, info, DIB_RGB_COLORS );
4797 ok( ret == 10, "got %d\n", ret );
4798 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4799 for (i = 32; i < 64; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4800 memset( dib_bits, 0xaa, 64 * 4 );
4802 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, -3, 1, 12, data, info, DIB_RGB_COLORS );
4803 ok( ret == 4, "got %d\n", ret );
4804 for (i = 0; i < 32; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4805 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4806 memset( dib_bits, 0xaa, 64 * 4 );
4808 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 5, 0, -2, 1, 12, data, info, DIB_RGB_COLORS );
4809 ok( ret == 2, "got %d\n", ret );
4810 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4811 for (i = 32; i < 48; i++) ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4812 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4813 memset( dib_bits, 0xaa, 64 * 4 );
4815 info->bmiHeader.biHeight = 5;
4816 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 2, 2, data, info, DIB_RGB_COLORS );
4817 ok( ret == 2, "got %d\n", ret );
4818 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4819 for (i = 16; i < 32; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4820 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4821 memset( dib_bits, 0xaa, 64 * 4 );
4823 ret = SetDIBitsToDevice( hdc, 3, 3, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4824 ok( ret == 3, "got %d\n", ret );
4825 for (i = 0; i < 64; i++)
4826 if (i == 27 || i == 28 || i == 35 || i == 36)
4827 ok( dib_bits[i] == data[i - 18], "%d: got %08x\n", i, dib_bits[i] );
4829 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4830 memset( dib_bits, 0xaa, 64 * 4 );
4832 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4833 ok( ret == 5, "got %d\n", ret );
4834 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4835 memset( dib_bits, 0xaa, 64 * 4 );
4837 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4838 ok( ret == 0, "got %d\n", ret );
4839 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4840 memset( dib_bits, 0xaa, 64 * 4 );
4842 SetMapMode( hdc, MM_ANISOTROPIC );
4843 SetWindowExtEx( hdc, 3, 3, NULL );
4844 ret = SetDIBitsToDevice( hdc, 2, 2, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4845 ok( ret == 3, "got %d\n", ret );
4846 for (i = 0; i < 64; i++)
4847 if (i == 41 || i == 42 || i == 49 || i == 50)
4848 ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4850 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4851 memset( dib_bits, 0xaa, 64 * 4 );
4853 SetWindowExtEx( hdc, -1, -1, NULL );
4854 ret = SetDIBitsToDevice( hdc, 2, 2, 4, 4, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4855 ok( ret == 4, "got %d\n", ret );
4856 for (i = 0; i < 64; i++)
4857 if (i == 48 || i == 49 || i == 56 || i == 57)
4858 ok( dib_bits[i] == data[i - 37], "%d: got %08x\n", i, dib_bits[i] );
4860 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4861 memset( dib_bits, 0xaa, 64 * 4 );
4862 SetMapMode( hdc, MM_TEXT );
4866 pSetLayout( hdc, LAYOUT_RTL );
4867 ret = SetDIBitsToDevice( hdc, 1, 2, 3, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4868 ok( ret == 3, "got %d\n", ret );
4869 for (i = 0; i < 64; i++)
4870 if (i == 36 || i == 37 || i == 38 || i == 44 || i == 45 || i == 46)
4871 ok( dib_bits[i] == data[i - 27], "%d: got %08x\n", i, dib_bits[i] );
4873 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4874 memset( dib_bits, 0xaa, 64 * 4 );
4875 pSetLayout( hdc, LAYOUT_LTR );
4879 info->bmiHeader.biHeight = -8;
4880 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4881 ok( ret == 8, "got %d\n", ret );
4882 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4883 memset( dib_bits, 0xaa, 64 * 4 );
4885 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4886 ok( ret == 5, "got %d\n", ret );
4887 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4888 for (i = 8; i < 48; i++) ok( dib_bits[i] == inverted_data[i + 80], "%d: got %08x\n", i, dib_bits[i] );
4889 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4890 memset( dib_bits, 0xaa, 64 * 4 );
4892 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 4, 1, 5, data, info, DIB_RGB_COLORS );
4893 ok( ret == 5, "got %d\n", ret );
4894 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4895 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4896 memset( dib_bits, 0xaa, 64 * 4 );
4898 info->bmiHeader.biHeight = -16;
4899 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4900 ok( ret == 12, "got %d\n", ret );
4901 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4902 for (i = 8; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4903 memset( dib_bits, 0xaa, 64 * 4 );
4905 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, 7, 1, 12, data, info, DIB_RGB_COLORS );
4906 ok( ret == 12, "got %d\n", ret );
4907 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4908 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4909 memset( dib_bits, 0xaa, 64 * 4 );
4911 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 4, 12, data, info, DIB_RGB_COLORS );
4912 ok( ret == 12, "got %d\n", ret );
4913 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4914 for (i = 32; i < 64; i++) ok( dib_bits[i] == inverted_data[i], "%d: got %08x\n", i, dib_bits[i] );
4915 memset( dib_bits, 0xaa, 64 * 4 );
4917 ret = SetDIBitsToDevice( hdc, 0, -3, 8, 8, 0, 2, 4, 12, data, info, DIB_RGB_COLORS );
4918 ok( ret == 12, "got %d\n", ret );
4919 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4920 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4921 memset( dib_bits, 0xaa, 64 * 4 );
4923 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, -2, 4, 12, data, info, DIB_RGB_COLORS );
4924 ok( ret == 12, "got %d\n", ret );
4925 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4926 for (i = 24; i < 40; i++) ok( dib_bits[i] == inverted_data[i + 8], "%d: got %08x\n", i, dib_bits[i] );
4927 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4928 memset( dib_bits, 0xaa, 64 * 4 );
4930 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 5, 12, data, info, DIB_RGB_COLORS );
4931 ok( ret == 12, "got %d\n", ret );
4932 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4933 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4934 memset( dib_bits, 0xaa, 64 * 4 );
4936 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4937 ok( ret == 12, "got %d\n", ret );
4938 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4939 memset( dib_bits, 0xaa, 64 * 4 );
4941 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -2, -4, 0, 12, data, info, DIB_RGB_COLORS );
4942 ok( ret == 12, "got %d\n", ret );
4943 for (i = 0; i < 64; i++)
4944 if (i == 31 || i == 39 || i == 47 || i == 55 || i == 63)
4945 ok( dib_bits[i] == inverted_data[i + 1], "%d: got %08x\n", i, dib_bits[i] );
4947 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4948 memset( dib_bits, 0xaa, 64 * 4 );
4950 info->bmiHeader.biHeight = -5;
4951 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4952 ok( ret == 2, "got %d\n", ret );
4953 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4954 for (i = 8; i < 24; i++) ok( dib_bits[i] == inverted_data[i + 104], "%d: got %08x\n", i, dib_bits[i] );
4955 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4956 memset( dib_bits, 0xaa, 64 * 4 );
4958 ret = SetDIBitsToDevice( hdc, 5, 4, 2, 2, 6, 3, 1, 5, data, info, DIB_RGB_COLORS );
4959 ok( ret == 5, "got %d\n", ret );
4960 for (i = 0; i < 64; i++)
4961 if (i == 21 || i == 22 || i == 29 || i == 30)
4962 ok( dib_bits[i] == inverted_data[i + 89], "%d: got %08x\n", i, dib_bits[i] );
4964 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4965 memset( dib_bits, 0xaa, 64 * 4 );
4967 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4968 ok( ret == 5, "got %d\n", ret );
4969 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4970 memset( dib_bits, 0xaa, 64 * 4 );
4972 info->bmiHeader.biHeight = -8;
4974 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4975 DeleteObject( SelectObject( hdc, dib ));
4976 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4980 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4981 ok( ret == 8, "got %d\n", ret );
4982 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4983 memset( dib_bits, 0xaa, 64 * 4 );
4985 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4986 ok( ret == 5, "got %d\n", ret );
4987 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4988 for (i = 16; i < 56; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4989 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4990 memset( dib_bits, 0xaa, 64 * 4 );
4992 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 3, 0, 2, 1, 5, data, info, DIB_RGB_COLORS );
4993 ok( ret == 5, "got %d\n", ret );
4994 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4995 for (i = 24; i < 48; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4996 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4997 memset( dib_bits, 0xaa, 64 * 4 );
4999 info->bmiHeader.biHeight = -16;
5000 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
5001 ok( ret == 12, "got %d\n", ret );
5002 for (i = 0; i < 56; i++) ok( dib_bits[i] == data[i + 40], "%d: got %08x\n", i, dib_bits[i] );
5003 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5004 memset( dib_bits, 0xaa, 64 * 4 );
5006 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -1, -8, 0, 12, data, info, DIB_RGB_COLORS );
5007 ok( ret == 12, "got %d\n", ret );
5008 for (i = 0; i < 64; i++)
5009 if (i == 6 || i == 7)
5010 ok( dib_bits[i] == data[i + 82], "%d: got %08x\n", i, dib_bits[i] );
5012 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5013 memset( dib_bits, 0xaa, 64 * 4 );
5015 info->bmiHeader.biHeight = -5;
5016 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
5017 ok( ret == 2, "got %d\n", ret );
5018 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5019 for (i = 40; i < 56; i++) ok( dib_bits[i] == data[i - 40], "%d: got %08x\n", i, dib_bits[i] );
5020 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5021 memset( dib_bits, 0xaa, 64 * 4 );
5023 ret = SetDIBitsToDevice( hdc, 7, 2, 8, 8, 1, 0, 0, 5, data, info, DIB_RGB_COLORS );
5024 ok( ret == 5, "got %d\n", ret );
5025 for (i = 0; i < 64; i++)
5026 if (i == 47 || i == 55 || i == 63)
5027 ok( dib_bits[i] == data[i - 46], "%d: got %08x\n", i, dib_bits[i] );
5029 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5030 memset( dib_bits, 0xaa, 64 * 4 );
5032 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5033 ok( ret == 5, "got %d\n", ret );
5034 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5035 memset( dib_bits, 0xaa, 64 * 4 );
5039 info->bmiHeader.biHeight = 8;
5040 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5041 ok( ret == 8, "got %d\n", ret );
5042 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
5043 memset( dib_bits, 0xaa, 64 * 4 );
5045 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
5046 ok( ret == 5, "got %d\n", ret );
5047 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5048 for (i = 16; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
5049 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5050 memset( dib_bits, 0xaa, 64 * 4 );
5052 info->bmiHeader.biHeight = 16;
5053 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
5054 ok( ret == 7, "got %d\n", ret );
5055 for (i = 0; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
5056 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5057 memset( dib_bits, 0xaa, 64 * 4 );
5059 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, 0, -4, 1, 12, data, info, DIB_RGB_COLORS );
5060 ok( ret == 3, "got %d\n", ret );
5061 for (i = 0; i < 64; i++)
5062 if ((i >= 36 && i <= 39) || (i >= 44 && i <= 47) || (i >= 52 && i <= 55))
5063 ok( dib_bits[i] == inverted_data[i + 68], "%d: got %08x\n", i, dib_bits[i] );
5065 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5066 memset( dib_bits, 0xaa, 64 * 4 );
5068 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, -30, -30, 1, 12, data, info, DIB_RGB_COLORS );
5069 ok( ret == 0, "got %d\n", ret );
5070 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5071 memset( dib_bits, 0xaa, 64 * 4 );
5073 ret = SetDIBitsToDevice( hdc, 5, -5, 8, 16, -2, -4, 4, 12, data, info, DIB_RGB_COLORS );
5074 ok( ret == 8, "got %d\n", ret );
5075 for (i = 0; i < 64; i++)
5076 if (i == 7 || i == 15 || i == 23)
5077 ok( dib_bits[i] == inverted_data[i + 97], "%d: got %08x\n", i, dib_bits[i] );
5079 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5080 memset( dib_bits, 0xaa, 64 * 4 );
5082 info->bmiHeader.biHeight = 5;
5083 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
5084 ok( ret == 2, "got %d\n", ret );
5085 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5086 for (i = 40; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
5087 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5088 memset( dib_bits, 0xaa, 64 * 4 );
5090 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5091 ok( ret == 5, "got %d\n", ret );
5092 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5093 memset( dib_bits, 0xaa, 64 * 4 );
5095 /* handling of partial color table */
5097 info->bmiHeader.biHeight = -8;
5098 info->bmiHeader.biBitCount = 8;
5099 info->bmiHeader.biClrUsed = 137;
5100 for (i = 0; i < 256; i++)
5102 info->bmiColors[i].rgbRed = 255 - i;
5103 info->bmiColors[i].rgbGreen = i * 2;
5104 info->bmiColors[i].rgbBlue = i;
5105 info->bmiColors[i].rgbReserved = 0;
5107 for (i = 0; i < 64; i++) ((BYTE *)data)[i] = i * 4 + 1;
5108 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5109 ok( ret == 8, "got %d\n", ret );
5110 for (i = 0; i < 64; i++)
5112 int idx = i * 4 + 1;
5113 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : (info->bmiColors[idx].rgbRed << 16 |
5114 info->bmiColors[idx].rgbGreen << 8 |
5115 info->bmiColors[idx].rgbBlue);
5116 ok( dib_bits[i] == expect, "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
5118 memset( dib_bits, 0xaa, 64 * 4 );
5120 /* handling of DIB_PAL_COLORS */
5122 pal->palVersion = 0x300;
5123 pal->palNumEntries = 137;
5124 info->bmiHeader.biClrUsed = 221;
5125 for (i = 0; i < 256; i++)
5127 palent[i].peRed = i * 2;
5128 palent[i].peGreen = 255 - i;
5129 palent[i].peBlue = i;
5131 palette = CreatePalette( pal );
5132 ok( palette != 0, "palette creation failed\n" );
5133 SelectPalette( hdc, palette, FALSE );
5134 for (i = 0; i < 256; i++) ((WORD *)info->bmiColors)[i] = 255 - i;
5135 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_PAL_COLORS );
5136 ok( ret == 8, "got %d\n", ret );
5137 for (i = 0; i < 64; i++)
5139 int idx = i * 4 + 1;
5140 int ent = (255 - idx) % pal->palNumEntries;
5141 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 :
5142 (palent[ent].peRed << 16 | palent[ent].peGreen << 8 | palent[ent].peBlue);
5143 ok( dib_bits[i] == expect || broken(dib_bits[i] == 0),
5144 "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
5146 memset( dib_bits, 0xaa, 64 * 4 );
5149 DeleteObject( dib );
5150 DeleteObject( palette );
5151 HeapFree( GetProcessHeap(), 0, info );
5154 static void test_SetDIBitsToDevice_RLE8(void)
5158 HDC hdc = CreateCompatibleDC( 0 );
5159 BYTE rle8_data[20] = { 0x04, 0x02, 0x03, 0xf0, 0x00, 0x00, /* 2, 2, 2, 2, f0, f0, f0, <eol> */
5160 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
5161 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
5162 0x00, 0x01 }; /* <eod> */
5165 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
5166 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5167 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5168 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
5169 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5170 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5171 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5172 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
5173 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5174 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5175 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5176 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5177 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
5178 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5179 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5180 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
5182 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
5184 info->bmiHeader.biSize = sizeof(info->bmiHeader);
5185 info->bmiHeader.biWidth = 8;
5186 info->bmiHeader.biHeight = 8;
5187 info->bmiHeader.biPlanes = 1;
5188 info->bmiHeader.biBitCount = 32;
5189 info->bmiHeader.biCompression = BI_RGB;
5191 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5192 memset( dib_bits, 0xaa, 64 * 4 );
5193 SelectObject( hdc, dib );
5195 info->bmiHeader.biBitCount = 8;
5196 info->bmiHeader.biCompression = BI_RLE8;
5197 info->bmiHeader.biSizeImage = sizeof(rle8_data);
5199 for (i = 0; i < 256; i++)
5201 info->bmiColors[i].rgbRed = i;
5202 info->bmiColors[i].rgbGreen = i;
5203 info->bmiColors[i].rgbBlue = i;
5204 info->bmiColors[i].rgbReserved = 0;
5207 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5208 ok( ret == 8, "got %d\n", ret );
5209 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5210 memset( dib_bits, 0xaa, 64 * 4 );
5212 /* startscan and lines are ignored, unless lines == 0 */
5213 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 8, rle8_data, info, DIB_RGB_COLORS );
5214 ok( ret == 8, "got %d\n", ret );
5215 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5216 memset( dib_bits, 0xaa, 64 * 4 );
5218 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 1, rle8_data, info, DIB_RGB_COLORS );
5219 ok( ret == 8, "got %d\n", ret );
5220 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5221 memset( dib_bits, 0xaa, 64 * 4 );
5223 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 0, rle8_data, info, DIB_RGB_COLORS );
5224 ok( ret == 0, "got %d\n", ret );
5225 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5226 memset( dib_bits, 0xaa, 64 * 4 );
5228 info->bmiHeader.biWidth = 2;
5229 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5230 ok( ret == 8, "got %d\n", ret );
5231 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5232 memset( dib_bits, 0xaa, 64 * 4 );
5234 info->bmiHeader.biWidth = 8;
5235 info->bmiHeader.biHeight = 2;
5236 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5237 ok( ret == 2, "got %d\n", ret );
5238 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5239 memset( dib_bits, 0xaa, 64 * 4 );
5241 info->bmiHeader.biHeight = 9;
5242 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5243 ok( ret == 9, "got %d\n", ret );
5244 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5245 memset( dib_bits, 0xaa, 64 * 4 );
5247 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5248 ok( ret == 9, "got %d\n", ret );
5249 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5250 memset( dib_bits, 0xaa, 64 * 4 );
5252 info->bmiHeader.biHeight = 8;
5253 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 9, rle8_data, info, DIB_RGB_COLORS );
5254 ok( ret == 8, "got %d\n", ret );
5255 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5256 memset( dib_bits, 0xaa, 64 * 4 );
5258 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5259 ok( ret == 8, "got %d\n", ret );
5260 for (i = 0; i < 40; i++) ok( dib_bits[i] == bottom_up[i + 24], "%d: got %08x\n", i, dib_bits[i] );
5261 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5262 memset( dib_bits, 0xaa, 64 * 4 );
5264 ret = SetDIBitsToDevice( hdc, 0, 3, 4, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5265 ok( ret == 8, "got %d\n", ret );
5266 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5267 for (i = 8; i < 40; i++)
5268 if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5269 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5270 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5271 memset( dib_bits, 0xaa, 64 * 4 );
5273 ret = SetDIBitsToDevice( hdc, 3, 3, 8, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5274 ok( ret == 8, "got %d\n", ret );
5275 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5276 for (i = 8; i < 40; i++)
5277 if ((i & 7) < 3) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5278 else ok( dib_bits[i] == bottom_up[i - 11], "%d: got %08x\n", i, dib_bits[i] );
5279 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5280 memset( dib_bits, 0xaa, 64 * 4 );
5282 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 4, 2, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5283 ok( ret == 8, "got %d\n", ret );
5284 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5285 for (i = 8; i < 40; i++)
5286 if ((i & 7) < 2) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5287 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5288 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5289 memset( dib_bits, 0xaa, 64 * 4 );
5291 info->bmiHeader.biWidth = 37;
5292 info->bmiHeader.biHeight = 37;
5293 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
5294 ok( ret == 37, "got %d\n", ret );
5295 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5296 for (i = 24; i < 64; i++)
5297 if (i == 52) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
5298 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5299 else ok( dib_bits[i] == bottom_up[i - 20], "%d: got %08x\n", i, dib_bits[i] );
5300 memset( dib_bits, 0xaa, 64 * 4 );
5302 /* top-down compressed dibs are invalid */
5303 info->bmiHeader.biWidth = 8;
5304 info->bmiHeader.biHeight = -8;
5305 SetLastError( 0xdeadbeef );
5306 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5307 ok( ret == 0, "got %d\n", ret );
5308 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
5312 info->bmiHeader.biHeight = -8;
5313 info->bmiHeader.biBitCount = 32;
5314 info->bmiHeader.biCompression = BI_RGB;
5315 info->bmiHeader.biSizeImage = 0;
5317 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5318 memset( dib_bits, 0xaa, 16 * 16 * 4 );
5319 DeleteObject( SelectObject( hdc, dib ));
5321 info->bmiHeader.biHeight = 8;
5322 info->bmiHeader.biBitCount = 8;
5323 info->bmiHeader.biCompression = BI_RLE8;
5324 info->bmiHeader.biSizeImage = sizeof(rle8_data);
5326 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5327 ok( ret == 8, "got %d\n", ret );
5328 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5329 memset( dib_bits, 0xaa, 64 * 4 );
5331 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5332 ok( ret == 8, "got %d\n", ret );
5333 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5334 memset( dib_bits, 0xaa, 64 * 4 );
5336 info->bmiHeader.biHeight = 4;
5337 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5338 ok( ret == 4, "got %d\n", ret );
5339 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5340 memset( dib_bits, 0xaa, 64 * 4 );
5342 info->bmiHeader.biHeight = 9;
5343 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5344 ok( ret == 9, "got %d\n", ret );
5345 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5346 memset( dib_bits, 0xaa, 64 * 4 );
5348 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5349 ok( ret == 9, "got %d\n", ret );
5350 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5351 memset( dib_bits, 0xaa, 64 * 4 );
5353 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 6, 2, 2, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5354 ok( ret == 9, "got %d\n", ret );
5355 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5356 for (i = 24; i < 64; i++) ok( dib_bits[i] == top_down[i - 24], "%d: got %08x\n", i, dib_bits[i] );
5357 memset( dib_bits, 0xaa, 64 * 4 );
5359 info->bmiHeader.biWidth = 37;
5360 info->bmiHeader.biHeight = 37;
5361 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
5362 ok( ret == 37, "got %d\n", ret );
5363 for (i = 0; i < 40; i++)
5364 if (i == 12) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
5365 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5366 else ok( dib_bits[i] == top_down[i + 28], "%d: got %08x\n", i, dib_bits[i] );
5367 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5368 memset( dib_bits, 0xaa, 64 * 4 );
5371 DeleteObject( dib );
5372 HeapFree( GetProcessHeap(), 0, info );
5379 hdll = GetModuleHandle("gdi32.dll");
5380 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
5381 pGdiGradientFill = (void*)GetProcAddress(hdll, "GdiGradientFill");
5382 pSetLayout = (void*)GetProcAddress(hdll, "SetLayout");
5384 test_createdibitmap();
5387 test_mono_dibsection();
5390 test_GetDIBits_selected_DIB(1);
5391 test_GetDIBits_selected_DIB(4);
5392 test_GetDIBits_selected_DIB(8);
5393 test_GetDIBits_selected_DDB(TRUE);
5394 test_GetDIBits_selected_DDB(FALSE);
5396 test_GetDIBits_BI_BITFIELDS();
5397 test_select_object();
5398 test_CreateBitmap();
5401 test_StretchDIBits();
5402 test_GdiAlphaBlend();
5403 test_GdiGradientFill();
5405 test_bitmapinfoheadersize();
5408 test_GetDIBits_top_down(16);
5409 test_GetDIBits_top_down(24);
5410 test_GetDIBits_top_down(32);
5411 test_GetSetDIBits_rtl();
5412 test_GetDIBits_scanlines();
5414 test_SetDIBits_RLE4();
5415 test_SetDIBits_RLE8();
5416 test_SetDIBitsToDevice();
5417 test_SetDIBitsToDevice_RLE8();