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 Rectangle(hdcSrc, 0, 0, 1, 1); /* A null operation to ensure dibs are coerced to X11 */
2751 BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
2752 ok(expected == *dstBuffer,
2753 "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2754 dwRop, expected, *dstBuffer, line);
2757 static void test_BitBlt(void)
2759 HBITMAP bmpDst, bmpSrc;
2760 HBITMAP oldDst, oldSrc;
2761 HDC hdcScreen, hdcDst, hdcSrc;
2762 UINT32 *dstBuffer, *srcBuffer;
2763 HBRUSH hBrush, hOldBrush;
2764 BITMAPINFO bitmapInfo;
2766 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2767 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2768 bitmapInfo.bmiHeader.biWidth = 1;
2769 bitmapInfo.bmiHeader.biHeight = 1;
2770 bitmapInfo.bmiHeader.biPlanes = 1;
2771 bitmapInfo.bmiHeader.biBitCount = 32;
2772 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2773 bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2775 hdcScreen = CreateCompatibleDC(0);
2776 hdcDst = CreateCompatibleDC(hdcScreen);
2777 hdcSrc = CreateCompatibleDC(hdcDst);
2779 /* Setup the destination dib section */
2780 bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
2782 oldDst = SelectObject(hdcDst, bmpDst);
2784 hBrush = CreateSolidBrush(0x012345678);
2785 hOldBrush = SelectObject(hdcDst, hBrush);
2787 /* Setup the source dib section */
2788 bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
2790 oldSrc = SelectObject(hdcSrc, bmpSrc);
2792 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2793 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2794 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2795 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2796 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2797 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2798 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2799 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2800 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2801 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2802 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2803 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2804 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2805 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2806 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2809 SelectObject(hdcSrc, oldSrc);
2810 DeleteObject(bmpSrc);
2813 SelectObject(hdcDst, hOldBrush);
2814 DeleteObject(hBrush);
2815 SelectObject(hdcDst, oldDst);
2816 DeleteObject(bmpDst);
2820 DeleteDC(hdcScreen);
2823 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2824 DWORD dwRop, UINT32 expected, int line)
2826 *srcBuffer = 0xFEDCBA98;
2827 *dstBuffer = 0x89ABCDEF;
2828 StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
2829 ok(expected == *dstBuffer,
2830 "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2831 dwRop, expected, *dstBuffer, line);
2834 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, BITMAPINFO *dst_info, UINT32 *dstBuffer, UINT32 *srcBuffer,
2835 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2836 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2837 UINT32 *expected, int line)
2839 int dst_size = get_dib_image_size( dst_info );
2841 memset(dstBuffer, 0, dst_size);
2842 StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2843 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
2844 ok(memcmp(dstBuffer, expected, dst_size) == 0,
2845 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2846 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2847 expected[0], expected[1], expected[2], expected[3],
2848 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2849 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2850 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2853 static void test_StretchBlt(void)
2855 HBITMAP bmpDst, bmpSrc;
2856 HBITMAP oldDst, oldSrc;
2857 HDC hdcScreen, hdcDst, hdcSrc;
2858 UINT32 *dstBuffer, *srcBuffer;
2859 HBRUSH hBrush, hOldBrush;
2860 BITMAPINFO biDst, biSrc;
2861 UINT32 expected[256];
2864 memset(&biDst, 0, sizeof(BITMAPINFO));
2865 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2866 biDst.bmiHeader.biWidth = 16;
2867 biDst.bmiHeader.biHeight = -16;
2868 biDst.bmiHeader.biPlanes = 1;
2869 biDst.bmiHeader.biBitCount = 32;
2870 biDst.bmiHeader.biCompression = BI_RGB;
2871 memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
2873 hdcScreen = CreateCompatibleDC(0);
2874 hdcDst = CreateCompatibleDC(hdcScreen);
2875 hdcSrc = CreateCompatibleDC(hdcDst);
2878 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2880 oldDst = SelectObject(hdcDst, bmpDst);
2882 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2884 oldSrc = SelectObject(hdcSrc, bmpSrc);
2886 hBrush = CreateSolidBrush(0x012345678);
2887 hOldBrush = SelectObject(hdcDst, hBrush);
2889 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2890 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2891 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2892 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2893 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2894 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2895 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2896 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2897 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2898 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2899 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2900 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2901 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2902 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2903 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2905 SelectObject(hdcDst, hOldBrush);
2906 DeleteObject(hBrush);
2908 /* Top-down to top-down tests */
2909 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2910 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2912 memset( expected, 0, get_dib_image_size( &biDst ) );
2913 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2914 expected[16] = 0xFEDCBA98, expected[17] = 0x76543210;
2915 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2916 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2918 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2919 expected[16] = 0x00000000, expected[17] = 0x00000000;
2920 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2921 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
2923 expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
2924 expected[16] = 0xCAFED00D, expected[17] = 0xCAFED00D;
2925 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2926 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
2928 /* This is an example of the dst width (height) == 1 exception, explored below */
2929 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2930 expected[16] = 0x00000000, expected[17] = 0x00000000;
2931 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2932 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
2934 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2935 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
2936 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2937 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2939 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2940 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
2941 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2942 1, 1, -2, -2, 0, 0, 2, 2, expected, __LINE__);
2944 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2945 expected[16] = 0x00000000, expected[17] = 0x00000000;
2946 todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2947 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
2949 expected[0] = 0x00000000, expected[1] = 0x00000000;
2950 expected[16] = 0x00000000, expected[17] = 0xCAFED00D, expected[18] = 0xFEEDFACE;
2951 expected[32] = 0x00000000, expected[33] = 0xFEDCBA98, expected[34] = 0x76543210;
2953 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2954 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2956 /* when dst width is 1 merge src width - 1 pixels */
2957 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
2958 srcBuffer[0] = 0x0000ff00, srcBuffer[1] = 0x0000f0f0, srcBuffer[2] = 0x0000cccc, srcBuffer[3] = 0x0000aaaa;
2959 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2961 memset( expected, 0, get_dib_image_size( &biDst ) );
2962 expected[0] = srcBuffer[0];
2963 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2964 0, 0, 1, 1, 0, 0, 2, 1, expected, __LINE__);
2966 expected[0] = srcBuffer[0] & srcBuffer[1];
2967 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2968 0, 0, 1, 1, 0, 0, 3, 1, expected, __LINE__);
2970 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
2971 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2972 0, 0, 1, 1, 0, 0, 4, 1, expected, __LINE__);
2974 /* this doesn't happen if the src width is -ve */
2975 expected[0] = srcBuffer[1] & srcBuffer[2];
2976 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2977 0, 0, 1, 1, 2, 0, -2, 1, expected, __LINE__);
2979 /* when dst width > 1 behaviour reverts to what one would expect */
2980 expected[0] = srcBuffer[0] & srcBuffer[1], expected[1] = srcBuffer[2] & srcBuffer[3];
2981 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2982 0, 0, 2, 1, 0, 0, 4, 1, expected, __LINE__);
2984 /* similarly in the vertical direction */
2985 memset( expected, 0, get_dib_image_size( &biDst ) );
2986 expected[0] = srcBuffer[0];
2987 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2988 0, 0, 1, 1, 0, 0, 1, 2, expected, __LINE__);
2990 /* check that it's the dst size in device units that needs to be 1 */
2991 SetMapMode( hdcDst, MM_ISOTROPIC );
2992 SetWindowExtEx( hdcDst, 200, 200, NULL );
2993 SetViewportExtEx( hdcDst, 100, 100, NULL );
2995 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
2996 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2997 0, 0, 2, 2, 0, 0, 4, 1, expected, __LINE__);
2998 SetMapMode( hdcDst, MM_TEXT );
3000 SelectObject(hdcDst, oldDst);
3001 DeleteObject(bmpDst);
3003 /* Top-down to bottom-up tests */
3004 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
3005 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3006 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
3008 biDst.bmiHeader.biHeight = 16;
3009 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3011 oldDst = SelectObject(hdcDst, bmpDst);
3013 memset( expected, 0, get_dib_image_size( &biDst ) );
3015 expected[224] = 0xFEDCBA98, expected[225] = 0x76543210;
3016 expected[240] = 0xCAFED00D, expected[241] = 0xFEEDFACE;
3017 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3018 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3020 expected[224] = 0xFEEDFACE, expected[225] = 0xCAFED00D;
3021 expected[240] = 0x76543210, expected[241] = 0xFEDCBA98;
3022 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3023 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3025 SelectObject(hdcSrc, oldSrc);
3026 DeleteObject(bmpSrc);
3028 /* Bottom-up to bottom-up tests */
3029 biSrc.bmiHeader.biHeight = 16;
3030 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
3032 srcBuffer[224] = 0xCAFED00D, srcBuffer[225] = 0xFEEDFACE;
3033 srcBuffer[240] = 0xFEDCBA98, srcBuffer[241] = 0x76543210;
3034 oldSrc = SelectObject(hdcSrc, bmpSrc);
3036 memset( expected, 0, get_dib_image_size( &biDst ) );
3038 expected[224] = 0xCAFED00D, expected[225] = 0xFEEDFACE;
3039 expected[240] = 0xFEDCBA98, expected[241] = 0x76543210;
3040 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3041 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3043 expected[224] = 0x76543210, expected[225] = 0xFEDCBA98;
3044 expected[240] = 0xFEEDFACE, expected[241] = 0xCAFED00D;
3045 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3046 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3048 SelectObject(hdcDst, oldDst);
3049 DeleteObject(bmpDst);
3051 /* Bottom-up to top-down tests */
3052 biDst.bmiHeader.biHeight = -16;
3053 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3055 oldDst = SelectObject(hdcDst, bmpDst);
3057 memset( expected, 0, get_dib_image_size( &biDst ) );
3058 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3059 expected[16] = 0xCAFED00D, expected[17] = 0xFEEDFACE;
3060 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3061 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3063 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3064 expected[16] = 0x76543210, expected[17] = 0xFEDCBA98;
3065 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3066 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3068 SelectObject(hdcSrc, oldSrc);
3069 DeleteObject(bmpSrc);
3071 biSrc.bmiHeader.biHeight = -2;
3072 biSrc.bmiHeader.biBitCount = 24;
3073 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
3074 oldSrc = SelectObject(hdcSrc, bmpSrc);
3076 memset( expected, 0, get_dib_image_size( &biDst ) );
3077 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3078 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
3079 memcpy(dstBuffer, expected, 4 * sizeof(*dstBuffer));
3080 StretchBlt(hdcSrc, 0, 0, 4, 1, hdcDst, 0, 0, 4, 1, SRCCOPY );
3081 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
3082 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3083 expected[0] = 0x00EDFACE, expected[1] = 0x00FED00D;
3084 expected[2] = 0x00543210, expected[3] = 0x00DCBA98;
3085 ok(!memcmp(dstBuffer, expected, 16),
3086 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3087 expected[0], expected[1], expected[2], expected[3],
3088 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3090 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3091 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
3092 memcpy(srcBuffer, expected, 4 * sizeof(*dstBuffer));
3093 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
3094 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3095 expected[0] = 0x00EDFACE, expected[1] = 0x00D00DFE;
3096 expected[2] = 0x0010CAFE, expected[3] = 0x00765432;
3097 ok(!memcmp(dstBuffer, expected, 16),
3098 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3099 expected[0], expected[1], expected[2], expected[3],
3100 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3102 SelectObject(hdcSrc, oldSrc);
3103 DeleteObject(bmpSrc);
3105 biSrc.bmiHeader.biBitCount = 1;
3106 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
3107 oldSrc = SelectObject(hdcSrc, bmpSrc);
3108 *((DWORD *)colors + 0) = 0x123456;
3109 *((DWORD *)colors + 1) = 0x335577;
3110 SetDIBColorTable( hdcSrc, 0, 2, colors );
3111 srcBuffer[0] = 0x55555555;
3112 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
3113 SetTextColor( hdcDst, 0 );
3114 SetBkColor( hdcDst, 0 );
3115 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3116 expected[0] = expected[2] = 0x00123456;
3117 expected[1] = expected[3] = 0x00335577;
3118 ok(!memcmp(dstBuffer, expected, 16),
3119 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3120 expected[0], expected[1], expected[2], expected[3],
3121 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3123 SelectObject(hdcSrc, oldSrc);
3124 DeleteObject(bmpSrc);
3126 bmpSrc = CreateBitmap( 16, 16, 1, 1, 0 );
3127 oldSrc = SelectObject(hdcSrc, bmpSrc);
3128 SetPixel( hdcSrc, 0, 0, 0 );
3129 SetPixel( hdcSrc, 1, 0, 0xffffff );
3130 SetPixel( hdcSrc, 2, 0, 0xffffff );
3131 SetPixel( hdcSrc, 3, 0, 0 );
3132 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
3133 SetTextColor( hdcDst, RGB(0x22,0x44,0x66) );
3134 SetBkColor( hdcDst, RGB(0x65,0x43,0x21) );
3135 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3136 expected[0] = expected[3] = 0x00224466;
3137 expected[1] = expected[2] = 0x00654321;
3138 ok(!memcmp(dstBuffer, expected, 16),
3139 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3140 expected[0], expected[1], expected[2], expected[3],
3141 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3143 SelectObject(hdcSrc, oldSrc);
3144 DeleteObject(bmpSrc);
3148 SelectObject(hdcDst, oldDst);
3149 DeleteObject(bmpDst);
3152 DeleteDC(hdcScreen);
3155 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3156 DWORD dwRop, UINT32 expected, int line)
3158 const UINT32 buffer[2] = { 0xFEDCBA98, 0 };
3159 BITMAPINFO bitmapInfo;
3161 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3162 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3163 bitmapInfo.bmiHeader.biWidth = 2;
3164 bitmapInfo.bmiHeader.biHeight = 1;
3165 bitmapInfo.bmiHeader.biPlanes = 1;
3166 bitmapInfo.bmiHeader.biBitCount = 32;
3167 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3168 bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer);
3170 *dstBuffer = 0x89ABCDEF;
3172 StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop);
3173 ok(expected == *dstBuffer,
3174 "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
3175 dwRop, expected, *dstBuffer, line);
3178 static void check_StretchDIBits_stretch(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3179 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
3180 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
3181 UINT32 expected[4], int line)
3183 BITMAPINFO bitmapInfo;
3185 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3186 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3187 bitmapInfo.bmiHeader.biWidth = 2;
3188 bitmapInfo.bmiHeader.biHeight = -2;
3189 bitmapInfo.bmiHeader.biPlanes = 1;
3190 bitmapInfo.bmiHeader.biBitCount = 32;
3191 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3193 memset(dstBuffer, 0, 16);
3194 StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
3195 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3196 srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
3197 ok(memcmp(dstBuffer, expected, 16) == 0,
3198 "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
3199 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
3200 expected[0], expected[1], expected[2], expected[3],
3201 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
3202 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3203 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
3206 static void test_StretchDIBits(void)
3210 HDC hdcScreen, hdcDst;
3211 UINT32 *dstBuffer, srcBuffer[4];
3212 HBRUSH hBrush, hOldBrush;
3216 memset(&biDst, 0, sizeof(BITMAPINFO));
3217 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3218 biDst.bmiHeader.biWidth = 2;
3219 biDst.bmiHeader.biHeight = -2;
3220 biDst.bmiHeader.biPlanes = 1;
3221 biDst.bmiHeader.biBitCount = 32;
3222 biDst.bmiHeader.biCompression = BI_RGB;
3224 hdcScreen = CreateCompatibleDC(0);
3225 hdcDst = CreateCompatibleDC(hdcScreen);
3228 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3230 oldDst = SelectObject(hdcDst, bmpDst);
3232 hBrush = CreateSolidBrush(0x012345678);
3233 hOldBrush = SelectObject(hdcDst, hBrush);
3235 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3236 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3237 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3238 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3239 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3240 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3241 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3242 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3243 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3244 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3245 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3246 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3247 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3248 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3249 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3251 SelectObject(hdcDst, hOldBrush);
3252 DeleteObject(hBrush);
3254 /* Top-down destination tests */
3255 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3256 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
3258 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
3259 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
3260 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3261 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3263 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3264 expected[2] = 0x00000000, expected[3] = 0x00000000;
3265 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3266 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
3268 expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
3269 expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
3270 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3271 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
3273 expected[0] = 0x42441000, expected[1] = 0x00000000;
3274 expected[2] = 0x00000000, expected[3] = 0x00000000;
3275 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3276 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
3278 expected[0] = 0x00000000, expected[1] = 0x00000000;
3279 expected[2] = 0x00000000, expected[3] = 0x00000000;
3280 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3281 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3283 expected[0] = 0x00000000, expected[1] = 0x00000000;
3284 expected[2] = 0x00000000, expected[3] = 0x00000000;
3285 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3286 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3288 expected[0] = 0x00000000, expected[1] = 0x00000000;
3289 expected[2] = 0x00000000, expected[3] = 0x00000000;
3290 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3291 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
3293 expected[0] = 0x00000000, expected[1] = 0x00000000;
3294 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
3295 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3296 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3298 SelectObject(hdcDst, oldDst);
3299 DeleteObject(bmpDst);
3301 /* Bottom up destination tests */
3302 biDst.bmiHeader.biHeight = 2;
3303 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3305 oldDst = SelectObject(hdcDst, bmpDst);
3307 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3308 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
3309 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3310 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3313 SelectObject(hdcDst, oldDst);
3314 DeleteObject(bmpDst);
3317 DeleteDC(hdcScreen);
3320 static void test_GdiAlphaBlend(void)
3332 BLENDFUNCTION blend;
3334 if (!pGdiAlphaBlend)
3336 win_skip("GdiAlphaBlend() is not implemented\n");
3340 hdcNull = GetDC(NULL);
3341 hdcDst = CreateCompatibleDC(hdcNull);
3342 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
3343 hdcSrc = CreateCompatibleDC(hdcNull);
3345 bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3346 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3347 bmi->bmiHeader.biHeight = 20;
3348 bmi->bmiHeader.biWidth = 20;
3349 bmi->bmiHeader.biBitCount = 32;
3350 bmi->bmiHeader.biPlanes = 1;
3351 bmi->bmiHeader.biCompression = BI_RGB;
3352 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3353 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3355 oldDst = SelectObject(hdcDst, bmpDst);
3356 oldSrc = SelectObject(hdcSrc, bmpSrc);
3358 blend.BlendOp = AC_SRC_OVER;
3359 blend.BlendFlags = 0;
3360 blend.SourceConstantAlpha = 128;
3361 blend.AlphaFormat = 0;
3363 SetLastError(0xdeadbeef);
3364 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3365 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3367 SetLastError(0xdeadbeef);
3368 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3369 ok( !ret, "GdiAlphaBlend succeeded\n" );
3370 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3372 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3373 ok( !ret, "GdiAlphaBlend succeeded\n" );
3374 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend);
3375 ok( !ret, "GdiAlphaBlend succeeded\n" );
3376 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3377 ok( !ret, "GdiAlphaBlend succeeded\n" );
3378 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3379 ok( !ret, "GdiAlphaBlend succeeded\n" );
3381 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
3382 SetLastError(0xdeadbeef);
3383 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3384 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3385 SetLastError(0xdeadbeef);
3386 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3387 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3388 SetMapMode(hdcSrc, MM_ANISOTROPIC);
3389 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
3390 SetLastError(0xdeadbeef);
3391 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend);
3392 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3393 SetLastError(0xdeadbeef);
3394 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend);
3395 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3397 SetLastError(0xdeadbeef);
3398 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend);
3399 ok( !ret, "GdiAlphaBlend succeeded\n" );
3400 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3402 /* overlapping source and dest not allowed */
3404 SetLastError(0xdeadbeef);
3405 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 19, 19, 20, 20, blend);
3406 ok( !ret, "GdiAlphaBlend succeeded\n" );
3407 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3409 SetLastError(0xdeadbeef);
3410 ret = pGdiAlphaBlend(hdcDst, 20, 20, 20, 20, hdcDst, 1, 1, 20, 20, blend);
3411 ok( !ret, "GdiAlphaBlend succeeded\n" );
3412 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3414 SetLastError(0xdeadbeef);
3415 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 20, 10, 20, 20, blend);
3416 ok( ret, "GdiAlphaBlend succeeded\n" );
3417 SetLastError(0xdeadbeef);
3418 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 10, 20, 20, 20, blend);
3419 ok( ret, "GdiAlphaBlend succeeded\n" );
3421 /* AC_SRC_ALPHA requires 32-bpp BI_RGB format */
3423 blend.AlphaFormat = AC_SRC_ALPHA;
3424 SetLastError(0xdeadbeef);
3425 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3426 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3428 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3429 ((DWORD *)bmi->bmiColors)[0] = 0xff0000;
3430 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3431 ((DWORD *)bmi->bmiColors)[2] = 0x0000ff;
3432 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3433 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3434 oldSrc = SelectObject(hdcSrc, bmpSrc);
3435 DeleteObject( oldSrc );
3437 SetLastError(0xdeadbeef);
3438 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3439 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3441 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3442 ((DWORD *)bmi->bmiColors)[0] = 0x0000ff;
3443 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3444 ((DWORD *)bmi->bmiColors)[2] = 0xff0000;
3445 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3446 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3447 oldSrc = SelectObject(hdcSrc, bmpSrc);
3448 DeleteObject( oldSrc );
3450 SetLastError(0xdeadbeef);
3451 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3452 ok( !ret, "GdiAlphaBlend succeeded\n" );
3453 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3455 bmi->bmiHeader.biBitCount = 24;
3456 bmi->bmiHeader.biCompression = BI_RGB;
3457 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3458 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3459 oldSrc = SelectObject(hdcSrc, bmpSrc);
3460 DeleteObject( oldSrc );
3462 SetLastError(0xdeadbeef);
3463 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3464 ok( !ret, "GdiAlphaBlend succeeded\n" );
3465 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3467 bmi->bmiHeader.biBitCount = 1;
3468 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3469 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3470 oldSrc = SelectObject(hdcSrc, bmpSrc);
3471 DeleteObject( oldSrc );
3473 SetLastError(0xdeadbeef);
3474 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3475 ok( !ret, "GdiAlphaBlend succeeded\n" );
3476 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3478 bmpSrc = CreateBitmap( 100, 100, 1, 1, NULL );
3479 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3480 oldSrc = SelectObject(hdcSrc, bmpSrc);
3481 DeleteObject( oldSrc );
3483 SetLastError(0xdeadbeef);
3484 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3485 ok( !ret, "GdiAlphaBlend succeeded\n" );
3486 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3488 SelectObject(hdcDst, oldDst);
3489 SelectObject(hdcSrc, oldSrc);
3490 DeleteObject(bmpSrc);
3491 DeleteObject(bmpDst);
3495 ReleaseDC(NULL, hdcNull);
3499 static void test_GdiGradientFill(void)
3506 GRADIENT_RECT rect[] = { { 0, 0 }, { 0, 1 }, { 2, 3 } };
3507 GRADIENT_TRIANGLE tri[] = { { 0, 0, 0 }, { 0, 1, 2 }, { 0, 2, 1 }, { 0, 1, 3 } };
3508 TRIVERTEX vt[3] = { { 2, 2, 0xff00, 0x0000, 0x0000, 0x8000 },
3509 { 10, 10, 0x0000, 0xff00, 0x0000, 0x8000 },
3510 { 20, 10, 0x0000, 0x0000, 0xff00, 0xff00 } };
3512 if (!pGdiGradientFill)
3514 win_skip( "GdiGradientFill is not implemented\n" );
3518 hdc = CreateCompatibleDC( NULL );
3519 bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3520 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3521 bmi->bmiHeader.biHeight = 20;
3522 bmi->bmiHeader.biWidth = 20;
3523 bmi->bmiHeader.biBitCount = 32;
3524 bmi->bmiHeader.biPlanes = 1;
3525 bmi->bmiHeader.biCompression = BI_RGB;
3526 bmp = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3527 ok( bmp != NULL, "couldn't create bitmap\n" );
3528 SelectObject( hdc, bmp );
3530 SetLastError( 0xdeadbeef );
3531 ret = pGdiGradientFill( hdc, vt, 3, rect, 1, GRADIENT_FILL_RECT_H );
3532 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3533 SetLastError( 0xdeadbeef );
3534 ret = pGdiGradientFill( hdc, vt, 3, rect, 1, 3 );
3535 ok( !ret, "GdiGradientFill succeeded\n" );
3536 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3537 SetLastError( 0xdeadbeef );
3538 ret = pGdiGradientFill( (HDC)0xdead, vt, 3, rect, 1, GRADIENT_FILL_RECT_H );
3539 ok( !ret, "GdiGradientFill succeeded\n" );
3540 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3541 SetLastError( 0xdeadbeef );
3542 ret = pGdiGradientFill( NULL, NULL, 0, rect, 1, GRADIENT_FILL_RECT_H );
3543 ok( !ret, "GdiGradientFill succeeded\n" );
3544 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3545 ret = pGdiGradientFill( hdc, NULL, 0, rect, 1, GRADIENT_FILL_RECT_H );
3546 ok( !ret, "GdiGradientFill succeeded\n" );
3547 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3548 SetLastError( 0xdeadbeef );
3549 ret = pGdiGradientFill( hdc, NULL, 3, rect, 1, GRADIENT_FILL_RECT_H );
3550 ok( !ret, "GdiGradientFill succeeded\n" );
3551 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3552 SetLastError( 0xdeadbeef );
3553 ret = pGdiGradientFill( hdc, vt, 3, NULL, 0, GRADIENT_FILL_RECT_H );
3554 ok( !ret, "GdiGradientFill succeeded\n" );
3555 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3556 SetLastError( 0xdeadbeef );
3557 ret = pGdiGradientFill( hdc, vt, 3, NULL, 1, GRADIENT_FILL_RECT_H );
3558 ok( !ret, "GdiGradientFill succeeded\n" );
3559 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3560 SetLastError( 0xdeadbeef );
3561 ret = pGdiGradientFill( hdc, vt, 3, rect, 0, GRADIENT_FILL_RECT_H );
3562 ok( !ret, "GdiGradientFill succeeded\n" );
3563 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3564 SetLastError( 0xdeadbeef );
3565 ret = pGdiGradientFill( hdc, vt, 3, rect, 3, GRADIENT_FILL_RECT_H );
3566 ok( !ret, "GdiGradientFill succeeded\n" );
3567 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3568 rect[2].UpperLeft = rect[2].LowerRight = 1;
3569 SetLastError( 0xdeadbeef );
3570 ret = pGdiGradientFill( hdc, vt, 3, rect, 3, GRADIENT_FILL_RECT_H );
3571 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3572 SetLastError( 0xdeadbeef );
3573 ret = pGdiGradientFill( hdc, vt, 1, rect, 1, GRADIENT_FILL_RECT_H );
3574 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3575 SetLastError( 0xdeadbeef );
3576 ret = pGdiGradientFill( hdc, vt, 1, tri, 0, GRADIENT_FILL_TRIANGLE );
3577 ok( !ret, "GdiGradientFill succeeded\n" );
3578 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3579 SetLastError( 0xdeadbeef );
3580 ret = pGdiGradientFill( hdc, vt, 1, tri, 1, GRADIENT_FILL_TRIANGLE );
3581 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3582 SetLastError( 0xdeadbeef );
3583 ret = pGdiGradientFill( hdc, vt, 3, tri, 2, GRADIENT_FILL_TRIANGLE );
3584 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3585 SetLastError( 0xdeadbeef );
3586 ret = pGdiGradientFill( hdc, vt, 3, tri, 3, GRADIENT_FILL_TRIANGLE );
3587 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3588 SetLastError( 0xdeadbeef );
3589 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3590 ok( !ret, "GdiGradientFill succeeded\n" );
3591 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3593 SetLastError( 0xdeadbeef );
3594 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3595 ok( !ret, "GdiGradientFill succeeded\n" );
3596 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3598 SetLastError( 0xdeadbeef );
3599 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3600 ok( !ret, "GdiGradientFill succeeded\n" );
3601 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3602 tri[3].Vertex1 = tri[3].Vertex2 = tri[3].Vertex3 = 1;
3603 SetLastError( 0xdeadbeef );
3604 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3605 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3608 DeleteObject( bmp );
3611 static void test_clipping(void)
3619 HDC hdcDst = CreateCompatibleDC( NULL );
3620 HDC hdcSrc = CreateCompatibleDC( NULL );
3622 BITMAPINFO bmpinfo={{0}};
3623 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3624 bmpinfo.bmiHeader.biWidth = 100;
3625 bmpinfo.bmiHeader.biHeight = 100;
3626 bmpinfo.bmiHeader.biPlanes = 1;
3627 bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3628 bmpinfo.bmiHeader.biCompression = BI_RGB;
3630 bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3631 ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3632 SelectObject( hdcDst, bmpDst );
3634 bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3635 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3636 SelectObject( hdcSrc, bmpSrc );
3638 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3639 ok(result, "BitBlt failed\n");
3641 hRgn = CreateRectRgn( 0,0,0,0 );
3642 SelectClipRgn( hdcDst, hRgn );
3644 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3645 ok(result, "BitBlt failed\n");
3647 DeleteObject( bmpDst );
3648 DeleteObject( bmpSrc );
3649 DeleteObject( hRgn );
3654 static void test_32bit_ddb(void)
3656 char buffer[sizeof(BITMAPINFOHEADER) + sizeof(DWORD)];
3657 BITMAPINFO *biDst = (BITMAPINFO *)buffer;
3658 HBITMAP bmpSrc, bmpDst;
3659 HBITMAP oldSrc, oldDst;
3660 HDC hdcSrc, hdcDst, hdcScreen;
3662 DWORD *dstBuffer, *data;
3663 DWORD colorSrc = 0x40201008;
3665 memset(biDst, 0, sizeof(BITMAPINFOHEADER));
3666 biDst->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3667 biDst->bmiHeader.biWidth = 1;
3668 biDst->bmiHeader.biHeight = -1;
3669 biDst->bmiHeader.biPlanes = 1;
3670 biDst->bmiHeader.biBitCount = 32;
3671 biDst->bmiHeader.biCompression = BI_RGB;
3673 hdcScreen = CreateCompatibleDC(0);
3674 if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3676 DeleteDC(hdcScreen);
3677 trace("Skipping 32-bit DDB test\n");
3681 hdcSrc = CreateCompatibleDC(hdcScreen);
3682 bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3683 oldSrc = SelectObject(hdcSrc, bmpSrc);
3685 hdcDst = CreateCompatibleDC(hdcScreen);
3686 bmpDst = CreateDIBSection(hdcDst, biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3687 oldDst = SelectObject(hdcDst, bmpDst);
3689 StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3690 ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3694 BLENDFUNCTION blend;
3697 blend.BlendOp = AC_SRC_OVER;
3698 blend.BlendFlags = 0;
3699 blend.SourceConstantAlpha = 128;
3700 blend.AlphaFormat = 0;
3701 dstBuffer[0] = 0x80808080;
3702 ret = pGdiAlphaBlend( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, blend );
3703 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3704 ok(dstBuffer[0] == 0x60504844, "wrong color %x\n", dstBuffer[0]);
3705 blend.AlphaFormat = AC_SRC_ALPHA;
3706 dstBuffer[0] = 0x80808080;
3707 ret = pGdiAlphaBlend( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, blend );
3708 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3709 ok(dstBuffer[0] == 0x90807874, "wrong color %x\n", dstBuffer[0]);
3712 data = (DWORD *)biDst->bmiColors;
3713 data[0] = 0x20304050;
3714 brush = CreateDIBPatternBrushPt( biDst, DIB_RGB_COLORS );
3715 ok( brush != 0, "brush creation failed\n" );
3716 SelectObject( hdcSrc, brush );
3717 PatBlt( hdcSrc, 0, 0, 1, 1, PATCOPY );
3718 BitBlt( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, SRCCOPY );
3719 ok(dstBuffer[0] == data[0], "Expected color=%x, received color=%x\n", data[0], dstBuffer[0]);
3720 SelectObject( hdcSrc, GetStockObject(BLACK_BRUSH) );
3721 DeleteObject( brush );
3723 biDst->bmiHeader.biBitCount = 24;
3724 brush = CreateDIBPatternBrushPt( biDst, DIB_RGB_COLORS );
3725 ok( brush != 0, "brush creation failed\n" );
3726 SelectObject( hdcSrc, brush );
3727 PatBlt( hdcSrc, 0, 0, 1, 1, PATCOPY );
3728 BitBlt( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, SRCCOPY );
3729 ok(dstBuffer[0] == (data[0] & ~0xff000000),
3730 "Expected color=%x, received color=%x\n", data[0] & 0xff000000, dstBuffer[0]);
3731 SelectObject( hdcSrc, GetStockObject(BLACK_BRUSH) );
3732 DeleteObject( brush );
3735 SelectObject(hdcDst, oldDst);
3736 DeleteObject(bmpDst);
3739 SelectObject(hdcSrc, oldSrc);
3740 DeleteObject(bmpSrc);
3743 DeleteDC(hdcScreen);
3747 * Used by test_GetDIBits_top_down to create the bitmap to test against.
3749 static void setup_picture(char *picture, int bpp)
3757 /*Set the first byte in each pixel to the index of that pixel.*/
3758 for (i = 0; i < 4; i++)
3759 picture[i * (bpp / 8)] = i;
3764 /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
3771 static void test_GetDIBits_top_down(int bpp)
3774 HBITMAP bmptb, bmpbt;
3780 memset( &bi, 0, sizeof(bi) );
3781 bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
3782 bi.bmiHeader.biWidth=2;
3783 bi.bmiHeader.biHeight=2;
3784 bi.bmiHeader.biPlanes=1;
3785 bi.bmiHeader.biBitCount=bpp;
3786 bi.bmiHeader.biCompression=BI_RGB;
3788 /*Get the device context for the screen.*/
3790 ok(hdc != NULL, "Could not get a handle to a device context.\n");
3792 /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
3793 bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3794 ok(bmpbt != NULL, "Could not create a DIB section.\n");
3795 /*Now that we have a pointer to the pixels, we write to them.*/
3796 setup_picture((char*)picture, bpp);
3797 /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
3798 bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
3799 bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3800 ok(bmptb != NULL, "Could not create a DIB section.\n");
3801 /*Write to this top to bottom bitmap.*/
3802 setup_picture((char*)picture, bpp);
3804 bi.bmiHeader.biWidth = 1;
3806 bi.bmiHeader.biHeight = 2;
3807 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3808 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3809 /*Check the first byte of the pixel.*/
3810 ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3811 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3812 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3813 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3814 /*Check second scanline.*/
3815 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3816 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3817 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3818 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3819 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3820 ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3821 /*Check both scanlines.*/
3822 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3823 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3824 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3825 ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3826 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3827 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3828 ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3829 ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3831 /*Make destination bitmap top-down.*/
3832 bi.bmiHeader.biHeight = -2;
3833 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3834 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3835 ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3836 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3837 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3838 ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3839 /*Check second scanline.*/
3840 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3841 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3842 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3843 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3844 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3845 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3846 /*Check both scanlines.*/
3847 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3848 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3849 ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3850 ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3851 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3852 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3853 ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3854 ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3856 DeleteObject(bmpbt);
3857 DeleteObject(bmptb);
3860 static void test_GetSetDIBits_rtl(void)
3863 HBITMAP bitmap, orig_bitmap;
3866 DWORD bits_1[8 * 8], bits_2[8 * 8];
3870 win_skip("Don't have SetLayout\n");
3874 hdc = GetDC( NULL );
3875 hdc_mem = CreateCompatibleDC( hdc );
3876 pSetLayout( hdc_mem, LAYOUT_LTR );
3878 bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
3879 orig_bitmap = SelectObject( hdc_mem, bitmap );
3880 SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
3881 SelectObject( hdc_mem, orig_bitmap );
3883 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3884 info.bmiHeader.biWidth = 8;
3885 info.bmiHeader.biHeight = 8;
3886 info.bmiHeader.biPlanes = 1;
3887 info.bmiHeader.biBitCount = 32;
3888 info.bmiHeader.biCompression = BI_RGB;
3890 /* First show that GetDIBits ignores the layout mode. */
3892 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3893 ok(ret == 8, "got %d\n", ret);
3894 ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
3896 pSetLayout( hdc_mem, LAYOUT_RTL );
3898 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3899 ok(ret == 8, "got %d\n", ret);
3901 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3903 /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
3904 followed by a GetDIBits and show that the bits remain unchanged. */
3906 pSetLayout( hdc_mem, LAYOUT_LTR );
3908 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3909 ok(ret == 8, "got %d\n", ret);
3910 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3911 ok(ret == 8, "got %d\n", ret);
3912 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3914 pSetLayout( hdc_mem, LAYOUT_RTL );
3916 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3917 ok(ret == 8, "got %d\n", ret);
3918 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3919 ok(ret == 8, "got %d\n", ret);
3920 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3922 DeleteObject( bitmap );
3923 DeleteDC( hdc_mem );
3924 ReleaseDC( NULL, hdc );
3927 static void test_GetDIBits_scanlines(void)
3931 HDC hdc = GetDC( NULL );
3933 DWORD data[128], inverted_bits[64];
3936 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
3938 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3939 info->bmiHeader.biWidth = 8;
3940 info->bmiHeader.biHeight = 8;
3941 info->bmiHeader.biPlanes = 1;
3942 info->bmiHeader.biBitCount = 32;
3943 info->bmiHeader.biCompression = BI_RGB;
3945 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3947 for (i = 0; i < 64; i++)
3950 inverted_bits[56 - (i & ~7) + (i & 7)] = i;
3955 memset( data, 0xaa, sizeof(data) );
3957 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3958 ok( ret == 8, "got %d\n", ret );
3959 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3960 memset( data, 0xaa, sizeof(data) );
3962 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3963 ok( ret == 5, "got %d\n", ret );
3964 ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
3965 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3966 memset( data, 0xaa, sizeof(data) );
3968 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3969 ok( ret == 7, "got %d\n", ret );
3970 ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
3971 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3972 memset( data, 0xaa, sizeof(data) );
3974 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3975 ok( ret == 1, "got %d\n", ret );
3976 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3977 memset( data, 0xaa, sizeof(data) );
3979 info->bmiHeader.biHeight = 16;
3980 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3981 ok( ret == 5, "got %d\n", ret );
3982 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3983 ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
3984 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3985 memset( data, 0xaa, sizeof(data) );
3987 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3988 ok( ret == 6, "got %d\n", ret );
3989 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3990 ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
3991 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3992 memset( data, 0xaa, sizeof(data) );
3994 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3995 ok( ret == 0, "got %d\n", ret );
3996 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3997 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3998 memset( data, 0xaa, sizeof(data) );
4000 info->bmiHeader.biHeight = 5;
4001 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4002 ok( ret == 2, "got %d\n", ret );
4003 ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
4004 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4005 memset( data, 0xaa, sizeof(data) );
4009 info->bmiHeader.biHeight = -8;
4010 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4011 ok( ret == 8, "got %d\n", ret );
4012 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4013 memset( data, 0xaa, sizeof(data) );
4015 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4016 ok( ret == 5, "got %d\n", ret );
4017 ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
4018 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4019 memset( data, 0xaa, sizeof(data) );
4021 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4022 ok( ret == 7, "got %d\n", ret );
4023 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
4024 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4025 memset( data, 0xaa, sizeof(data) );
4027 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4028 ok( ret == 4, "got %d\n", ret );
4029 ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
4030 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4031 memset( data, 0xaa, sizeof(data) );
4033 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
4034 ok( ret == 5, "got %d\n", ret );
4035 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
4036 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4037 memset( data, 0xaa, sizeof(data) );
4039 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
4040 ok( ret == 5, "got %d\n", ret );
4041 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
4042 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4043 memset( data, 0xaa, sizeof(data) );
4045 info->bmiHeader.biHeight = -16;
4046 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
4047 ok( ret == 8, "got %d\n", ret );
4048 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4049 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4050 memset( data, 0xaa, sizeof(data) );
4052 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4053 ok( ret == 5, "got %d\n", ret );
4054 ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
4055 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4056 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4057 memset( data, 0xaa, sizeof(data) );
4059 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4060 ok( ret == 8, "got %d\n", ret );
4061 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4062 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4063 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4064 memset( data, 0xaa, sizeof(data) );
4066 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4067 ok( ret == 8, "got %d\n", ret );
4068 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4069 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4070 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4071 memset( data, 0xaa, sizeof(data) );
4073 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4074 ok( ret == 7, "got %d\n", ret );
4075 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
4076 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4077 memset( data, 0xaa, sizeof(data) );
4079 ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
4080 ok( ret == 1, "got %d\n", ret );
4081 for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4082 memset( data, 0xaa, sizeof(data) );
4084 info->bmiHeader.biHeight = -5;
4085 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4086 ok( ret == 2, "got %d\n", ret );
4087 ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
4088 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4089 memset( data, 0xaa, sizeof(data) );
4091 DeleteObject( dib );
4093 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4094 info->bmiHeader.biWidth = 8;
4095 info->bmiHeader.biHeight = -8;
4096 info->bmiHeader.biPlanes = 1;
4097 info->bmiHeader.biBitCount = 32;
4098 info->bmiHeader.biCompression = BI_RGB;
4100 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4102 for (i = 0; i < 64; i++) dib_bits[i] = i;
4106 info->bmiHeader.biHeight = -8;
4107 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4108 ok( ret == 8, "got %d\n", ret );
4109 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4110 memset( data, 0xaa, sizeof(data) );
4112 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4113 ok( ret == 5, "got %d\n", ret );
4114 ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
4115 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4116 memset( data, 0xaa, sizeof(data) );
4118 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4119 ok( ret == 7, "got %d\n", ret );
4120 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
4121 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4122 memset( data, 0xaa, sizeof(data) );
4124 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4125 ok( ret == 4, "got %d\n", ret );
4126 ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
4127 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4128 memset( data, 0xaa, sizeof(data) );
4130 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
4131 ok( ret == 5, "got %d\n", ret );
4132 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
4133 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4134 memset( data, 0xaa, sizeof(data) );
4136 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
4137 ok( ret == 5, "got %d\n", ret );
4138 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
4139 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4140 memset( data, 0xaa, sizeof(data) );
4142 info->bmiHeader.biHeight = -16;
4143 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
4144 ok( ret == 8, "got %d\n", ret );
4145 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4146 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4147 memset( data, 0xaa, sizeof(data) );
4149 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4150 ok( ret == 5, "got %d\n", ret );
4151 ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
4152 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4153 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4154 memset( data, 0xaa, sizeof(data) );
4156 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4157 ok( ret == 8, "got %d\n", ret );
4158 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4159 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4160 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4161 memset( data, 0xaa, sizeof(data) );
4163 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4164 ok( ret == 8, "got %d\n", ret );
4165 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4166 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4167 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4168 memset( data, 0xaa, sizeof(data) );
4170 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4171 ok( ret == 7, "got %d\n", ret );
4172 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
4173 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4174 memset( data, 0xaa, sizeof(data) );
4176 info->bmiHeader.biHeight = -5;
4177 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4178 ok( ret == 2, "got %d\n", ret );
4179 ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
4180 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4181 memset( data, 0xaa, sizeof(data) );
4186 info->bmiHeader.biHeight = 8;
4188 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4189 ok( ret == 8, "got %d\n", ret );
4190 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4191 memset( data, 0xaa, sizeof(data) );
4193 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4194 ok( ret == 5, "got %d\n", ret );
4195 ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
4196 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4197 memset( data, 0xaa, sizeof(data) );
4199 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4200 ok( ret == 7, "got %d\n", ret );
4201 ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
4202 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4203 memset( data, 0xaa, sizeof(data) );
4205 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4206 ok( ret == 1, "got %d\n", ret );
4207 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4208 memset( data, 0xaa, sizeof(data) );
4210 info->bmiHeader.biHeight = 16;
4211 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4212 ok( ret == 5, "got %d\n", ret );
4213 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4214 ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
4215 for (i = 96; 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, 2, 12, data, info, DIB_RGB_COLORS );
4219 ok( ret == 6, "got %d\n", ret );
4220 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4221 ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
4222 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4223 memset( data, 0xaa, sizeof(data) );
4225 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
4226 ok( ret == 0, "got %d\n", ret );
4227 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4228 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4229 memset( data, 0xaa, sizeof(data) );
4231 info->bmiHeader.biHeight = 5;
4232 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4233 ok( ret == 2, "got %d\n", ret );
4234 ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
4235 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4236 memset( data, 0xaa, sizeof(data) );
4238 DeleteObject( dib );
4240 ReleaseDC( NULL, hdc );
4241 HeapFree( GetProcessHeap(), 0, info );
4245 static void test_SetDIBits(void)
4247 char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
4248 LOGPALETTE *pal = (LOGPALETTE *)palbuf;
4249 PALETTEENTRY *palent = pal->palPalEntry;
4253 HDC hdc = GetDC( NULL );
4254 DWORD data[128], inverted_data[128];
4258 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4260 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4261 info->bmiHeader.biWidth = 8;
4262 info->bmiHeader.biHeight = 8;
4263 info->bmiHeader.biPlanes = 1;
4264 info->bmiHeader.biBitCount = 32;
4265 info->bmiHeader.biCompression = BI_RGB;
4267 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4268 memset( dib_bits, 0xaa, 64 * 4 );
4270 for (i = 0; i < 128; i++)
4273 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4278 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4279 ok( ret == 8, "got %d\n", ret );
4280 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4281 memset( dib_bits, 0xaa, 64 * 4 );
4283 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4284 ok( ret == 5, "got %d\n", ret );
4285 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4286 ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
4287 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4288 memset( dib_bits, 0xaa, 64 * 4 );
4290 /* top of dst is aligned with startscans down for the top of the src.
4291 Then starting from the bottom of src, lines rows are copied across. */
4293 info->bmiHeader.biHeight = 16;
4294 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4295 ok( ret == 12, "got %d\n", ret );
4296 ok( !memcmp( dib_bits, data + 56, 40 * 4 ), "bits differ\n");
4297 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4298 memset( dib_bits, 0xaa, 64 * 4 );
4300 info->bmiHeader.biHeight = 5;
4301 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4302 ok( ret == 2, "got %d\n", ret );
4303 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4304 ok( !memcmp( dib_bits + 32, data, 16 * 4 ), "bits differ\n");
4305 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4306 memset( dib_bits, 0xaa, 64 * 4 );
4309 info->bmiHeader.biHeight = -8;
4310 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4311 ok( ret == 8, "got %d\n", ret );
4312 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4313 memset( dib_bits, 0xaa, 64 * 4 );
4315 /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
4316 we copy lines rows from the top of the src */
4318 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4319 ok( ret == 5, "got %d\n", ret );
4320 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4321 ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
4322 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4323 memset( dib_bits, 0xaa, 64 * 4 );
4325 info->bmiHeader.biHeight = -16;
4326 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4327 ok( ret == 12, "got %d\n", ret );
4328 ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
4329 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4330 memset( dib_bits, 0xaa, 64 * 4 );
4332 ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4333 ok( ret == 12, "got %d\n", ret );
4334 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4335 memset( dib_bits, 0xaa, 64 * 4 );
4337 ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4338 ok( ret == 12, "got %d\n", ret );
4339 ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
4340 memset( dib_bits, 0xaa, 64 * 4 );
4342 info->bmiHeader.biHeight = -5;
4343 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4344 ok( ret == 2, "got %d\n", ret );
4345 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4346 ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
4347 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4348 memset( dib_bits, 0xaa, 64 * 4 );
4350 DeleteObject( dib );
4352 info->bmiHeader.biHeight = -8;
4354 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4355 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4359 /* like the t-d -> b-u case. */
4361 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4362 ok( ret == 8, "got %d\n", ret );
4363 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4364 memset( dib_bits, 0xaa, 64 * 4 );
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 < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4369 ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
4370 for (i = 56; 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 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4377 ok( !memcmp( dib_bits + 24, data, 40 * 4 ), "bits differ\n");
4378 memset( dib_bits, 0xaa, 64 * 4 );
4380 info->bmiHeader.biHeight = -5;
4381 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4382 ok( ret == 2, "got %d\n", ret );
4383 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4384 ok( !memcmp( dib_bits + 16, data, 16 * 4 ), "bits differ\n");
4385 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4386 memset( dib_bits, 0xaa, 64 * 4 );
4389 /* like the b-u -> b-u case */
4391 info->bmiHeader.biHeight = 8;
4392 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4393 ok( ret == 8, "got %d\n", ret );
4394 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4395 memset( dib_bits, 0xaa, 64 * 4 );
4397 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4398 ok( ret == 5, "got %d\n", ret );
4399 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4400 ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
4401 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4402 memset( dib_bits, 0xaa, 64 * 4 );
4404 info->bmiHeader.biHeight = 16;
4405 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4406 ok( ret == 12, "got %d\n", ret );
4407 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4408 ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
4409 memset( dib_bits, 0xaa, 64 * 4 );
4411 info->bmiHeader.biHeight = 5;
4412 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4413 ok( ret == 2, "got %d\n", ret );
4414 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4415 ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
4416 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4417 memset( dib_bits, 0xaa, 64 * 4 );
4419 /* handling of partial color table */
4421 info->bmiHeader.biHeight = -8;
4422 info->bmiHeader.biBitCount = 8;
4423 info->bmiHeader.biClrUsed = 137;
4424 for (i = 0; i < 256; i++)
4426 info->bmiColors[i].rgbRed = 255 - i;
4427 info->bmiColors[i].rgbGreen = i * 2;
4428 info->bmiColors[i].rgbBlue = i;
4429 info->bmiColors[i].rgbReserved = 0;
4431 for (i = 0; i < 64; i++) ((BYTE *)data)[i] = i * 4 + 1;
4432 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4433 ok( ret == 8, "got %d\n", ret );
4434 for (i = 0; i < 64; i++)
4436 int idx = i * 4 + 1;
4437 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : (info->bmiColors[idx].rgbRed << 16 |
4438 info->bmiColors[idx].rgbGreen << 8 |
4439 info->bmiColors[idx].rgbBlue);
4440 ok( dib_bits[i] == expect, "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
4442 memset( dib_bits, 0xaa, 64 * 4 );
4444 /* handling of DIB_PAL_COLORS */
4446 pal->palVersion = 0x300;
4447 pal->palNumEntries = 137;
4448 info->bmiHeader.biClrUsed = 221;
4449 for (i = 0; i < 256; i++)
4451 palent[i].peRed = i * 2;
4452 palent[i].peGreen = 255 - i;
4453 palent[i].peBlue = i;
4455 palette = CreatePalette( pal );
4456 ok( palette != 0, "palette creation failed\n" );
4457 SelectPalette( hdc, palette, FALSE );
4458 for (i = 0; i < 256; i++) ((WORD *)info->bmiColors)[i] = 255 - i;
4459 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_PAL_COLORS );
4460 ok( ret == 8, "got %d\n", ret );
4461 for (i = 0; i < 64; i++)
4463 int idx = i * 4 + 1;
4464 int ent = (255 - idx) % pal->palNumEntries;
4465 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 :
4466 (palent[ent].peRed << 16 | palent[ent].peGreen << 8 | palent[ent].peBlue);
4467 ok( dib_bits[i] == expect || broken(dib_bits[i] == 0), /* various Windows versions get some values wrong */
4468 "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
4470 memset( dib_bits, 0xaa, 64 * 4 );
4472 ReleaseDC( NULL, hdc );
4473 DeleteObject( dib );
4474 DeleteObject( palette );
4475 HeapFree( GetProcessHeap(), 0, info );
4478 static void test_SetDIBits_RLE4(void)
4482 HDC hdc = GetDC( NULL );
4483 BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00, /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
4484 0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
4485 0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00, /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
4486 0x00, 0x02, 0x01, 0x02, 0x05, 0x87, /* dx=1, dy=2, 8, 7, 8, 7, 8 */
4487 0x00, 0x01 }; /* <eod> */
4490 DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
4491 0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
4492 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4493 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4494 0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
4495 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4496 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4497 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4499 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4501 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4502 info->bmiHeader.biWidth = 8;
4503 info->bmiHeader.biHeight = 8;
4504 info->bmiHeader.biPlanes = 1;
4505 info->bmiHeader.biBitCount = 32;
4506 info->bmiHeader.biCompression = BI_RGB;
4508 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4509 memset( dib_bits, 0xaa, 64 * 4 );
4511 info->bmiHeader.biBitCount = 4;
4512 info->bmiHeader.biCompression = BI_RLE4;
4513 info->bmiHeader.biSizeImage = sizeof(rle4_data);
4515 for (i = 0; i < 16; i++)
4517 info->bmiColors[i].rgbRed = i;
4518 info->bmiColors[i].rgbGreen = i;
4519 info->bmiColors[i].rgbBlue = i;
4520 info->bmiColors[i].rgbReserved = 0;
4523 ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
4524 ok( ret == 8, "got %d\n", ret );
4525 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
4526 memset( dib_bits, 0xaa, 64 * 4 );
4528 DeleteObject( dib );
4529 ReleaseDC( NULL, hdc );
4530 HeapFree( GetProcessHeap(), 0, info );
4533 static void test_SetDIBits_RLE8(void)
4537 HDC hdc = GetDC( NULL );
4538 BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00, /* 2, 2, 2, f0, f0, f0, f0, <eol> */
4539 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4540 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4541 0x00, 0x01 }; /* <eod> */
4544 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4545 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4546 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4547 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4548 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4549 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4550 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4551 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4552 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4553 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4554 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4555 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4556 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4557 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4558 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4559 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4561 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4563 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4564 info->bmiHeader.biWidth = 8;
4565 info->bmiHeader.biHeight = 8;
4566 info->bmiHeader.biPlanes = 1;
4567 info->bmiHeader.biBitCount = 32;
4568 info->bmiHeader.biCompression = BI_RGB;
4570 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4571 memset( dib_bits, 0xaa, 64 * 4 );
4573 info->bmiHeader.biBitCount = 8;
4574 info->bmiHeader.biCompression = BI_RLE8;
4575 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4577 for (i = 0; i < 256; i++)
4579 info->bmiColors[i].rgbRed = i;
4580 info->bmiColors[i].rgbGreen = i;
4581 info->bmiColors[i].rgbBlue = i;
4582 info->bmiColors[i].rgbReserved = 0;
4585 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4586 ok( ret == 8, "got %d\n", ret );
4587 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4588 memset( dib_bits, 0xaa, 64 * 4 );
4590 /* startscan and lines are ignored, unless lines == 0 */
4591 ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4592 ok( ret == 8, "got %d\n", ret );
4593 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4594 memset( dib_bits, 0xaa, 64 * 4 );
4596 ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4597 ok( ret == 8, "got %d\n", ret );
4598 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4599 memset( dib_bits, 0xaa, 64 * 4 );
4601 ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4602 ok( ret == 0, "got %d\n", ret );
4603 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4604 memset( dib_bits, 0xaa, 64 * 4 );
4606 /* reduce width to 4, left-hand side of dst is touched. */
4607 info->bmiHeader.biWidth = 4;
4608 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4609 ok( ret == 8, "got %d\n", ret );
4610 for (i = 0; i < 64; i++)
4612 DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4613 ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4615 memset( dib_bits, 0xaa, 64 * 4 );
4617 /* Show that the top lines are aligned by adjusting the height of the src */
4619 /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4620 info->bmiHeader.biWidth = 8;
4621 info->bmiHeader.biHeight = 4;
4622 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4623 ok( ret == 4, "got %d\n", ret );
4624 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4625 ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4626 memset( dib_bits, 0xaa, 64 * 4 );
4628 /* increase the height to 9 -> everything moves down one row. */
4629 info->bmiHeader.biHeight = 9;
4630 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4631 ok( ret == 9, "got %d\n", ret );
4632 ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4633 for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4634 memset( dib_bits, 0xaa, 64 * 4 );
4636 /* top-down compressed dibs are invalid */
4637 info->bmiHeader.biHeight = -8;
4638 SetLastError( 0xdeadbeef );
4639 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4640 ok( ret == 0, "got %d\n", ret );
4641 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4642 DeleteObject( dib );
4646 info->bmiHeader.biHeight = -8;
4647 info->bmiHeader.biBitCount = 32;
4648 info->bmiHeader.biCompression = BI_RGB;
4649 info->bmiHeader.biSizeImage = 0;
4651 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4652 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4654 info->bmiHeader.biHeight = 8;
4655 info->bmiHeader.biBitCount = 8;
4656 info->bmiHeader.biCompression = BI_RLE8;
4657 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4659 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4660 ok( ret == 8, "got %d\n", ret );
4661 ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4662 memset( dib_bits, 0xaa, 64 * 4 );
4664 info->bmiHeader.biHeight = 4;
4665 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4666 ok( ret == 4, "got %d\n", ret );
4667 ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4668 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4669 memset( dib_bits, 0xaa, 64 * 4 );
4671 info->bmiHeader.biHeight = 9;
4672 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4673 ok( ret == 9, "got %d\n", ret );
4674 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4675 ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4676 memset( dib_bits, 0xaa, 64 * 4 );
4678 DeleteObject( dib );
4679 ReleaseDC( NULL, hdc );
4680 HeapFree( GetProcessHeap(), 0, info );
4683 static void test_SetDIBitsToDevice(void)
4685 char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
4686 LOGPALETTE *pal = (LOGPALETTE *)palbuf;
4687 PALETTEENTRY *palent = pal->palPalEntry;
4691 HDC hdc = CreateCompatibleDC( 0 );
4692 DWORD data[128], inverted_data[128];
4696 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4698 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4699 info->bmiHeader.biWidth = 8;
4700 info->bmiHeader.biHeight = 8;
4701 info->bmiHeader.biPlanes = 1;
4702 info->bmiHeader.biBitCount = 32;
4703 info->bmiHeader.biCompression = BI_RGB;
4705 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4706 memset( dib_bits, 0xaa, 64 * 4 );
4707 SelectObject( hdc, dib );
4709 for (i = 0; i < 128; i++)
4712 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4717 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4718 ok( ret == 8, "got %d\n", ret );
4719 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4720 memset( dib_bits, 0xaa, 64 * 4 );
4722 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4723 ok( ret == 5, "got %d\n", ret );
4724 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4725 for (i = 8; i < 48; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4726 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4727 memset( dib_bits, 0xaa, 64 * 4 );
4729 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 3, 1, 5, data, info, DIB_RGB_COLORS );
4730 ok( ret == 5, "got %d\n", ret );
4731 for (i = 0; i < 24; i++) ok( dib_bits[i] == data[i + 16], "%d: got %08x\n", i, dib_bits[i] );
4732 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4733 memset( dib_bits, 0xaa, 64 * 4 );
4735 info->bmiHeader.biHeight = 16;
4736 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4737 ok( ret == 7, "got %d\n", ret );
4738 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4739 for (i = 8; i < 64; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4740 memset( dib_bits, 0xaa, 64 * 4 );
4742 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 8, 0, 6, 1, 12, data, info, DIB_RGB_COLORS );
4743 ok( ret == 12, "got %d\n", ret );
4744 for (i = 0; i < 40; i++) ok( dib_bits[i] == data[i + 56], "%d: got %08x\n", i, dib_bits[i] );
4745 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4746 memset( dib_bits, 0xaa, 64 * 4 );
4748 ret = SetDIBitsToDevice( hdc, 0, -4, 8, 8, 0, 3, 1, 12, data, info, DIB_RGB_COLORS );
4749 ok( ret == 10, "got %d\n", ret );
4750 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4751 for (i = 32; i < 64; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4752 memset( dib_bits, 0xaa, 64 * 4 );
4754 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, -3, 1, 12, data, info, DIB_RGB_COLORS );
4755 ok( ret == 4, "got %d\n", ret );
4756 for (i = 0; i < 32; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4757 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4758 memset( dib_bits, 0xaa, 64 * 4 );
4760 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 5, 0, -2, 1, 12, data, info, DIB_RGB_COLORS );
4761 ok( ret == 2, "got %d\n", ret );
4762 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4763 for (i = 32; i < 48; i++) ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4764 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4765 memset( dib_bits, 0xaa, 64 * 4 );
4767 info->bmiHeader.biHeight = 5;
4768 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 2, 2, data, info, DIB_RGB_COLORS );
4769 ok( ret == 2, "got %d\n", ret );
4770 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4771 for (i = 16; i < 32; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4772 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4773 memset( dib_bits, 0xaa, 64 * 4 );
4775 ret = SetDIBitsToDevice( hdc, 3, 3, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4776 ok( ret == 3, "got %d\n", ret );
4777 for (i = 0; i < 64; i++)
4778 if (i == 27 || i == 28 || i == 35 || i == 36)
4779 ok( dib_bits[i] == data[i - 18], "%d: got %08x\n", i, dib_bits[i] );
4781 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4782 memset( dib_bits, 0xaa, 64 * 4 );
4784 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4785 ok( ret == 5, "got %d\n", ret );
4786 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4787 memset( dib_bits, 0xaa, 64 * 4 );
4789 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4790 ok( ret == 0, "got %d\n", ret );
4791 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4792 memset( dib_bits, 0xaa, 64 * 4 );
4794 SetMapMode( hdc, MM_ANISOTROPIC );
4795 SetWindowExtEx( hdc, 3, 3, NULL );
4796 ret = SetDIBitsToDevice( hdc, 2, 2, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4797 ok( ret == 3, "got %d\n", ret );
4798 for (i = 0; i < 64; i++)
4799 if (i == 41 || i == 42 || i == 49 || i == 50)
4800 ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4802 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4803 memset( dib_bits, 0xaa, 64 * 4 );
4805 SetWindowExtEx( hdc, -1, -1, NULL );
4806 ret = SetDIBitsToDevice( hdc, 2, 2, 4, 4, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4807 ok( ret == 4, "got %d\n", ret );
4808 for (i = 0; i < 64; i++)
4809 if (i == 48 || i == 49 || i == 56 || i == 57)
4810 ok( dib_bits[i] == data[i - 37], "%d: got %08x\n", i, dib_bits[i] );
4812 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4813 memset( dib_bits, 0xaa, 64 * 4 );
4814 SetMapMode( hdc, MM_TEXT );
4818 pSetLayout( hdc, LAYOUT_RTL );
4819 ret = SetDIBitsToDevice( hdc, 1, 2, 3, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4820 ok( ret == 3, "got %d\n", ret );
4821 for (i = 0; i < 64; i++)
4822 if (i == 36 || i == 37 || i == 38 || i == 44 || i == 45 || i == 46)
4823 ok( dib_bits[i] == data[i - 27], "%d: got %08x\n", i, dib_bits[i] );
4825 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4826 memset( dib_bits, 0xaa, 64 * 4 );
4827 pSetLayout( hdc, LAYOUT_LTR );
4831 info->bmiHeader.biHeight = -8;
4832 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4833 ok( ret == 8, "got %d\n", ret );
4834 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4835 memset( dib_bits, 0xaa, 64 * 4 );
4837 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4838 ok( ret == 5, "got %d\n", ret );
4839 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4840 for (i = 8; i < 48; i++) ok( dib_bits[i] == inverted_data[i + 80], "%d: got %08x\n", i, dib_bits[i] );
4841 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4842 memset( dib_bits, 0xaa, 64 * 4 );
4844 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 4, 1, 5, data, info, DIB_RGB_COLORS );
4845 ok( ret == 5, "got %d\n", ret );
4846 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4847 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4848 memset( dib_bits, 0xaa, 64 * 4 );
4850 info->bmiHeader.biHeight = -16;
4851 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4852 ok( ret == 12, "got %d\n", ret );
4853 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4854 for (i = 8; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4855 memset( dib_bits, 0xaa, 64 * 4 );
4857 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, 7, 1, 12, data, info, DIB_RGB_COLORS );
4858 ok( ret == 12, "got %d\n", ret );
4859 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4860 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4861 memset( dib_bits, 0xaa, 64 * 4 );
4863 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 4, 12, data, info, DIB_RGB_COLORS );
4864 ok( ret == 12, "got %d\n", ret );
4865 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4866 for (i = 32; i < 64; i++) ok( dib_bits[i] == inverted_data[i], "%d: got %08x\n", i, dib_bits[i] );
4867 memset( dib_bits, 0xaa, 64 * 4 );
4869 ret = SetDIBitsToDevice( hdc, 0, -3, 8, 8, 0, 2, 4, 12, data, info, DIB_RGB_COLORS );
4870 ok( ret == 12, "got %d\n", ret );
4871 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4872 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4873 memset( dib_bits, 0xaa, 64 * 4 );
4875 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, -2, 4, 12, data, info, DIB_RGB_COLORS );
4876 ok( ret == 12, "got %d\n", ret );
4877 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4878 for (i = 24; i < 40; i++) ok( dib_bits[i] == inverted_data[i + 8], "%d: got %08x\n", i, dib_bits[i] );
4879 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4880 memset( dib_bits, 0xaa, 64 * 4 );
4882 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 5, 12, data, info, DIB_RGB_COLORS );
4883 ok( ret == 12, "got %d\n", ret );
4884 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4885 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4886 memset( dib_bits, 0xaa, 64 * 4 );
4888 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4889 ok( ret == 12, "got %d\n", ret );
4890 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4891 memset( dib_bits, 0xaa, 64 * 4 );
4893 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -2, -4, 0, 12, data, info, DIB_RGB_COLORS );
4894 ok( ret == 12, "got %d\n", ret );
4895 for (i = 0; i < 64; i++)
4896 if (i == 31 || i == 39 || i == 47 || i == 55 || i == 63)
4897 ok( dib_bits[i] == inverted_data[i + 1], "%d: got %08x\n", i, dib_bits[i] );
4899 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4900 memset( dib_bits, 0xaa, 64 * 4 );
4902 info->bmiHeader.biHeight = -5;
4903 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4904 ok( ret == 2, "got %d\n", ret );
4905 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4906 for (i = 8; i < 24; i++) ok( dib_bits[i] == inverted_data[i + 104], "%d: got %08x\n", i, dib_bits[i] );
4907 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4908 memset( dib_bits, 0xaa, 64 * 4 );
4910 ret = SetDIBitsToDevice( hdc, 5, 4, 2, 2, 6, 3, 1, 5, data, info, DIB_RGB_COLORS );
4911 ok( ret == 5, "got %d\n", ret );
4912 for (i = 0; i < 64; i++)
4913 if (i == 21 || i == 22 || i == 29 || i == 30)
4914 ok( dib_bits[i] == inverted_data[i + 89], "%d: got %08x\n", i, dib_bits[i] );
4916 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4917 memset( dib_bits, 0xaa, 64 * 4 );
4919 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4920 ok( ret == 5, "got %d\n", ret );
4921 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4922 memset( dib_bits, 0xaa, 64 * 4 );
4924 info->bmiHeader.biHeight = -8;
4926 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4927 DeleteObject( SelectObject( hdc, dib ));
4928 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4932 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4933 ok( ret == 8, "got %d\n", ret );
4934 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4935 memset( dib_bits, 0xaa, 64 * 4 );
4937 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4938 ok( ret == 5, "got %d\n", ret );
4939 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4940 for (i = 16; i < 56; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4941 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4942 memset( dib_bits, 0xaa, 64 * 4 );
4944 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 3, 0, 2, 1, 5, data, info, DIB_RGB_COLORS );
4945 ok( ret == 5, "got %d\n", ret );
4946 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4947 for (i = 24; i < 48; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4948 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4949 memset( dib_bits, 0xaa, 64 * 4 );
4951 info->bmiHeader.biHeight = -16;
4952 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4953 ok( ret == 12, "got %d\n", ret );
4954 for (i = 0; i < 56; i++) ok( dib_bits[i] == data[i + 40], "%d: got %08x\n", i, dib_bits[i] );
4955 for (i = 56; 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, -7, 8, 16, -1, -8, 0, 12, data, info, DIB_RGB_COLORS );
4959 ok( ret == 12, "got %d\n", ret );
4960 for (i = 0; i < 64; i++)
4961 if (i == 6 || i == 7)
4962 ok( dib_bits[i] == data[i + 82], "%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 info->bmiHeader.biHeight = -5;
4968 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4969 ok( ret == 2, "got %d\n", ret );
4970 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4971 for (i = 40; i < 56; i++) ok( dib_bits[i] == data[i - 40], "%d: got %08x\n", i, dib_bits[i] );
4972 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4973 memset( dib_bits, 0xaa, 64 * 4 );
4975 ret = SetDIBitsToDevice( hdc, 7, 2, 8, 8, 1, 0, 0, 5, data, info, DIB_RGB_COLORS );
4976 ok( ret == 5, "got %d\n", ret );
4977 for (i = 0; i < 64; i++)
4978 if (i == 47 || i == 55 || i == 63)
4979 ok( dib_bits[i] == data[i - 46], "%d: got %08x\n", i, dib_bits[i] );
4981 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4982 memset( dib_bits, 0xaa, 64 * 4 );
4984 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4985 ok( ret == 5, "got %d\n", ret );
4986 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4987 memset( dib_bits, 0xaa, 64 * 4 );
4991 info->bmiHeader.biHeight = 8;
4992 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4993 ok( ret == 8, "got %d\n", ret );
4994 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4995 memset( dib_bits, 0xaa, 64 * 4 );
4997 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4998 ok( ret == 5, "got %d\n", ret );
4999 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5000 for (i = 16; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
5001 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5002 memset( dib_bits, 0xaa, 64 * 4 );
5004 info->bmiHeader.biHeight = 16;
5005 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
5006 ok( ret == 7, "got %d\n", ret );
5007 for (i = 0; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
5008 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5009 memset( dib_bits, 0xaa, 64 * 4 );
5011 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, 0, -4, 1, 12, data, info, DIB_RGB_COLORS );
5012 ok( ret == 3, "got %d\n", ret );
5013 for (i = 0; i < 64; i++)
5014 if ((i >= 36 && i <= 39) || (i >= 44 && i <= 47) || (i >= 52 && i <= 55))
5015 ok( dib_bits[i] == inverted_data[i + 68], "%d: got %08x\n", i, dib_bits[i] );
5017 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5018 memset( dib_bits, 0xaa, 64 * 4 );
5020 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, -30, -30, 1, 12, data, info, DIB_RGB_COLORS );
5021 ok( ret == 0, "got %d\n", ret );
5022 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5023 memset( dib_bits, 0xaa, 64 * 4 );
5025 ret = SetDIBitsToDevice( hdc, 5, -5, 8, 16, -2, -4, 4, 12, data, info, DIB_RGB_COLORS );
5026 ok( ret == 8, "got %d\n", ret );
5027 for (i = 0; i < 64; i++)
5028 if (i == 7 || i == 15 || i == 23)
5029 ok( dib_bits[i] == inverted_data[i + 97], "%d: got %08x\n", i, dib_bits[i] );
5031 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5032 memset( dib_bits, 0xaa, 64 * 4 );
5034 info->bmiHeader.biHeight = 5;
5035 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
5036 ok( ret == 2, "got %d\n", ret );
5037 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5038 for (i = 40; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
5039 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5040 memset( dib_bits, 0xaa, 64 * 4 );
5042 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5043 ok( ret == 5, "got %d\n", ret );
5044 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5045 memset( dib_bits, 0xaa, 64 * 4 );
5047 /* handling of partial color table */
5049 info->bmiHeader.biHeight = -8;
5050 info->bmiHeader.biBitCount = 8;
5051 info->bmiHeader.biClrUsed = 137;
5052 for (i = 0; i < 256; i++)
5054 info->bmiColors[i].rgbRed = 255 - i;
5055 info->bmiColors[i].rgbGreen = i * 2;
5056 info->bmiColors[i].rgbBlue = i;
5057 info->bmiColors[i].rgbReserved = 0;
5059 for (i = 0; i < 64; i++) ((BYTE *)data)[i] = i * 4 + 1;
5060 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5061 ok( ret == 8, "got %d\n", ret );
5062 for (i = 0; i < 64; i++)
5064 int idx = i * 4 + 1;
5065 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : (info->bmiColors[idx].rgbRed << 16 |
5066 info->bmiColors[idx].rgbGreen << 8 |
5067 info->bmiColors[idx].rgbBlue);
5068 ok( dib_bits[i] == expect, "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
5070 memset( dib_bits, 0xaa, 64 * 4 );
5072 /* handling of DIB_PAL_COLORS */
5074 pal->palVersion = 0x300;
5075 pal->palNumEntries = 137;
5076 info->bmiHeader.biClrUsed = 221;
5077 for (i = 0; i < 256; i++)
5079 palent[i].peRed = i * 2;
5080 palent[i].peGreen = 255 - i;
5081 palent[i].peBlue = i;
5083 palette = CreatePalette( pal );
5084 ok( palette != 0, "palette creation failed\n" );
5085 SelectPalette( hdc, palette, FALSE );
5086 for (i = 0; i < 256; i++) ((WORD *)info->bmiColors)[i] = 255 - i;
5087 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_PAL_COLORS );
5088 ok( ret == 8, "got %d\n", ret );
5089 for (i = 0; i < 64; i++)
5091 int idx = i * 4 + 1;
5092 int ent = (255 - idx) % pal->palNumEntries;
5093 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 :
5094 (palent[ent].peRed << 16 | palent[ent].peGreen << 8 | palent[ent].peBlue);
5095 ok( dib_bits[i] == expect || broken(dib_bits[i] == 0),
5096 "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
5098 memset( dib_bits, 0xaa, 64 * 4 );
5101 DeleteObject( dib );
5102 DeleteObject( palette );
5103 HeapFree( GetProcessHeap(), 0, info );
5106 static void test_SetDIBitsToDevice_RLE8(void)
5110 HDC hdc = CreateCompatibleDC( 0 );
5111 BYTE rle8_data[20] = { 0x04, 0x02, 0x03, 0xf0, 0x00, 0x00, /* 2, 2, 2, 2, f0, f0, f0, <eol> */
5112 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
5113 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
5114 0x00, 0x01 }; /* <eod> */
5117 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
5118 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5119 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5120 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
5121 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5122 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5123 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5124 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
5125 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5126 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5127 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5128 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5129 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
5130 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5131 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5132 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
5134 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
5136 info->bmiHeader.biSize = sizeof(info->bmiHeader);
5137 info->bmiHeader.biWidth = 8;
5138 info->bmiHeader.biHeight = 8;
5139 info->bmiHeader.biPlanes = 1;
5140 info->bmiHeader.biBitCount = 32;
5141 info->bmiHeader.biCompression = BI_RGB;
5143 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5144 memset( dib_bits, 0xaa, 64 * 4 );
5145 SelectObject( hdc, dib );
5147 info->bmiHeader.biBitCount = 8;
5148 info->bmiHeader.biCompression = BI_RLE8;
5149 info->bmiHeader.biSizeImage = sizeof(rle8_data);
5151 for (i = 0; i < 256; i++)
5153 info->bmiColors[i].rgbRed = i;
5154 info->bmiColors[i].rgbGreen = i;
5155 info->bmiColors[i].rgbBlue = i;
5156 info->bmiColors[i].rgbReserved = 0;
5159 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5160 ok( ret == 8, "got %d\n", ret );
5161 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5162 memset( dib_bits, 0xaa, 64 * 4 );
5164 /* startscan and lines are ignored, unless lines == 0 */
5165 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 8, rle8_data, info, DIB_RGB_COLORS );
5166 ok( ret == 8, "got %d\n", ret );
5167 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5168 memset( dib_bits, 0xaa, 64 * 4 );
5170 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 1, rle8_data, info, DIB_RGB_COLORS );
5171 ok( ret == 8, "got %d\n", ret );
5172 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5173 memset( dib_bits, 0xaa, 64 * 4 );
5175 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 0, rle8_data, info, DIB_RGB_COLORS );
5176 ok( ret == 0, "got %d\n", ret );
5177 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5178 memset( dib_bits, 0xaa, 64 * 4 );
5180 info->bmiHeader.biWidth = 2;
5181 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5182 ok( ret == 8, "got %d\n", ret );
5183 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5184 memset( dib_bits, 0xaa, 64 * 4 );
5186 info->bmiHeader.biWidth = 8;
5187 info->bmiHeader.biHeight = 2;
5188 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5189 ok( ret == 2, "got %d\n", ret );
5190 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5191 memset( dib_bits, 0xaa, 64 * 4 );
5193 info->bmiHeader.biHeight = 9;
5194 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5195 ok( ret == 9, "got %d\n", ret );
5196 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5197 memset( dib_bits, 0xaa, 64 * 4 );
5199 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5200 ok( ret == 9, "got %d\n", ret );
5201 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5202 memset( dib_bits, 0xaa, 64 * 4 );
5204 info->bmiHeader.biHeight = 8;
5205 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 9, rle8_data, info, DIB_RGB_COLORS );
5206 ok( ret == 8, "got %d\n", ret );
5207 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5208 memset( dib_bits, 0xaa, 64 * 4 );
5210 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5211 ok( ret == 8, "got %d\n", ret );
5212 for (i = 0; i < 40; i++) ok( dib_bits[i] == bottom_up[i + 24], "%d: got %08x\n", i, dib_bits[i] );
5213 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5214 memset( dib_bits, 0xaa, 64 * 4 );
5216 ret = SetDIBitsToDevice( hdc, 0, 3, 4, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5217 ok( ret == 8, "got %d\n", ret );
5218 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5219 for (i = 8; i < 40; i++)
5220 if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5221 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5222 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5223 memset( dib_bits, 0xaa, 64 * 4 );
5225 ret = SetDIBitsToDevice( hdc, 3, 3, 8, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5226 ok( ret == 8, "got %d\n", ret );
5227 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5228 for (i = 8; i < 40; i++)
5229 if ((i & 7) < 3) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5230 else ok( dib_bits[i] == bottom_up[i - 11], "%d: got %08x\n", i, dib_bits[i] );
5231 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5232 memset( dib_bits, 0xaa, 64 * 4 );
5234 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 4, 2, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5235 ok( ret == 8, "got %d\n", ret );
5236 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5237 for (i = 8; i < 40; i++)
5238 if ((i & 7) < 2) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5239 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5240 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5241 memset( dib_bits, 0xaa, 64 * 4 );
5243 info->bmiHeader.biWidth = 37;
5244 info->bmiHeader.biHeight = 37;
5245 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
5246 ok( ret == 37, "got %d\n", ret );
5247 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5248 for (i = 24; i < 64; i++)
5249 if (i == 52) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
5250 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5251 else ok( dib_bits[i] == bottom_up[i - 20], "%d: got %08x\n", i, dib_bits[i] );
5252 memset( dib_bits, 0xaa, 64 * 4 );
5254 /* top-down compressed dibs are invalid */
5255 info->bmiHeader.biWidth = 8;
5256 info->bmiHeader.biHeight = -8;
5257 SetLastError( 0xdeadbeef );
5258 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5259 ok( ret == 0, "got %d\n", ret );
5260 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
5264 info->bmiHeader.biHeight = -8;
5265 info->bmiHeader.biBitCount = 32;
5266 info->bmiHeader.biCompression = BI_RGB;
5267 info->bmiHeader.biSizeImage = 0;
5269 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5270 memset( dib_bits, 0xaa, 16 * 16 * 4 );
5271 DeleteObject( SelectObject( hdc, dib ));
5273 info->bmiHeader.biHeight = 8;
5274 info->bmiHeader.biBitCount = 8;
5275 info->bmiHeader.biCompression = BI_RLE8;
5276 info->bmiHeader.biSizeImage = sizeof(rle8_data);
5278 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5279 ok( ret == 8, "got %d\n", ret );
5280 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5281 memset( dib_bits, 0xaa, 64 * 4 );
5283 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5284 ok( ret == 8, "got %d\n", ret );
5285 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5286 memset( dib_bits, 0xaa, 64 * 4 );
5288 info->bmiHeader.biHeight = 4;
5289 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5290 ok( ret == 4, "got %d\n", ret );
5291 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5292 memset( dib_bits, 0xaa, 64 * 4 );
5294 info->bmiHeader.biHeight = 9;
5295 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5296 ok( ret == 9, "got %d\n", ret );
5297 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5298 memset( dib_bits, 0xaa, 64 * 4 );
5300 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5301 ok( ret == 9, "got %d\n", ret );
5302 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5303 memset( dib_bits, 0xaa, 64 * 4 );
5305 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 6, 2, 2, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5306 ok( ret == 9, "got %d\n", ret );
5307 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5308 for (i = 24; i < 64; i++) ok( dib_bits[i] == top_down[i - 24], "%d: got %08x\n", i, dib_bits[i] );
5309 memset( dib_bits, 0xaa, 64 * 4 );
5311 info->bmiHeader.biWidth = 37;
5312 info->bmiHeader.biHeight = 37;
5313 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
5314 ok( ret == 37, "got %d\n", ret );
5315 for (i = 0; i < 40; i++)
5316 if (i == 12) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
5317 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5318 else ok( dib_bits[i] == top_down[i + 28], "%d: got %08x\n", i, dib_bits[i] );
5319 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5320 memset( dib_bits, 0xaa, 64 * 4 );
5323 DeleteObject( dib );
5324 HeapFree( GetProcessHeap(), 0, info );
5331 hdll = GetModuleHandle("gdi32.dll");
5332 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
5333 pGdiGradientFill = (void*)GetProcAddress(hdll, "GdiGradientFill");
5334 pSetLayout = (void*)GetProcAddress(hdll, "SetLayout");
5336 test_createdibitmap();
5339 test_mono_dibsection();
5342 test_GetDIBits_selected_DIB(1);
5343 test_GetDIBits_selected_DIB(4);
5344 test_GetDIBits_selected_DIB(8);
5345 test_GetDIBits_selected_DDB(TRUE);
5346 test_GetDIBits_selected_DDB(FALSE);
5348 test_GetDIBits_BI_BITFIELDS();
5349 test_select_object();
5350 test_CreateBitmap();
5353 test_StretchDIBits();
5354 test_GdiAlphaBlend();
5355 test_GdiGradientFill();
5357 test_bitmapinfoheadersize();
5360 test_GetDIBits_top_down(16);
5361 test_GetDIBits_top_down(24);
5362 test_GetDIBits_top_down(32);
5363 test_GetSetDIBits_rtl();
5364 test_GetDIBits_scanlines();
5366 test_SetDIBits_RLE4();
5367 test_SetDIBits_RLE8();
5368 test_SetDIBitsToDevice();
5369 test_SetDIBitsToDevice_RLE8();