gdi32/tests: Add some GetDIBits tests with zero lines and bits parameters.
[wine/multimedia.git] / dlls / gdi32 / tests / bitmap.c
blob69f4d74efd2bdf7650327dd83df0b4f04d1b0124
1 /*
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
22 #include <stdarg.h>
23 #include <assert.h>
24 #include <string.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winerror.h"
29 #include "wingdi.h"
30 #include "winuser.h"
31 #include "mmsystem.h"
33 #include "wine/test.h"
35 static BOOL (WINAPI *pGdiAlphaBlend)(HDC,int,int,int,int,HDC,int,int,int,int,BLENDFUNCTION);
36 static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
38 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
40 static INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp )
42 switch(bpp)
44 case 1:
45 return 2 * ((bmWidth+15) >> 4);
47 case 24:
48 bmWidth *= 3; /* fall through */
49 case 8:
50 return bmWidth + (bmWidth & 1);
52 case 32:
53 return bmWidth * 4;
55 case 16:
56 case 15:
57 return bmWidth * 2;
59 case 4:
60 return 2 * ((bmWidth+3) >> 2);
62 default:
63 trace("Unknown depth %d, please report.\n", bpp );
64 assert(0);
66 return -1;
69 static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHEADER *bmih)
71 BITMAP bm;
72 BITMAP bma[2];
73 INT ret, width_bytes;
74 BYTE buf[512], buf_cmp[512];
76 ret = GetObject(hbm, sizeof(bm), &bm);
77 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
79 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
80 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
81 ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
82 width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
83 ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
84 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
85 ok(bm.bmBitsPixel == expected_depth, "wrong bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, expected_depth);
86 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
88 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
89 assert(sizeof(buf) == sizeof(buf_cmp));
91 SetLastError(0xdeadbeef);
92 ret = GetBitmapBits(hbm, 0, NULL);
93 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
95 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
96 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
98 memset(buf, 0xAA, sizeof(buf));
99 ret = GetBitmapBits(hbm, sizeof(buf), buf);
100 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
101 ok(!memcmp(buf, buf_cmp, sizeof(buf)),
102 "buffers do not match, depth %d\n", bmih->biBitCount);
104 /* test various buffer sizes for GetObject */
105 ret = GetObject(hbm, sizeof(*bma) * 2, bma);
106 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
108 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
109 ok(ret == 0, "%d != 0\n", ret);
111 ret = GetObject(hbm, 0, &bm);
112 ok(ret == 0, "%d != 0\n", ret);
114 ret = GetObject(hbm, 1, &bm);
115 ok(ret == 0, "%d != 0\n", ret);
117 ret = GetObject(hbm, 0, NULL);
118 ok(ret == sizeof(bm), "wrong size %d\n", ret);
121 static void test_createdibitmap(void)
123 HDC hdc, hdcmem;
124 BITMAPINFOHEADER bmih;
125 BITMAPINFO bm;
126 HBITMAP hbm, hbm_colour, hbm_old;
127 INT screen_depth;
128 DWORD pixel;
130 hdc = GetDC(0);
131 screen_depth = GetDeviceCaps(hdc, BITSPIXEL);
132 memset(&bmih, 0, sizeof(bmih));
133 bmih.biSize = sizeof(bmih);
134 bmih.biWidth = 10;
135 bmih.biHeight = 10;
136 bmih.biPlanes = 1;
137 bmih.biBitCount = 32;
138 bmih.biCompression = BI_RGB;
140 hbm = CreateDIBitmap(hdc, NULL, CBM_INIT, NULL, NULL, 0);
141 ok(hbm == NULL, "CreateDIBitmap should fail\n");
142 hbm = CreateDIBitmap(hdc, NULL, 0, NULL, NULL, 0);
143 ok(hbm == NULL, "CreateDIBitmap should fail\n");
145 /* First create an un-initialised bitmap. The depth of the bitmap
146 should match that of the hdc and not that supplied in bmih.
149 /* First try 32 bits */
150 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
151 ok(hbm != NULL, "CreateDIBitmap failed\n");
152 test_bitmap_info(hbm, screen_depth, &bmih);
153 DeleteObject(hbm);
155 /* Then 16 */
156 bmih.biBitCount = 16;
157 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
158 ok(hbm != NULL, "CreateDIBitmap failed\n");
159 test_bitmap_info(hbm, screen_depth, &bmih);
160 DeleteObject(hbm);
162 /* Then 1 */
163 bmih.biBitCount = 1;
164 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
165 ok(hbm != NULL, "CreateDIBitmap failed\n");
166 test_bitmap_info(hbm, screen_depth, &bmih);
167 DeleteObject(hbm);
169 /* Now with a monochrome dc we expect a monochrome bitmap */
170 hdcmem = CreateCompatibleDC(hdc);
172 /* First try 32 bits */
173 bmih.biBitCount = 32;
174 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
175 ok(hbm != NULL, "CreateDIBitmap failed\n");
176 test_bitmap_info(hbm, 1, &bmih);
177 DeleteObject(hbm);
179 /* Then 16 */
180 bmih.biBitCount = 16;
181 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
182 ok(hbm != NULL, "CreateDIBitmap failed\n");
183 test_bitmap_info(hbm, 1, &bmih);
184 DeleteObject(hbm);
186 /* Then 1 */
187 bmih.biBitCount = 1;
188 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
189 ok(hbm != NULL, "CreateDIBitmap failed\n");
190 test_bitmap_info(hbm, 1, &bmih);
191 DeleteObject(hbm);
193 /* Now select a polychrome bitmap into the dc and we expect
194 screen_depth bitmaps again */
195 hbm_colour = CreateCompatibleBitmap(hdc, bmih.biWidth, bmih.biHeight);
196 test_bitmap_info(hbm_colour, screen_depth, &bmih);
197 hbm_old = SelectObject(hdcmem, hbm_colour);
199 /* First try 32 bits */
200 bmih.biBitCount = 32;
201 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
202 ok(hbm != NULL, "CreateDIBitmap failed\n");
203 test_bitmap_info(hbm, screen_depth, &bmih);
204 DeleteObject(hbm);
206 /* Then 16 */
207 bmih.biBitCount = 16;
208 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
209 ok(hbm != NULL, "CreateDIBitmap failed\n");
210 test_bitmap_info(hbm, screen_depth, &bmih);
211 DeleteObject(hbm);
213 /* Then 1 */
214 bmih.biBitCount = 1;
215 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
216 ok(hbm != NULL, "CreateDIBitmap failed\n");
217 test_bitmap_info(hbm, screen_depth, &bmih);
218 DeleteObject(hbm);
220 SelectObject(hdcmem, hbm_old);
221 DeleteObject(hbm_colour);
222 DeleteDC(hdcmem);
224 bmih.biBitCount = 32;
225 hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0);
226 ok(hbm != NULL, "CreateDIBitmap failed\n");
227 test_bitmap_info(hbm, 1, &bmih);
228 DeleteObject(hbm);
230 /* Test how formats are converted */
231 pixel = 0xffffffff;
232 bmih.biBitCount = 1;
233 bmih.biWidth = 1;
234 bmih.biHeight = 1;
236 memset(&bm, 0, sizeof(bm));
237 bm.bmiHeader.biSize = sizeof(bm.bmiHeader);
238 bm.bmiHeader.biWidth = 1;
239 bm.bmiHeader.biHeight = 1;
240 bm.bmiHeader.biPlanes = 1;
241 bm.bmiHeader.biBitCount= 24;
242 bm.bmiHeader.biCompression= BI_RGB;
243 bm.bmiHeader.biSizeImage = 0;
244 hbm = CreateDIBitmap(hdc, &bmih, CBM_INIT, &pixel, &bm, DIB_RGB_COLORS);
245 ok(hbm != NULL, "CreateDIBitmap failed\n");
247 pixel = 0xdeadbeef;
248 bm.bmiHeader.biBitCount= 32;
249 GetDIBits(hdc, hbm, 0, 1, &pixel, &bm, DIB_RGB_COLORS);
250 ok(pixel == 0x00ffffff, "Reading a 32 bit pixel from a DDB returned %08x\n", pixel);
251 DeleteObject(hbm);
253 ReleaseDC(0, hdc);
256 static INT DIB_GetWidthBytes( int width, int bpp )
258 int words;
260 switch (bpp)
262 case 1: words = (width + 31) / 32; break;
263 case 4: words = (width + 7) / 8; break;
264 case 8: words = (width + 3) / 4; break;
265 case 15:
266 case 16: words = (width + 1) / 2; break;
267 case 24: words = (width * 3 + 3)/4; break;
268 case 32: words = width; break;
270 default:
271 words=0;
272 trace("Unknown depth %d, please report.\n", bpp );
273 assert(0);
274 break;
276 return 4 * words;
279 static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
281 BITMAP bm;
282 BITMAP bma[2];
283 DIBSECTION ds;
284 DIBSECTION dsa[2];
285 INT ret, bm_width_bytes, dib_width_bytes;
286 BYTE *buf;
288 ret = GetObject(hbm, sizeof(bm), &bm);
289 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
291 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
292 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
293 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
294 dib_width_bytes = DIB_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
295 bm_width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
296 if (bm.bmWidthBytes != dib_width_bytes) /* Win2k bug */
297 ok(bm.bmWidthBytes == bm_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, bm_width_bytes);
298 else
299 ok(bm.bmWidthBytes == dib_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, dib_width_bytes);
300 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
301 ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount);
302 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
304 buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);
306 /* GetBitmapBits returns not 32-bit aligned data */
307 SetLastError(0xdeadbeef);
308 ret = GetBitmapBits(hbm, 0, NULL);
309 ok(ret == bm_width_bytes * bm.bmHeight,
310 "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
312 memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
313 ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
314 ok(ret == bm_width_bytes * bm.bmHeight, "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
316 HeapFree(GetProcessHeap(), 0, buf);
318 /* test various buffer sizes for GetObject */
319 memset(&ds, 0xAA, sizeof(ds));
320 ret = GetObject(hbm, sizeof(*bma) * 2, bma);
321 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
322 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
323 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
324 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
326 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
327 ok(ret == 0, "%d != 0\n", ret);
329 ret = GetObject(hbm, 0, &bm);
330 ok(ret == 0, "%d != 0\n", ret);
332 ret = GetObject(hbm, 1, &bm);
333 ok(ret == 0, "%d != 0\n", ret);
335 /* test various buffer sizes for GetObject */
336 ret = GetObject(hbm, 0, NULL);
337 ok(ret == sizeof(bm), "wrong size %d\n", ret);
339 ret = GetObject(hbm, sizeof(*dsa) * 2, dsa);
340 ok(ret == sizeof(*dsa), "wrong size %d\n", ret);
342 memset(&ds, 0xAA, sizeof(ds));
343 ret = GetObject(hbm, sizeof(ds), &ds);
344 ok(ret == sizeof(ds), "wrong size %d\n", ret);
346 ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
347 if (ds.dsBm.bmWidthBytes != bm_width_bytes) /* Win2k bug */
348 ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%u != %u\n",
349 ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
350 ok(bmih->biSizeImage == 0, "%u != 0\n", bmih->biSizeImage);
351 ds.dsBmih.biSizeImage = 0;
353 ok(ds.dsBmih.biSize == bmih->biSize, "%u != %u\n", ds.dsBmih.biSize, bmih->biSize);
354 ok(ds.dsBmih.biWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
355 ok(ds.dsBmih.biHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
356 ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes);
357 ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount);
358 ok(ds.dsBmih.biCompression == bmih->biCompression ||
359 ((bmih->biBitCount == 32) && broken(ds.dsBmih.biCompression == BI_BITFIELDS)), /* nt4 sp1 and 2 */
360 "%u != %u\n", ds.dsBmih.biCompression, bmih->biCompression);
361 ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%u != %u\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
362 ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%d != %d\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
363 ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%d != %d\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);
365 memset(&ds, 0xAA, sizeof(ds));
366 ret = GetObject(hbm, sizeof(ds) - 4, &ds);
367 ok(ret == sizeof(ds.dsBm), "wrong size %d\n", ret);
368 ok(ds.dsBm.bmWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
369 ok(ds.dsBm.bmHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
370 ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);
372 ret = GetObject(hbm, 0, &ds);
373 ok(ret == 0, "%d != 0\n", ret);
375 ret = GetObject(hbm, 1, &ds);
376 ok(ret == 0, "%d != 0\n", ret);
379 #define test_color_todo(got, exp, txt, todo) \
380 if (!todo && got != exp && screen_depth < 24) { \
381 todo_wine ok(0, #txt " failed at %d-bit screen depth: got 0x%06x expected 0x%06x - skipping DIB tests\n", \
382 screen_depth, (UINT)got, (UINT)exp); \
383 return; \
384 } else if (todo) todo_wine { ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp); } \
385 else ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp) \
387 #define test_color(hdc, color, exp, todo_setp, todo_getp) \
389 COLORREF c; \
390 c = SetPixel(hdc, 0, 0, color); \
391 test_color_todo(c, exp, SetPixel, todo_setp); \
392 c = GetPixel(hdc, 0, 0); \
393 test_color_todo(c, exp, GetPixel, todo_getp); \
396 static void test_dib_bits_access( HBITMAP hdib, void *bits )
398 MEMORY_BASIC_INFORMATION info;
399 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
400 DWORD data[256];
401 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
402 HDC hdc;
403 char filename[MAX_PATH];
404 HANDLE file;
405 DWORD written;
406 INT ret;
408 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
409 "VirtualQuery failed\n");
410 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
411 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
412 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
413 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
414 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
415 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
417 memset( pbmi, 0, sizeof(bmibuf) );
418 memset( data, 0xcc, sizeof(data) );
419 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
420 pbmi->bmiHeader.biHeight = 16;
421 pbmi->bmiHeader.biWidth = 16;
422 pbmi->bmiHeader.biBitCount = 32;
423 pbmi->bmiHeader.biPlanes = 1;
424 pbmi->bmiHeader.biCompression = BI_RGB;
426 hdc = GetDC(0);
428 ret = SetDIBits( hdc, hdib, 0, 16, data, pbmi, DIB_RGB_COLORS );
429 ok(ret == 16, "SetDIBits failed: expected 16 got %d\n", ret);
431 ReleaseDC(0, hdc);
433 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
434 "VirtualQuery failed\n");
435 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
436 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
437 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
438 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
439 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
440 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
442 /* try writing protected bits to a file */
444 GetTempFileNameA( ".", "dib", 0, filename );
445 file = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
446 CREATE_ALWAYS, 0, 0 );
447 ok( file != INVALID_HANDLE_VALUE, "failed to open %s error %u\n", filename, GetLastError() );
448 ret = WriteFile( file, bits, 8192, &written, NULL );
449 ok( ret, "WriteFile failed error %u\n", GetLastError() );
450 if (ret) ok( written == 8192, "only wrote %u bytes\n", written );
451 CloseHandle( file );
452 DeleteFileA( filename );
455 static void test_dibsections(void)
457 HDC hdc, hdcmem, hdcmem2;
458 HBITMAP hdib, oldbm, hdib2, oldbm2;
459 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
460 char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
461 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
462 BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
463 HBITMAP hcoredib;
464 char coreBits[256];
465 BYTE *bits;
466 RGBQUAD rgb[256];
467 int ret;
468 char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
469 LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
470 WORD *index;
471 DWORD *bits32;
472 HPALETTE hpal, oldpal;
473 DIBSECTION dibsec;
474 COLORREF c0, c1;
475 int i;
476 int screen_depth;
477 MEMORY_BASIC_INFORMATION info;
479 hdc = GetDC(0);
480 screen_depth = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
482 memset(pbmi, 0, sizeof(bmibuf));
483 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
484 pbmi->bmiHeader.biHeight = 100;
485 pbmi->bmiHeader.biWidth = 512;
486 pbmi->bmiHeader.biBitCount = 24;
487 pbmi->bmiHeader.biPlanes = 1;
488 pbmi->bmiHeader.biCompression = BI_RGB;
490 SetLastError(0xdeadbeef);
492 /* invalid pointer for BITMAPINFO
493 (*bits should be NULL on error) */
494 bits = (BYTE*)0xdeadbeef;
495 hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
496 ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n");
498 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
499 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
500 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
501 ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
503 /* test the DIB memory */
504 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
505 "VirtualQuery failed\n");
506 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
507 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
508 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
509 ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
510 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
511 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
512 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
514 test_dib_bits_access( hdib, bits );
516 test_dib_info(hdib, bits, &pbmi->bmiHeader);
517 DeleteObject(hdib);
519 /* Test a top-down DIB. */
520 pbmi->bmiHeader.biHeight = -100;
521 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
522 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
523 test_dib_info(hdib, bits, &pbmi->bmiHeader);
524 DeleteObject(hdib);
526 pbmi->bmiHeader.biHeight = 100;
527 pbmi->bmiHeader.biBitCount = 8;
528 pbmi->bmiHeader.biCompression = BI_RLE8;
529 SetLastError(0xdeadbeef);
530 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
531 ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
532 ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
534 for (i = 0; i < 128; i++)
536 pbmi->bmiHeader.biBitCount = i;
537 pbmi->bmiHeader.biCompression = BI_RGB;
538 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
539 if (i == 1 || i == 4 || i == 8 || i == 16 || i == 24 || i == 32)
540 ok(hdib != NULL, "CreateDIBSection bpp %u\n", i);
541 else
542 ok(hdib == NULL, "CreateDIBSection bpp %u succeeded\n", i);
543 if (hdib) DeleteObject( hdib );
546 pbmi->bmiHeader.biBitCount = 16;
547 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
548 ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
549 ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
550 ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
551 SetLastError(0xdeadbeef);
552 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
553 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
555 /* test the DIB memory */
556 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
557 "VirtualQuery failed\n");
558 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
559 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
560 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
561 ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
562 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
563 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
564 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
566 test_dib_info(hdib, bits, &pbmi->bmiHeader);
567 DeleteObject(hdib);
569 memset(pbmi, 0, sizeof(bmibuf));
570 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
571 pbmi->bmiHeader.biHeight = 16;
572 pbmi->bmiHeader.biWidth = 16;
573 pbmi->bmiHeader.biBitCount = 1;
574 pbmi->bmiHeader.biPlanes = 1;
575 pbmi->bmiHeader.biCompression = BI_RGB;
576 pbmi->bmiColors[0].rgbRed = 0xff;
577 pbmi->bmiColors[0].rgbGreen = 0;
578 pbmi->bmiColors[0].rgbBlue = 0;
579 pbmi->bmiColors[1].rgbRed = 0;
580 pbmi->bmiColors[1].rgbGreen = 0;
581 pbmi->bmiColors[1].rgbBlue = 0xff;
583 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
584 ok(hdib != NULL, "CreateDIBSection failed\n");
585 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
586 ok(dibsec.dsBmih.biClrUsed == 2,
587 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
589 /* Test if the old BITMAPCOREINFO structure is supported */
591 pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
592 pbci->bmciHeader.bcBitCount = 0;
594 ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
595 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
596 ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
597 && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
598 "GetDIBits did't fill in the BITMAPCOREHEADER structure properly\n");
600 ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
601 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
602 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
603 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
604 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
605 "The color table has not been translated to the old BITMAPCOREINFO format\n");
607 hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
608 ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
610 ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
611 ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
612 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
613 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
614 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
615 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
616 "The color table has not been translated to the old BITMAPCOREINFO format\n");
618 DeleteObject(hcoredib);
620 hdcmem = CreateCompatibleDC(hdc);
621 oldbm = SelectObject(hdcmem, hdib);
623 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
624 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
625 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
626 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
627 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
628 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
630 c0 = RGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen, pbmi->bmiColors[0].rgbBlue);
631 c1 = RGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen, pbmi->bmiColors[1].rgbBlue);
633 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
634 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
635 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
636 test_color(hdcmem, PALETTEINDEX(0), c0, 1, 1);
637 test_color(hdcmem, PALETTEINDEX(1), c0, 1, 1);
638 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
639 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen,
640 pbmi->bmiColors[0].rgbBlue), c0, 1, 1);
641 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen,
642 pbmi->bmiColors[1].rgbBlue), c1, 1, 1);
643 test_color(hdcmem, PALETTERGB(0, 0, 0), c0, 1, 1);
644 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
645 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1, 1, 1);
647 SelectObject(hdcmem, oldbm);
648 DeleteObject(hdib);
650 pbmi->bmiColors[0].rgbRed = 0xff;
651 pbmi->bmiColors[0].rgbGreen = 0xff;
652 pbmi->bmiColors[0].rgbBlue = 0xff;
653 pbmi->bmiColors[1].rgbRed = 0;
654 pbmi->bmiColors[1].rgbGreen = 0;
655 pbmi->bmiColors[1].rgbBlue = 0;
657 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
658 ok(hdib != NULL, "CreateDIBSection failed\n");
660 test_dib_info(hdib, bits, &pbmi->bmiHeader);
662 oldbm = SelectObject(hdcmem, hdib);
664 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
665 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
666 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
667 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
668 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
669 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
671 SelectObject(hdcmem, oldbm);
672 test_dib_info(hdib, bits, &pbmi->bmiHeader);
673 DeleteObject(hdib);
675 pbmi->bmiHeader.biBitCount = 4;
676 for (i = 0; i < 16; i++) {
677 pbmi->bmiColors[i].rgbRed = i;
678 pbmi->bmiColors[i].rgbGreen = 16-i;
679 pbmi->bmiColors[i].rgbBlue = 0;
681 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
682 ok(hdib != NULL, "CreateDIBSection failed\n");
683 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
684 ok(dibsec.dsBmih.biClrUsed == 16,
685 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
686 test_dib_info(hdib, bits, &pbmi->bmiHeader);
687 DeleteObject(hdib);
689 pbmi->bmiHeader.biBitCount = 8;
691 for (i = 0; i < 128; i++) {
692 pbmi->bmiColors[i].rgbRed = 255 - i * 2;
693 pbmi->bmiColors[i].rgbGreen = i * 2;
694 pbmi->bmiColors[i].rgbBlue = 0;
695 pbmi->bmiColors[255 - i].rgbRed = 0;
696 pbmi->bmiColors[255 - i].rgbGreen = i * 2;
697 pbmi->bmiColors[255 - i].rgbBlue = 255 - i * 2;
699 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
700 ok(hdib != NULL, "CreateDIBSection failed\n");
701 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
702 ok(dibsec.dsBmih.biClrUsed == 256,
703 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
705 oldbm = SelectObject(hdcmem, hdib);
707 for (i = 0; i < 256; i++) {
708 test_color(hdcmem, DIBINDEX(i),
709 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
710 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue),
711 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
714 SelectObject(hdcmem, oldbm);
715 test_dib_info(hdib, bits, &pbmi->bmiHeader);
716 DeleteObject(hdib);
718 pbmi->bmiHeader.biBitCount = 1;
720 /* Now create a palette and a palette indexed dib section */
721 memset(plogpal, 0, sizeof(logpalbuf));
722 plogpal->palVersion = 0x300;
723 plogpal->palNumEntries = 2;
724 plogpal->palPalEntry[0].peRed = 0xff;
725 plogpal->palPalEntry[0].peBlue = 0xff;
726 plogpal->palPalEntry[1].peGreen = 0xff;
728 index = (WORD*)pbmi->bmiColors;
729 *index++ = 0;
730 *index = 1;
731 hpal = CreatePalette(plogpal);
732 ok(hpal != NULL, "CreatePalette failed\n");
733 oldpal = SelectPalette(hdc, hpal, TRUE);
734 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
735 ok(hdib != NULL, "CreateDIBSection failed\n");
736 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
737 ok(dibsec.dsBmih.biClrUsed == 2, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
739 /* The colour table has already been grabbed from the dc, so we select back the
740 old palette */
742 SelectPalette(hdc, oldpal, TRUE);
743 oldbm = SelectObject(hdcmem, hdib);
744 oldpal = SelectPalette(hdcmem, hpal, TRUE);
746 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
747 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
748 ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
749 rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
750 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
751 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
752 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
754 c0 = RGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen, plogpal->palPalEntry[0].peBlue);
755 c1 = RGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen, plogpal->palPalEntry[1].peBlue);
757 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
758 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
759 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
760 test_color(hdcmem, PALETTEINDEX(0), c0, 0, 1);
761 test_color(hdcmem, PALETTEINDEX(1), c1, 0, 1);
762 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
763 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen,
764 plogpal->palPalEntry[0].peBlue), c0, 1, 1);
765 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen,
766 plogpal->palPalEntry[1].peBlue), c1, 1, 1);
767 test_color(hdcmem, PALETTERGB(0, 0, 0), c1, 1, 1);
768 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
769 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0, 1, 1);
770 test_color(hdcmem, PALETTERGB(0, 1, 0), c1, 1, 1);
771 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1, 1, 1);
772 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0, 1, 1);
774 /* Bottom and 2nd row from top green, everything else magenta */
775 bits[0] = bits[1] = 0xff;
776 bits[13 * 4] = bits[13*4 + 1] = 0xff;
778 test_dib_info(hdib, bits, &pbmi->bmiHeader);
780 pbmi->bmiHeader.biBitCount = 32;
782 hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
783 ok(hdib2 != NULL, "CreateDIBSection failed\n");
784 hdcmem2 = CreateCompatibleDC(hdc);
785 oldbm2 = SelectObject(hdcmem2, hdib2);
787 BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
789 ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
790 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
792 SelectObject(hdcmem2, oldbm2);
793 test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
794 DeleteObject(hdib2);
796 SelectObject(hdcmem, oldbm);
797 SelectPalette(hdcmem, oldpal, TRUE);
798 DeleteObject(hdib);
799 DeleteObject(hpal);
802 pbmi->bmiHeader.biBitCount = 8;
804 memset(plogpal, 0, sizeof(logpalbuf));
805 plogpal->palVersion = 0x300;
806 plogpal->palNumEntries = 256;
808 for (i = 0; i < 128; i++) {
809 plogpal->palPalEntry[i].peRed = 255 - i * 2;
810 plogpal->palPalEntry[i].peBlue = i * 2;
811 plogpal->palPalEntry[i].peGreen = 0;
812 plogpal->palPalEntry[255 - i].peRed = 0;
813 plogpal->palPalEntry[255 - i].peGreen = i * 2;
814 plogpal->palPalEntry[255 - i].peBlue = 255 - i * 2;
817 index = (WORD*)pbmi->bmiColors;
818 for (i = 0; i < 256; i++) {
819 *index++ = i;
822 hpal = CreatePalette(plogpal);
823 ok(hpal != NULL, "CreatePalette failed\n");
824 oldpal = SelectPalette(hdc, hpal, TRUE);
825 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
826 ok(hdib != NULL, "CreateDIBSection failed\n");
827 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
828 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
830 test_dib_info(hdib, bits, &pbmi->bmiHeader);
832 SelectPalette(hdc, oldpal, TRUE);
833 oldbm = SelectObject(hdcmem, hdib);
834 oldpal = SelectPalette(hdcmem, hpal, TRUE);
836 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
837 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
838 for (i = 0; i < 256; i++) {
839 ok(rgb[i].rgbRed == plogpal->palPalEntry[i].peRed &&
840 rgb[i].rgbBlue == plogpal->palPalEntry[i].peBlue &&
841 rgb[i].rgbGreen == plogpal->palPalEntry[i].peGreen,
842 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
843 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
846 for (i = 0; i < 256; i++) {
847 test_color(hdcmem, DIBINDEX(i),
848 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
849 test_color(hdcmem, PALETTEINDEX(i),
850 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
851 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue),
852 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
855 SelectPalette(hdcmem, oldpal, TRUE);
856 SelectObject(hdcmem, oldbm);
857 DeleteObject(hdib);
858 DeleteObject(hpal);
860 DeleteDC(hdcmem);
861 DeleteDC(hdcmem2);
862 ReleaseDC(0, hdc);
865 static void test_mono_dibsection(void)
867 HDC hdc, memdc;
868 HBITMAP old_bm, mono_ds;
869 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
870 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
871 BYTE bits[10 * 4];
872 BYTE *ds_bits;
873 int num;
875 hdc = GetDC(0);
877 memdc = CreateCompatibleDC(hdc);
879 memset(pbmi, 0, sizeof(bmibuf));
880 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
881 pbmi->bmiHeader.biHeight = 10;
882 pbmi->bmiHeader.biWidth = 10;
883 pbmi->bmiHeader.biBitCount = 1;
884 pbmi->bmiHeader.biPlanes = 1;
885 pbmi->bmiHeader.biCompression = BI_RGB;
886 pbmi->bmiColors[0].rgbRed = 0xff;
887 pbmi->bmiColors[0].rgbGreen = 0xff;
888 pbmi->bmiColors[0].rgbBlue = 0xff;
889 pbmi->bmiColors[1].rgbRed = 0x0;
890 pbmi->bmiColors[1].rgbGreen = 0x0;
891 pbmi->bmiColors[1].rgbBlue = 0x0;
894 * First dib section is 'inverted' ie color[0] is white, color[1] is black
897 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
898 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
899 old_bm = SelectObject(memdc, mono_ds);
901 /* black border, white interior */
902 Rectangle(memdc, 0, 0, 10, 10);
903 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
904 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
906 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
908 memset(bits, 0, sizeof(bits));
909 bits[0] = 0xaa;
911 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
912 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
914 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
916 pbmi->bmiColors[0].rgbRed = 0x0;
917 pbmi->bmiColors[0].rgbGreen = 0x0;
918 pbmi->bmiColors[0].rgbBlue = 0x0;
919 pbmi->bmiColors[1].rgbRed = 0xff;
920 pbmi->bmiColors[1].rgbGreen = 0xff;
921 pbmi->bmiColors[1].rgbBlue = 0xff;
923 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
924 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
926 SelectObject(memdc, old_bm);
927 DeleteObject(mono_ds);
930 * Next dib section is 'normal' ie color[0] is black, color[1] is white
933 pbmi->bmiColors[0].rgbRed = 0x0;
934 pbmi->bmiColors[0].rgbGreen = 0x0;
935 pbmi->bmiColors[0].rgbBlue = 0x0;
936 pbmi->bmiColors[1].rgbRed = 0xff;
937 pbmi->bmiColors[1].rgbGreen = 0xff;
938 pbmi->bmiColors[1].rgbBlue = 0xff;
940 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
941 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
942 old_bm = SelectObject(memdc, mono_ds);
944 /* black border, white interior */
945 Rectangle(memdc, 0, 0, 10, 10);
946 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
947 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
949 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
951 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
952 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
954 /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
956 pbmi->bmiColors[0].rgbRed = 0xff;
957 pbmi->bmiColors[0].rgbGreen = 0xff;
958 pbmi->bmiColors[0].rgbBlue = 0xff;
959 pbmi->bmiColors[1].rgbRed = 0x0;
960 pbmi->bmiColors[1].rgbGreen = 0x0;
961 pbmi->bmiColors[1].rgbBlue = 0x0;
963 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
964 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
967 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
970 pbmi->bmiColors[0].rgbRed = 0xff;
971 pbmi->bmiColors[0].rgbGreen = 0xff;
972 pbmi->bmiColors[0].rgbBlue = 0xff;
973 pbmi->bmiColors[1].rgbRed = 0x0;
974 pbmi->bmiColors[1].rgbGreen = 0x0;
975 pbmi->bmiColors[1].rgbBlue = 0x0;
976 num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors);
977 ok(num == 2, "num = %d\n", num);
979 /* black border, white interior */
980 Rectangle(memdc, 0, 0, 10, 10);
981 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
982 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
984 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
986 memset(bits, 0, sizeof(bits));
987 bits[0] = 0xaa;
989 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
990 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
992 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
994 pbmi->bmiColors[0].rgbRed = 0x0;
995 pbmi->bmiColors[0].rgbGreen = 0x0;
996 pbmi->bmiColors[0].rgbBlue = 0x0;
997 pbmi->bmiColors[1].rgbRed = 0xff;
998 pbmi->bmiColors[1].rgbGreen = 0xff;
999 pbmi->bmiColors[1].rgbBlue = 0xff;
1001 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1002 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1004 SelectObject(memdc, old_bm);
1005 DeleteObject(mono_ds);
1008 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
1011 pbmi->bmiColors[0].rgbRed = 0xff;
1012 pbmi->bmiColors[0].rgbGreen = 0x0;
1013 pbmi->bmiColors[0].rgbBlue = 0x0;
1014 pbmi->bmiColors[1].rgbRed = 0xfe;
1015 pbmi->bmiColors[1].rgbGreen = 0x0;
1016 pbmi->bmiColors[1].rgbBlue = 0x0;
1018 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1019 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1020 old_bm = SelectObject(memdc, mono_ds);
1022 /* black border, white interior */
1023 Rectangle(memdc, 0, 0, 10, 10);
1024 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1025 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1027 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1029 pbmi->bmiColors[0].rgbRed = 0x0;
1030 pbmi->bmiColors[0].rgbGreen = 0x0;
1031 pbmi->bmiColors[0].rgbBlue = 0x0;
1032 pbmi->bmiColors[1].rgbRed = 0xff;
1033 pbmi->bmiColors[1].rgbGreen = 0xff;
1034 pbmi->bmiColors[1].rgbBlue = 0xff;
1036 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1037 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1039 /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
1041 pbmi->bmiColors[0].rgbRed = 0xff;
1042 pbmi->bmiColors[0].rgbGreen = 0xff;
1043 pbmi->bmiColors[0].rgbBlue = 0xff;
1044 pbmi->bmiColors[1].rgbRed = 0x0;
1045 pbmi->bmiColors[1].rgbGreen = 0x0;
1046 pbmi->bmiColors[1].rgbBlue = 0x0;
1048 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1049 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1051 SelectObject(memdc, old_bm);
1052 DeleteObject(mono_ds);
1054 DeleteDC(memdc);
1055 ReleaseDC(0, hdc);
1058 static void test_bitmap(void)
1060 char buf[256], buf_cmp[256];
1061 HBITMAP hbmp, hbmp_old;
1062 HDC hdc;
1063 BITMAP bm;
1064 BITMAP bma[2];
1065 INT ret;
1067 hdc = CreateCompatibleDC(0);
1068 assert(hdc != 0);
1070 SetLastError(0xdeadbeef);
1071 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1072 if (!hbmp)
1074 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1075 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1076 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1078 else
1079 DeleteObject(hbmp);
1081 SetLastError(0xdeadbeef);
1082 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1083 if (!hbmp)
1085 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1086 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1087 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1089 else
1090 DeleteObject(hbmp);
1092 SetLastError(0xdeadbeef);
1093 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1094 ok(!hbmp, "CreateBitmap should fail\n");
1095 if (!hbmp)
1096 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1097 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1098 else
1099 DeleteObject(hbmp);
1101 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1102 assert(hbmp != NULL);
1104 ret = GetObject(hbmp, sizeof(bm), &bm);
1105 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1107 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1108 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1109 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1110 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1111 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1112 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1113 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1115 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1116 assert(sizeof(buf) == sizeof(buf_cmp));
1118 ret = GetBitmapBits(hbmp, 0, NULL);
1119 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1121 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1122 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1124 memset(buf, 0xAA, sizeof(buf));
1125 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1126 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1127 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1129 hbmp_old = SelectObject(hdc, hbmp);
1131 ret = GetObject(hbmp, sizeof(bm), &bm);
1132 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1134 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1135 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1136 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1137 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1138 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1139 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1140 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1142 memset(buf, 0xAA, sizeof(buf));
1143 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1144 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1145 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1147 hbmp_old = SelectObject(hdc, hbmp_old);
1148 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1150 /* test various buffer sizes for GetObject */
1151 ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
1152 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1154 ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1155 ok(ret == 0, "%d != 0\n", ret);
1157 ret = GetObject(hbmp, 0, &bm);
1158 ok(ret == 0, "%d != 0\n", ret);
1160 ret = GetObject(hbmp, 1, &bm);
1161 ok(ret == 0, "%d != 0\n", ret);
1163 DeleteObject(hbmp);
1164 DeleteDC(hdc);
1167 static void test_bmBits(void)
1169 BYTE bits[4];
1170 HBITMAP hbmp;
1171 BITMAP bmp;
1173 memset(bits, 0, sizeof(bits));
1174 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1175 ok(hbmp != NULL, "CreateBitmap failed\n");
1177 memset(&bmp, 0xFF, sizeof(bmp));
1178 ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1179 "GetObject failed or returned a wrong structure size\n");
1180 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1182 DeleteObject(hbmp);
1185 static void test_GetDIBits_selected_DIB(UINT bpp)
1187 HBITMAP dib;
1188 char bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1189 char bmibuf2[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1190 BITMAPINFO *info = (BITMAPINFO *)bmibuf;
1191 BITMAPINFO *info2 = (BITMAPINFO *)bmibuf2;
1192 void * bits;
1193 void * bits2;
1194 UINT dib_size, dib32_size;
1195 DWORD pixel;
1196 HDC dib_dc, dc;
1197 HBITMAP old_bmp;
1198 UINT i;
1199 int res;
1201 /* Create a DIB section with a color table */
1203 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1204 info->bmiHeader.biWidth = 32;
1205 info->bmiHeader.biHeight = 32;
1206 info->bmiHeader.biPlanes = 1;
1207 info->bmiHeader.biBitCount = bpp;
1208 info->bmiHeader.biCompression = BI_RGB;
1209 info->bmiHeader.biXPelsPerMeter = 0;
1210 info->bmiHeader.biYPelsPerMeter = 0;
1211 info->bmiHeader.biClrUsed = 0;
1212 info->bmiHeader.biClrImportant = 0;
1214 for (i=0; i < (1u << bpp); i++)
1216 BYTE c = i * (1 << (8 - bpp));
1217 info->bmiColors[i].rgbRed = c;
1218 info->bmiColors[i].rgbGreen = c;
1219 info->bmiColors[i].rgbBlue = c;
1220 info->bmiColors[i].rgbReserved = 0;
1223 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1224 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1225 dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1227 /* Set the bits of the DIB section */
1228 for (i=0; i < dib_size; i++)
1230 ((BYTE *)bits)[i] = i % 256;
1233 /* Select the DIB into a DC */
1234 dib_dc = CreateCompatibleDC(NULL);
1235 old_bmp = SelectObject(dib_dc, dib);
1236 dc = CreateCompatibleDC(NULL);
1237 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
1239 /* Copy the DIB attributes but not the color table */
1240 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1242 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1243 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1245 /* Compare the color table and the bits */
1246 for (i=0; i < (1u << bpp); i++)
1247 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1248 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1249 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1250 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1251 "color table entry %d differs (bpp %d)\n", i, bpp );
1253 ok( !memcmp( bits, bits2, dib_size ), "bit mismatch (bpp %d)\n", bpp );
1255 /* Test various combinations of lines = 0 and bits2 = NULL */
1256 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1257 res = GetDIBits( dc, dib, 0, 0, bits2, info2, DIB_RGB_COLORS );
1258 todo_wine
1259 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1260 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1261 "color table mismatch (bpp %d)\n", bpp );
1263 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1264 res = GetDIBits( dc, dib, 0, 0, NULL, info2, DIB_RGB_COLORS );
1265 todo_wine
1266 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1267 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1268 "color table mismatch (bpp %d)\n", bpp );
1270 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1271 res = GetDIBits( dc, dib, 0, info->bmiHeader.biHeight, NULL, info2, DIB_RGB_COLORS );
1272 todo_wine
1273 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1274 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1275 "color table mismatch (bpp %d)\n", bpp );
1277 /* Map into a 32bit-DIB */
1278 info2->bmiHeader.biBitCount = 32;
1279 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1280 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1282 /* Check if last pixel was set */
1283 pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
1284 ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
1286 HeapFree(GetProcessHeap(), 0, bits2);
1287 DeleteDC(dc);
1289 SelectObject(dib_dc, old_bmp);
1290 DeleteDC(dib_dc);
1291 DeleteObject(dib);
1294 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1296 HBITMAP ddb;
1297 char bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1298 char bmibuf2[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1299 BITMAPINFO *info = (BITMAPINFO *)bmibuf;
1300 BITMAPINFO *info2 = (BITMAPINFO *)bmibuf2;
1301 void * bits;
1302 void * bits2;
1303 HDC ddb_dc, dc;
1304 HBITMAP old_bmp;
1305 UINT width, height;
1306 UINT bpp;
1307 UINT i, j;
1308 int res;
1310 width = height = 16;
1312 /* Create a DDB (device-dependent bitmap) */
1313 if (monochrome)
1315 bpp = 1;
1316 ddb = CreateBitmap(width, height, 1, 1, NULL);
1318 else
1320 HDC screen_dc = GetDC(NULL);
1321 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1322 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1323 ReleaseDC(NULL, screen_dc);
1326 /* Set the pixels */
1327 ddb_dc = CreateCompatibleDC(NULL);
1328 old_bmp = SelectObject(ddb_dc, ddb);
1329 for (i = 0; i < width; i++)
1331 for (j=0; j < height; j++)
1333 BYTE c = (i * width + j) % 256;
1334 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1337 SelectObject(ddb_dc, old_bmp);
1339 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1340 info->bmiHeader.biWidth = width;
1341 info->bmiHeader.biHeight = height;
1342 info->bmiHeader.biPlanes = 1;
1343 info->bmiHeader.biBitCount = bpp;
1344 info->bmiHeader.biCompression = BI_RGB;
1346 dc = CreateCompatibleDC(NULL);
1348 /* Fill in biSizeImage */
1349 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1350 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1352 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1353 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1355 /* Get the bits */
1356 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1357 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1359 /* Copy the DIB attributes but not the color table */
1360 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1362 /* Select the DDB into another DC */
1363 old_bmp = SelectObject(ddb_dc, ddb);
1365 /* Get the bits */
1366 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1367 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1369 /* Compare the color table and the bits */
1370 if (bpp <= 8)
1372 for (i=0; i < (1u << bpp); i++)
1373 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1374 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1375 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1376 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1377 "color table entry %d differs (bpp %d)\n", i, bpp );
1380 ok( !memcmp( bits, bits2, info->bmiHeader.biSizeImage ), "bit mismatch (bpp %d)\n", bpp );
1382 /* Test the palette */
1383 if (info2->bmiHeader.biBitCount <= 8)
1385 WORD *colors = (WORD*)info2->bmiColors;
1387 /* Get the palette indices */
1388 res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1389 todo_wine
1390 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1392 for (i = 0; i < (1 << info->bmiHeader.biBitCount); i++)
1393 ok( colors[i] == i, "%d: got %d (bpp %d)\n", i, colors[i], bpp );
1396 HeapFree(GetProcessHeap(), 0, bits2);
1397 HeapFree(GetProcessHeap(), 0, bits);
1398 DeleteDC(dc);
1400 SelectObject(ddb_dc, old_bmp);
1401 DeleteDC(ddb_dc);
1402 DeleteObject(ddb);
1405 static void test_GetDIBits(void)
1407 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1408 static const BYTE bmp_bits_1[16 * 2] =
1410 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1411 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1412 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1413 0xff,0xff, 0,0, 0xff,0xff, 0,0
1415 /* 4-bytes aligned 1-bit DIB data: 16x16 */
1416 static const BYTE dib_bits_1[16 * 4] =
1418 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1419 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1420 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1421 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1423 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1424 static const BYTE bmp_bits_24[16 * 16*3] =
1426 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1427 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1428 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1429 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1430 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1431 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1432 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1433 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1434 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1435 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1436 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1437 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1438 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1439 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1440 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1441 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1442 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1443 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1444 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1445 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1446 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1447 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1448 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1449 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1450 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1451 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1452 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1453 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1454 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1455 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1456 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1457 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1459 /* 4-bytes aligned 24-bit DIB data: 16x16 */
1460 static const BYTE dib_bits_24[16 * 16*3] =
1462 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1463 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1464 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1465 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1466 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1467 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1468 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1469 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1470 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1471 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1472 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1473 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1474 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1475 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1476 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1477 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1478 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1479 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1480 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1481 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1482 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1483 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1484 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1485 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1486 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1487 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1488 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1489 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1490 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1491 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1492 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1493 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1495 HBITMAP hbmp;
1496 BITMAP bm;
1497 HDC hdc;
1498 int i, bytes, lines;
1499 BYTE buf[1024];
1500 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1501 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1502 PALETTEENTRY pal_ents[20];
1504 hdc = GetDC(0);
1506 /* 1-bit source bitmap data */
1507 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1508 ok(hbmp != 0, "CreateBitmap failed\n");
1510 memset(&bm, 0xAA, sizeof(bm));
1511 bytes = GetObject(hbmp, sizeof(bm), &bm);
1512 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1513 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1514 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1515 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1516 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1517 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1518 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1519 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1521 bytes = GetBitmapBits(hbmp, 0, NULL);
1522 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1523 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1524 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1525 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1527 /* retrieve 1-bit DIB data */
1528 memset(bi, 0, sizeof(*bi));
1529 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1530 bi->bmiHeader.biWidth = bm.bmWidth;
1531 bi->bmiHeader.biHeight = bm.bmHeight;
1532 bi->bmiHeader.biPlanes = 1;
1533 bi->bmiHeader.biBitCount = 1;
1534 bi->bmiHeader.biCompression = BI_RGB;
1535 bi->bmiHeader.biSizeImage = 0;
1536 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1537 SetLastError(0xdeadbeef);
1538 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1539 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1540 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1541 broken(GetLastError() == 0xdeadbeef), /* winnt */
1542 "wrong error %u\n", GetLastError());
1543 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1545 memset(buf, 0xAA, sizeof(buf));
1546 SetLastError(0xdeadbeef);
1547 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1548 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1549 lines, bm.bmHeight, GetLastError());
1550 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1552 /* the color table consists of black and white */
1553 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1554 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1555 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1556 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1557 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1558 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1559 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1560 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1561 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1562 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1563 for (i = 2; i < 256; i++)
1565 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1566 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1567 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1568 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1569 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1572 /* returned bits are DWORD aligned and upside down */
1573 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1575 /* Test the palette indices */
1576 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1577 SetLastError(0xdeadbeef);
1578 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1579 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1580 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1581 for (i = 2; i < 256; i++)
1582 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[1]);
1584 /* retrieve 24-bit DIB data */
1585 memset(bi, 0, sizeof(*bi));
1586 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1587 bi->bmiHeader.biWidth = bm.bmWidth;
1588 bi->bmiHeader.biHeight = bm.bmHeight;
1589 bi->bmiHeader.biPlanes = 1;
1590 bi->bmiHeader.biBitCount = 24;
1591 bi->bmiHeader.biCompression = BI_RGB;
1592 bi->bmiHeader.biSizeImage = 0;
1593 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1594 memset(buf, 0xAA, sizeof(buf));
1595 SetLastError(0xdeadbeef);
1596 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1597 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1598 lines, bm.bmHeight, GetLastError());
1599 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1601 /* the color table doesn't exist for 24-bit images */
1602 for (i = 0; i < 256; i++)
1604 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1605 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1606 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1607 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1608 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1611 /* returned bits are DWORD aligned and upside down */
1612 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1613 DeleteObject(hbmp);
1615 /* 24-bit source bitmap data */
1616 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1617 ok(hbmp != 0, "CreateBitmap failed\n");
1618 SetLastError(0xdeadbeef);
1619 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1620 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1621 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1622 lines, bm.bmHeight, GetLastError());
1624 memset(&bm, 0xAA, sizeof(bm));
1625 bytes = GetObject(hbmp, sizeof(bm), &bm);
1626 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1627 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1628 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1629 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1630 ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1631 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1632 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1633 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1635 bytes = GetBitmapBits(hbmp, 0, NULL);
1636 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
1637 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1638 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1639 bm.bmWidthBytes * bm.bmHeight, bytes);
1641 /* retrieve 1-bit DIB data */
1642 memset(bi, 0, sizeof(*bi));
1643 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1644 bi->bmiHeader.biWidth = bm.bmWidth;
1645 bi->bmiHeader.biHeight = bm.bmHeight;
1646 bi->bmiHeader.biPlanes = 1;
1647 bi->bmiHeader.biBitCount = 1;
1648 bi->bmiHeader.biCompression = BI_RGB;
1649 bi->bmiHeader.biSizeImage = 0;
1650 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1651 memset(buf, 0xAA, sizeof(buf));
1652 SetLastError(0xdeadbeef);
1653 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1654 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1655 lines, bm.bmHeight, GetLastError());
1656 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1658 /* the color table consists of black and white */
1659 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1660 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1661 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1662 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1663 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1664 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1665 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1666 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1667 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1668 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1669 for (i = 2; i < 256; i++)
1671 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1672 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1673 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1674 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1675 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1678 /* returned bits are DWORD aligned and upside down */
1679 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1681 /* Test the palette indices */
1682 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1683 SetLastError(0xdeadbeef);
1684 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1685 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1686 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1687 for (i = 2; i < 256; i++)
1688 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[i]);
1690 /* retrieve 4-bit DIB data */
1691 memset(bi, 0, sizeof(*bi));
1692 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1693 bi->bmiHeader.biWidth = bm.bmWidth;
1694 bi->bmiHeader.biHeight = bm.bmHeight;
1695 bi->bmiHeader.biPlanes = 1;
1696 bi->bmiHeader.biBitCount = 4;
1697 bi->bmiHeader.biCompression = BI_RGB;
1698 bi->bmiHeader.biSizeImage = 0;
1699 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1700 memset(buf, 0xAA, sizeof(buf));
1701 SetLastError(0xdeadbeef);
1702 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1703 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1704 lines, bm.bmHeight, GetLastError());
1706 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
1708 for (i = 0; i < 16; i++)
1710 RGBQUAD expect;
1711 int entry = i < 8 ? i : i + 4;
1713 if(entry == 7) entry = 12;
1714 else if(entry == 12) entry = 7;
1716 expect.rgbRed = pal_ents[entry].peRed;
1717 expect.rgbGreen = pal_ents[entry].peGreen;
1718 expect.rgbBlue = pal_ents[entry].peBlue;
1719 expect.rgbReserved = 0;
1721 ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
1722 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
1723 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
1724 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1725 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1728 /* retrieve 8-bit DIB data */
1729 memset(bi, 0, sizeof(*bi));
1730 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1731 bi->bmiHeader.biWidth = bm.bmWidth;
1732 bi->bmiHeader.biHeight = bm.bmHeight;
1733 bi->bmiHeader.biPlanes = 1;
1734 bi->bmiHeader.biBitCount = 8;
1735 bi->bmiHeader.biCompression = BI_RGB;
1736 bi->bmiHeader.biSizeImage = 0;
1737 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1738 memset(buf, 0xAA, sizeof(buf));
1739 SetLastError(0xdeadbeef);
1740 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1741 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1742 lines, bm.bmHeight, GetLastError());
1744 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
1746 for (i = 0; i < 256; i++)
1748 RGBQUAD expect;
1750 if (i < 10 || i >= 246)
1752 int entry = i < 10 ? i : i - 236;
1753 expect.rgbRed = pal_ents[entry].peRed;
1754 expect.rgbGreen = pal_ents[entry].peGreen;
1755 expect.rgbBlue = pal_ents[entry].peBlue;
1757 else
1759 expect.rgbRed = (i & 0x07) << 5;
1760 expect.rgbGreen = (i & 0x38) << 2;
1761 expect.rgbBlue = i & 0xc0;
1763 expect.rgbReserved = 0;
1765 ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
1766 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
1767 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
1768 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1769 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1772 /* retrieve 24-bit DIB data */
1773 memset(bi, 0, sizeof(*bi));
1774 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1775 bi->bmiHeader.biWidth = bm.bmWidth;
1776 bi->bmiHeader.biHeight = bm.bmHeight;
1777 bi->bmiHeader.biPlanes = 1;
1778 bi->bmiHeader.biBitCount = 24;
1779 bi->bmiHeader.biCompression = BI_RGB;
1780 bi->bmiHeader.biSizeImage = 0;
1781 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1782 memset(buf, 0xAA, sizeof(buf));
1783 SetLastError(0xdeadbeef);
1784 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1785 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1786 lines, bm.bmHeight, GetLastError());
1787 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1789 /* the color table doesn't exist for 24-bit images */
1790 for (i = 0; i < 256; i++)
1792 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1793 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1794 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1795 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1796 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1799 /* returned bits are DWORD aligned and upside down */
1800 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1801 DeleteObject(hbmp);
1803 ReleaseDC(0, hdc);
1806 static void test_GetDIBits_BI_BITFIELDS(void)
1808 /* Try a screen resolution detection technique
1809 * from the September 1999 issue of Windows Developer's Journal
1810 * which seems to be in widespread use.
1811 * http://www.lesher.ws/highcolor.html
1812 * http://www.lesher.ws/vidfmt.c
1813 * It hinges on being able to retrieve the bitmaps
1814 * for the three primary colors in non-paletted 16 bit mode.
1816 char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
1817 DWORD bits[32];
1818 LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
1819 DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
1820 HDC hdc;
1821 HBITMAP hbm;
1822 int ret;
1823 void *ptr;
1825 memset(dibinfo, 0, sizeof(dibinfo_buf));
1826 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1828 hdc = GetDC(NULL);
1829 ok(hdc != NULL, "GetDC failed?\n");
1830 hbm = CreateCompatibleBitmap(hdc, 1, 1);
1831 ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
1833 /* Call GetDIBits to fill in bmiHeader. */
1834 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1835 ok(ret == 1, "GetDIBits failed\n");
1836 if (dibinfo->bmiHeader.biBitCount > 8)
1838 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
1839 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
1840 "compression is %u (%d bpp)\n", dibinfo->bmiHeader.biCompression, dibinfo->bmiHeader.biBitCount );
1842 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
1844 ok( !bitmasks[0], "red mask is set\n" );
1845 ok( !bitmasks[1], "green mask is set\n" );
1846 ok( !bitmasks[2], "blue mask is set\n" );
1848 /* test with NULL bits pointer and correct bpp */
1849 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1850 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1851 ok(ret == 1, "GetDIBits failed\n");
1853 ok( bitmasks[0] != 0, "red mask is not set\n" );
1854 ok( bitmasks[1] != 0, "green mask is not set\n" );
1855 ok( bitmasks[2] != 0, "blue mask is not set\n" );
1856 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1858 /* test with valid bits pointer */
1859 memset(dibinfo, 0, sizeof(dibinfo_buf));
1860 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1861 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1862 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1863 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1864 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
1865 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1867 ok( bitmasks[0] != 0, "red mask is not set\n" );
1868 ok( bitmasks[1] != 0, "green mask is not set\n" );
1869 ok( bitmasks[2] != 0, "blue mask is not set\n" );
1870 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1872 /* now with bits and 0 lines */
1873 memset(dibinfo, 0, sizeof(dibinfo_buf));
1874 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1875 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1876 SetLastError(0xdeadbeef);
1877 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
1878 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1880 ok( !bitmasks[0], "red mask is set\n" );
1881 ok( !bitmasks[1], "green mask is set\n" );
1882 ok( !bitmasks[2], "blue mask is set\n" );
1883 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1885 memset(bitmasks, 0, 3*sizeof(DWORD));
1886 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1887 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
1888 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1890 ok( bitmasks[0] != 0, "red mask is not set\n" );
1891 ok( bitmasks[1] != 0, "green mask is not set\n" );
1892 ok( bitmasks[2] != 0, "blue mask is not set\n" );
1893 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1896 else skip("bitmap in colortable mode, skipping BI_BITFIELDS tests\n");
1898 DeleteObject(hbm);
1900 /* same thing now with a 32-bpp DIB section */
1902 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1903 dibinfo->bmiHeader.biWidth = 1;
1904 dibinfo->bmiHeader.biHeight = 1;
1905 dibinfo->bmiHeader.biPlanes = 1;
1906 dibinfo->bmiHeader.biBitCount = 32;
1907 dibinfo->bmiHeader.biCompression = BI_RGB;
1908 dibinfo->bmiHeader.biSizeImage = 0;
1909 dibinfo->bmiHeader.biXPelsPerMeter = 0;
1910 dibinfo->bmiHeader.biYPelsPerMeter = 0;
1911 dibinfo->bmiHeader.biClrUsed = 0;
1912 dibinfo->bmiHeader.biClrImportant = 0;
1913 bitmasks[0] = 0x0000ff;
1914 bitmasks[1] = 0x00ff00;
1915 bitmasks[2] = 0xff0000;
1916 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
1917 ok( hbm != 0, "failed to create bitmap\n" );
1919 memset(dibinfo, 0, sizeof(dibinfo_buf));
1920 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1921 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
1922 ok(ret == 1, "GetDIBits failed\n");
1923 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
1925 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
1926 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
1927 "compression is %u\n", dibinfo->bmiHeader.biCompression );
1928 ok( !bitmasks[0], "red mask is set\n" );
1929 ok( !bitmasks[1], "green mask is set\n" );
1930 ok( !bitmasks[2], "blue mask is set\n" );
1932 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1933 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
1934 ok(ret == 1, "GetDIBits failed\n");
1935 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
1936 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
1937 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
1938 "compression is %u\n", dibinfo->bmiHeader.biCompression );
1939 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
1941 ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
1942 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
1943 ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
1945 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1947 DeleteObject(hbm);
1949 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1950 dibinfo->bmiHeader.biWidth = 1;
1951 dibinfo->bmiHeader.biHeight = 1;
1952 dibinfo->bmiHeader.biPlanes = 1;
1953 dibinfo->bmiHeader.biBitCount = 32;
1954 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
1955 dibinfo->bmiHeader.biSizeImage = 0;
1956 dibinfo->bmiHeader.biXPelsPerMeter = 0;
1957 dibinfo->bmiHeader.biYPelsPerMeter = 0;
1958 dibinfo->bmiHeader.biClrUsed = 0;
1959 dibinfo->bmiHeader.biClrImportant = 0;
1960 bitmasks[0] = 0x0000ff;
1961 bitmasks[1] = 0x00ff00;
1962 bitmasks[2] = 0xff0000;
1963 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
1964 ok( hbm != 0, "failed to create bitmap\n" );
1966 if (hbm)
1968 memset(dibinfo, 0, sizeof(dibinfo_buf));
1969 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1970 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
1971 ok(ret == 1, "GetDIBits failed\n");
1973 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
1974 "compression is %u\n", dibinfo->bmiHeader.biCompression );
1975 ok( !bitmasks[0], "red mask is set\n" );
1976 ok( !bitmasks[1], "green mask is set\n" );
1977 ok( !bitmasks[2], "blue mask is set\n" );
1979 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1980 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
1981 ok(ret == 1, "GetDIBits failed\n");
1982 ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
1983 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
1984 ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
1985 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1987 DeleteObject(hbm);
1990 /* 24-bpp DIB sections don't have bitfields */
1992 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1993 dibinfo->bmiHeader.biWidth = 1;
1994 dibinfo->bmiHeader.biHeight = 1;
1995 dibinfo->bmiHeader.biPlanes = 1;
1996 dibinfo->bmiHeader.biBitCount = 24;
1997 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
1998 dibinfo->bmiHeader.biSizeImage = 0;
1999 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2000 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2001 dibinfo->bmiHeader.biClrUsed = 0;
2002 dibinfo->bmiHeader.biClrImportant = 0;
2003 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2004 ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
2005 dibinfo->bmiHeader.biCompression = BI_RGB;
2006 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2007 ok( hbm != 0, "failed to create bitmap\n" );
2009 memset(dibinfo, 0, sizeof(dibinfo_buf));
2010 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2011 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2012 ok(ret == 1, "GetDIBits failed\n");
2013 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2015 ok( dibinfo->bmiHeader.biCompression == BI_RGB,
2016 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2017 ok( !bitmasks[0], "red mask is set\n" );
2018 ok( !bitmasks[1], "green mask is set\n" );
2019 ok( !bitmasks[2], "blue mask is set\n" );
2021 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2022 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2023 ok(ret == 1, "GetDIBits failed\n");
2024 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2025 ok( !bitmasks[0], "red mask is set\n" );
2026 ok( !bitmasks[1], "green mask is set\n" );
2027 ok( !bitmasks[2], "blue mask is set\n" );
2028 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2030 DeleteObject(hbm);
2031 ReleaseDC(NULL, hdc);
2034 static void test_select_object(void)
2036 HDC hdc;
2037 HBITMAP hbm, hbm_old;
2038 INT planes, bpp, i;
2039 DWORD depths[] = {8, 15, 16, 24, 32};
2040 BITMAP bm;
2041 DWORD bytes;
2043 hdc = GetDC(0);
2044 ok(hdc != 0, "GetDC(0) failed\n");
2045 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2046 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2048 hbm_old = SelectObject(hdc, hbm);
2049 ok(hbm_old == 0, "SelectObject should fail\n");
2051 DeleteObject(hbm);
2052 ReleaseDC(0, hdc);
2054 hdc = CreateCompatibleDC(0);
2055 ok(hdc != 0, "GetDC(0) failed\n");
2056 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2057 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2059 hbm_old = SelectObject(hdc, hbm);
2060 ok(hbm_old != 0, "SelectObject failed\n");
2061 hbm_old = SelectObject(hdc, hbm_old);
2062 ok(hbm_old == hbm, "SelectObject failed\n");
2064 DeleteObject(hbm);
2066 /* test an 1-bpp bitmap */
2067 planes = GetDeviceCaps(hdc, PLANES);
2068 bpp = 1;
2070 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
2071 ok(hbm != 0, "CreateBitmap failed\n");
2073 hbm_old = SelectObject(hdc, hbm);
2074 ok(hbm_old != 0, "SelectObject failed\n");
2075 hbm_old = SelectObject(hdc, hbm_old);
2076 ok(hbm_old == hbm, "SelectObject failed\n");
2078 DeleteObject(hbm);
2080 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
2081 /* test a color bitmap to dc bpp matching */
2082 planes = GetDeviceCaps(hdc, PLANES);
2083 bpp = GetDeviceCaps(hdc, BITSPIXEL);
2085 hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
2086 ok(hbm != 0, "CreateBitmap failed\n");
2088 hbm_old = SelectObject(hdc, hbm);
2089 if(depths[i] == bpp ||
2090 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
2092 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
2093 SelectObject(hdc, hbm_old);
2094 } else {
2095 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
2098 memset(&bm, 0xAA, sizeof(bm));
2099 bytes = GetObject(hbm, sizeof(bm), &bm);
2100 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2101 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2102 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
2103 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
2104 ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2105 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
2106 if(depths[i] == 15) {
2107 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
2108 } else {
2109 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2111 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2113 DeleteObject(hbm);
2116 DeleteDC(hdc);
2119 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
2121 INT ret;
2122 BITMAP bm;
2124 ret = GetObjectType(hbmp);
2125 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
2127 ret = GetObject(hbmp, 0, 0);
2128 ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
2130 memset(&bm, 0xDA, sizeof(bm));
2131 SetLastError(0xdeadbeef);
2132 ret = GetObject(hbmp, sizeof(bm), &bm);
2133 if (!ret) /* XP, only for curObj2 */ return;
2134 ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
2135 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2136 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2137 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2138 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2139 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2140 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2141 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2144 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2146 static void test_CreateBitmap(void)
2148 BITMAP bmp;
2149 HDC screenDC = GetDC(0);
2150 HDC hdc = CreateCompatibleDC(screenDC);
2151 UINT i, expect = 0;
2153 /* all of these are the stock monochrome bitmap */
2154 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2155 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2156 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2157 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2158 HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2159 HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2161 /* these 2 are not the stock monochrome bitmap */
2162 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2163 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2165 HBITMAP old1 = SelectObject(hdc, bm2);
2166 HBITMAP old2 = SelectObject(screenDC, bm3);
2167 SelectObject(hdc, old1);
2168 SelectObject(screenDC, old2);
2170 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2171 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2172 bm, bm1, bm4, bm5, curObj1, old1);
2173 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2174 todo_wine
2175 ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
2176 ok(old2 == 0, "old2 %p\n", old2);
2178 test_mono_1x1_bmp(bm);
2179 test_mono_1x1_bmp(bm1);
2180 test_mono_1x1_bmp(bm2);
2181 test_mono_1x1_bmp(bm3);
2182 test_mono_1x1_bmp(bm4);
2183 test_mono_1x1_bmp(bm5);
2184 test_mono_1x1_bmp(old1);
2185 test_mono_1x1_bmp(curObj1);
2187 DeleteObject(bm);
2188 DeleteObject(bm1);
2189 DeleteObject(bm2);
2190 DeleteObject(bm3);
2191 DeleteObject(bm4);
2192 DeleteObject(bm5);
2194 DeleteDC(hdc);
2195 ReleaseDC(0, screenDC);
2197 /* show that Windows ignores the provided bm.bmWidthBytes */
2198 bmp.bmType = 0;
2199 bmp.bmWidth = 1;
2200 bmp.bmHeight = 1;
2201 bmp.bmWidthBytes = 28;
2202 bmp.bmPlanes = 1;
2203 bmp.bmBitsPixel = 1;
2204 bmp.bmBits = NULL;
2205 bm = CreateBitmapIndirect(&bmp);
2206 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2207 test_mono_1x1_bmp(bm);
2208 DeleteObject(bm);
2210 /* Test how the bmBitsPixel field is treated */
2211 for(i = 1; i <= 33; i++) {
2212 bmp.bmType = 0;
2213 bmp.bmWidth = 1;
2214 bmp.bmHeight = 1;
2215 bmp.bmWidthBytes = 28;
2216 bmp.bmPlanes = 1;
2217 bmp.bmBitsPixel = i;
2218 bmp.bmBits = NULL;
2219 SetLastError(0xdeadbeef);
2220 bm = CreateBitmapIndirect(&bmp);
2221 if(i > 32) {
2222 DWORD error = GetLastError();
2223 ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
2224 ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2225 DeleteObject(bm);
2226 continue;
2228 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2229 GetObject(bm, sizeof(bmp), &bmp);
2230 if(i == 1) {
2231 expect = 1;
2232 } else if(i <= 4) {
2233 expect = 4;
2234 } else if(i <= 8) {
2235 expect = 8;
2236 } else if(i <= 16) {
2237 expect = 16;
2238 } else if(i <= 24) {
2239 expect = 24;
2240 } else if(i <= 32) {
2241 expect = 32;
2243 ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2244 i, bmp.bmBitsPixel, expect);
2245 DeleteObject(bm);
2249 static void test_bitmapinfoheadersize(void)
2251 HBITMAP hdib;
2252 BITMAPINFO bmi;
2253 BITMAPCOREINFO bci;
2254 HDC hdc = GetDC(0);
2256 memset(&bmi, 0, sizeof(BITMAPINFO));
2257 bmi.bmiHeader.biHeight = 100;
2258 bmi.bmiHeader.biWidth = 512;
2259 bmi.bmiHeader.biBitCount = 24;
2260 bmi.bmiHeader.biPlanes = 1;
2262 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2264 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2265 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2267 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2269 SetLastError(0xdeadbeef);
2270 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2271 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2272 DeleteObject(hdib);
2274 bmi.bmiHeader.biSize++;
2276 SetLastError(0xdeadbeef);
2277 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2278 ok(hdib != NULL ||
2279 broken(!hdib), /* Win98, WinMe */
2280 "CreateDIBSection error %d\n", GetLastError());
2281 DeleteObject(hdib);
2283 bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2285 SetLastError(0xdeadbeef);
2286 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2287 ok(hdib != NULL ||
2288 broken(!hdib), /* Win98, WinMe */
2289 "CreateDIBSection error %d\n", GetLastError());
2290 DeleteObject(hdib);
2292 bmi.bmiHeader.biSize++;
2294 SetLastError(0xdeadbeef);
2295 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2296 ok(hdib != NULL ||
2297 broken(!hdib), /* Win98, WinMe */
2298 "CreateDIBSection error %d\n", GetLastError());
2299 DeleteObject(hdib);
2301 bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2303 SetLastError(0xdeadbeef);
2304 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2305 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2306 DeleteObject(hdib);
2308 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2310 SetLastError(0xdeadbeef);
2311 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2312 ok(hdib != NULL ||
2313 broken(!hdib), /* Win95 */
2314 "CreateDIBSection error %d\n", GetLastError());
2315 DeleteObject(hdib);
2317 memset(&bci, 0, sizeof(BITMAPCOREINFO));
2318 bci.bmciHeader.bcHeight = 100;
2319 bci.bmciHeader.bcWidth = 512;
2320 bci.bmciHeader.bcBitCount = 24;
2321 bci.bmciHeader.bcPlanes = 1;
2323 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2325 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2326 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2328 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2330 SetLastError(0xdeadbeef);
2331 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2332 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2333 DeleteObject(hdib);
2335 bci.bmciHeader.bcSize++;
2337 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2338 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2340 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2342 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2343 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2345 ReleaseDC(0, hdc);
2348 static void test_get16dibits(void)
2350 BYTE bits[4 * (16 / sizeof(BYTE))];
2351 HBITMAP hbmp;
2352 HDC screen_dc = GetDC(NULL);
2353 int ret;
2354 BITMAPINFO * info;
2355 int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2356 BYTE *p;
2357 int overwritten_bytes = 0;
2359 memset(bits, 0, sizeof(bits));
2360 hbmp = CreateBitmap(2, 2, 1, 16, bits);
2361 ok(hbmp != NULL, "CreateBitmap failed\n");
2363 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2364 assert(info);
2366 memset(info, '!', info_len);
2367 memset(info, 0, sizeof(info->bmiHeader));
2369 info->bmiHeader.biSize = sizeof(info->bmiHeader);
2370 info->bmiHeader.biWidth = 2;
2371 info->bmiHeader.biHeight = 2;
2372 info->bmiHeader.biPlanes = 1;
2373 info->bmiHeader.biCompression = BI_RGB;
2375 ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2376 ok(ret != 0, "GetDIBits failed got %d\n", ret);
2378 for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2379 if (*p != '!')
2380 overwritten_bytes++;
2381 ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2383 HeapFree(GetProcessHeap(), 0, info);
2384 DeleteObject(hbmp);
2385 ReleaseDC(NULL, screen_dc);
2388 static BOOL compare_buffers_no_alpha(UINT32 *a, UINT32 *b, int length)
2390 int i;
2391 for(i = 0; i < length; i++)
2392 if((a[i] & 0x00FFFFFF) != (b[i] & 0x00FFFFFF))
2393 return FALSE;
2394 return TRUE;
2397 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2398 DWORD dwRop, UINT32 expected, int line)
2400 *srcBuffer = 0xFEDCBA98;
2401 *dstBuffer = 0x89ABCDEF;
2402 Rectangle(hdcSrc, 0, 0, 1, 1); /* A null operation to ensure dibs are coerced to X11 */
2403 BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
2404 ok(expected == *dstBuffer,
2405 "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2406 dwRop, expected, *dstBuffer, line);
2409 static void test_BitBlt(void)
2411 HBITMAP bmpDst, bmpSrc;
2412 HBITMAP oldDst, oldSrc;
2413 HDC hdcScreen, hdcDst, hdcSrc;
2414 UINT32 *dstBuffer, *srcBuffer;
2415 HBRUSH hBrush, hOldBrush;
2416 BITMAPINFO bitmapInfo;
2418 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2419 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2420 bitmapInfo.bmiHeader.biWidth = 1;
2421 bitmapInfo.bmiHeader.biHeight = 1;
2422 bitmapInfo.bmiHeader.biPlanes = 1;
2423 bitmapInfo.bmiHeader.biBitCount = 32;
2424 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2425 bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2427 hdcScreen = CreateCompatibleDC(0);
2428 hdcDst = CreateCompatibleDC(hdcScreen);
2429 hdcSrc = CreateCompatibleDC(hdcDst);
2431 /* Setup the destination dib section */
2432 bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
2433 NULL, 0);
2434 oldDst = SelectObject(hdcDst, bmpDst);
2436 hBrush = CreateSolidBrush(0x012345678);
2437 hOldBrush = SelectObject(hdcDst, hBrush);
2439 /* Setup the source dib section */
2440 bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
2441 NULL, 0);
2442 oldSrc = SelectObject(hdcSrc, bmpSrc);
2444 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2445 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2446 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2447 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2448 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2449 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2450 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2451 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2452 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2453 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2454 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2455 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2456 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2457 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2458 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2460 /* Tidy up */
2461 SelectObject(hdcSrc, oldSrc);
2462 DeleteObject(bmpSrc);
2463 DeleteDC(hdcSrc);
2465 SelectObject(hdcDst, hOldBrush);
2466 DeleteObject(hBrush);
2467 SelectObject(hdcDst, oldDst);
2468 DeleteObject(bmpDst);
2469 DeleteDC(hdcDst);
2472 DeleteDC(hdcScreen);
2475 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2476 DWORD dwRop, UINT32 expected, int line)
2478 *srcBuffer = 0xFEDCBA98;
2479 *dstBuffer = 0x89ABCDEF;
2480 StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
2481 ok(expected == *dstBuffer,
2482 "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2483 dwRop, expected, *dstBuffer, line);
2486 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2487 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2488 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2489 UINT32 expected[4], UINT32 legacy_expected[4], int line)
2491 memset(dstBuffer, 0, 16);
2492 StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2493 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
2494 ok(memcmp(dstBuffer, expected, 16) == 0 ||
2495 broken(compare_buffers_no_alpha(dstBuffer, legacy_expected, 4)),
2496 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2497 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2498 expected[0], expected[1], expected[2], expected[3],
2499 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2500 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2501 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2504 static void test_StretchBlt(void)
2506 HBITMAP bmpDst, bmpSrc;
2507 HBITMAP oldDst, oldSrc;
2508 HDC hdcScreen, hdcDst, hdcSrc;
2509 UINT32 *dstBuffer, *srcBuffer;
2510 HBRUSH hBrush, hOldBrush;
2511 BITMAPINFO biDst, biSrc;
2512 UINT32 expected[4], legacy_expected[4];
2514 memset(&biDst, 0, sizeof(BITMAPINFO));
2515 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2516 biDst.bmiHeader.biWidth = 2;
2517 biDst.bmiHeader.biHeight = -2;
2518 biDst.bmiHeader.biPlanes = 1;
2519 biDst.bmiHeader.biBitCount = 32;
2520 biDst.bmiHeader.biCompression = BI_RGB;
2521 memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
2523 hdcScreen = CreateCompatibleDC(0);
2524 hdcDst = CreateCompatibleDC(hdcScreen);
2525 hdcSrc = CreateCompatibleDC(hdcDst);
2527 /* Pixel Tests */
2528 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2529 NULL, 0);
2530 oldDst = SelectObject(hdcDst, bmpDst);
2532 bmpSrc = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&srcBuffer,
2533 NULL, 0);
2534 oldSrc = SelectObject(hdcSrc, bmpSrc);
2536 hBrush = CreateSolidBrush(0x012345678);
2537 hOldBrush = SelectObject(hdcDst, hBrush);
2539 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2540 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2541 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2542 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2543 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2544 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2545 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2546 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2547 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2548 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2549 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2550 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2551 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2552 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2553 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2555 SelectObject(hdcDst, hOldBrush);
2556 DeleteObject(hBrush);
2558 /* Top-down to top-down tests */
2559 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2560 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
2562 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2563 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2564 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2565 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2567 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2568 expected[2] = 0x00000000, expected[3] = 0x00000000;
2569 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2570 0, 0, 1, 1, 0, 0, 1, 1, expected, expected, __LINE__);
2572 expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
2573 expected[2] = 0xCAFED00D, expected[3] = 0xCAFED00D;
2574 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2575 0, 0, 2, 2, 0, 0, 1, 1, expected, expected, __LINE__);
2577 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2578 expected[2] = 0x00000000, expected[3] = 0x00000000;
2579 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2580 0, 0, 1, 1, 0, 0, 2, 2, expected, expected, __LINE__);
2582 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2583 expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2584 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2585 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2587 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2588 expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2589 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2590 1, 1, -2, -2, 0, 0, 2, 2, expected, expected, __LINE__);
2592 /* This result seems broken. One might expect the following result:
2593 * 0xCAFED00D 0xFEEDFACE
2594 * 0xFEDCBA98 0x76543210
2596 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2597 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2598 legacy_expected[0] = 0xCAFED00D, legacy_expected[1] = 0x00000000;
2599 legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
2600 todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2601 1, 1, -2, -2, 1, 1, -2, -2, expected,
2602 legacy_expected, __LINE__);
2604 expected[0] = 0x00000000, expected[1] = 0x00000000;
2605 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
2606 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2607 1, 1, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2609 SelectObject(hdcDst, oldDst);
2610 DeleteObject(bmpDst);
2612 /* Top-down to bottom-up tests */
2613 biDst.bmiHeader.biHeight = 2;
2614 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2615 NULL, 0);
2616 oldDst = SelectObject(hdcDst, bmpDst);
2618 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2619 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
2620 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2621 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2623 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2624 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2625 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2626 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2628 SelectObject(hdcSrc, oldSrc);
2629 DeleteObject(bmpSrc);
2631 /* Bottom-up to bottom-up tests */
2632 biSrc.bmiHeader.biHeight = 2;
2633 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2634 NULL, 0);
2635 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2636 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
2637 oldSrc = SelectObject(hdcSrc, bmpSrc);
2639 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2640 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2641 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2642 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2644 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2645 expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2646 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2647 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2649 SelectObject(hdcDst, oldDst);
2650 DeleteObject(bmpDst);
2652 /* Bottom-up to top-down tests */
2653 biDst.bmiHeader.biHeight = -2;
2654 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2655 NULL, 0);
2656 oldDst = SelectObject(hdcDst, bmpDst);
2658 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2659 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
2660 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2661 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2663 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2664 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2665 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2666 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2668 /* Tidy up */
2669 SelectObject(hdcSrc, oldSrc);
2670 DeleteObject(bmpSrc);
2671 DeleteDC(hdcSrc);
2673 SelectObject(hdcDst, oldDst);
2674 DeleteObject(bmpDst);
2675 DeleteDC(hdcDst);
2677 DeleteDC(hdcScreen);
2680 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
2681 DWORD dwRop, UINT32 expected, int line)
2683 const UINT32 buffer[2] = { 0xFEDCBA98, 0 };
2684 BITMAPINFO bitmapInfo;
2686 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2687 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2688 bitmapInfo.bmiHeader.biWidth = 2;
2689 bitmapInfo.bmiHeader.biHeight = 1;
2690 bitmapInfo.bmiHeader.biPlanes = 1;
2691 bitmapInfo.bmiHeader.biBitCount = 32;
2692 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2693 bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer);
2695 *dstBuffer = 0x89ABCDEF;
2697 StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop);
2698 ok(expected == *dstBuffer,
2699 "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2700 dwRop, expected, *dstBuffer, line);
2703 static void check_StretchDIBits_stretch(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
2704 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2705 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2706 UINT32 expected[4], UINT32 legacy_expected[4], int line)
2708 BITMAPINFO bitmapInfo;
2710 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2711 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2712 bitmapInfo.bmiHeader.biWidth = 2;
2713 bitmapInfo.bmiHeader.biHeight = -2;
2714 bitmapInfo.bmiHeader.biPlanes = 1;
2715 bitmapInfo.bmiHeader.biBitCount = 32;
2716 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2718 memset(dstBuffer, 0, 16);
2719 StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2720 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2721 srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
2722 ok(memcmp(dstBuffer, expected, 16) == 0,
2723 "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2724 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2725 expected[0], expected[1], expected[2], expected[3],
2726 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2727 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2728 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2731 static void test_StretchDIBits(void)
2733 HBITMAP bmpDst;
2734 HBITMAP oldDst;
2735 HDC hdcScreen, hdcDst;
2736 UINT32 *dstBuffer, srcBuffer[4];
2737 HBRUSH hBrush, hOldBrush;
2738 BITMAPINFO biDst;
2739 UINT32 expected[4], legacy_expected[4];
2741 memset(&biDst, 0, sizeof(BITMAPINFO));
2742 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2743 biDst.bmiHeader.biWidth = 2;
2744 biDst.bmiHeader.biHeight = -2;
2745 biDst.bmiHeader.biPlanes = 1;
2746 biDst.bmiHeader.biBitCount = 32;
2747 biDst.bmiHeader.biCompression = BI_RGB;
2749 hdcScreen = CreateCompatibleDC(0);
2750 hdcDst = CreateCompatibleDC(hdcScreen);
2752 /* Pixel Tests */
2753 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2754 NULL, 0);
2755 oldDst = SelectObject(hdcDst, bmpDst);
2757 hBrush = CreateSolidBrush(0x012345678);
2758 hOldBrush = SelectObject(hdcDst, hBrush);
2760 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2761 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2762 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2763 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2764 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2765 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2766 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2767 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2768 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2769 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2770 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2771 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2772 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2773 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2774 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2776 SelectObject(hdcDst, hOldBrush);
2777 DeleteObject(hBrush);
2779 /* Top-down destination tests */
2780 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2781 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
2783 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2784 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2785 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2786 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2788 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2789 expected[2] = 0x00000000, expected[3] = 0x00000000;
2790 legacy_expected[0] = 0xFEDCBA98, legacy_expected[1] = 0x00000000;
2791 legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
2792 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2793 0, 0, 1, 1, 0, 0, 1, 1, expected, legacy_expected, __LINE__);
2795 expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
2796 expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
2797 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2798 0, 0, 2, 2, 0, 0, 1, 1, expected, expected, __LINE__);
2800 expected[0] = 0x42441000, expected[1] = 0x00000000;
2801 expected[2] = 0x00000000, expected[3] = 0x00000000;
2802 legacy_expected[0] = 0x00543210, legacy_expected[1] = 0x00000000;
2803 legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
2804 todo_wine check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2805 0, 0, 1, 1, 0, 0, 2, 2, expected, legacy_expected, __LINE__);
2807 expected[0] = 0x00000000, expected[1] = 0x00000000;
2808 expected[2] = 0x00000000, expected[3] = 0x00000000;
2809 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2810 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2812 expected[0] = 0x00000000, expected[1] = 0x00000000;
2813 expected[2] = 0x00000000, expected[3] = 0x00000000;
2814 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2815 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2817 expected[0] = 0x00000000, expected[1] = 0x00000000;
2818 expected[2] = 0x00000000, expected[3] = 0x00000000;
2819 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2820 1, 1, -2, -2, 1, 1, -2, -2, expected, expected, __LINE__);
2822 expected[0] = 0x00000000, expected[1] = 0x00000000;
2823 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
2824 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2825 1, 1, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2827 SelectObject(hdcDst, oldDst);
2828 DeleteObject(bmpDst);
2830 /* Bottom up destination tests */
2831 biDst.bmiHeader.biHeight = 2;
2832 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2833 NULL, 0);
2834 oldDst = SelectObject(hdcDst, bmpDst);
2836 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2837 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
2838 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2839 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2841 /* Tidy up */
2842 SelectObject(hdcDst, oldDst);
2843 DeleteObject(bmpDst);
2844 DeleteDC(hdcDst);
2846 DeleteDC(hdcScreen);
2849 static void test_GdiAlphaBlend(void)
2851 /* test out-of-bound parameters for GdiAlphaBlend */
2852 HDC hdcNull;
2854 HDC hdcDst;
2855 HBITMAP bmpDst;
2856 HBITMAP oldDst;
2858 BITMAPINFO bmi;
2859 HDC hdcSrc;
2860 HBITMAP bmpSrc;
2861 HBITMAP oldSrc;
2862 LPVOID bits;
2864 BLENDFUNCTION blend;
2866 if (!pGdiAlphaBlend)
2868 win_skip("GdiAlphaBlend() is not implemented\n");
2869 return;
2872 hdcNull = GetDC(NULL);
2873 hdcDst = CreateCompatibleDC(hdcNull);
2874 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
2875 hdcSrc = CreateCompatibleDC(hdcNull);
2877 memset(&bmi, 0, sizeof(bmi)); /* as of Wine 0.9.44 we require the src to be a DIB section */
2878 bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
2879 bmi.bmiHeader.biHeight = 20;
2880 bmi.bmiHeader.biWidth = 20;
2881 bmi.bmiHeader.biBitCount = 32;
2882 bmi.bmiHeader.biPlanes = 1;
2883 bmi.bmiHeader.biCompression = BI_RGB;
2884 bmpSrc = CreateDIBSection(hdcDst, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
2885 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
2887 oldDst = SelectObject(hdcDst, bmpDst);
2888 oldSrc = SelectObject(hdcSrc, bmpSrc);
2890 blend.BlendOp = AC_SRC_OVER;
2891 blend.BlendFlags = 0;
2892 blend.SourceConstantAlpha = 128;
2893 blend.AlphaFormat = 0;
2895 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend), TRUE, BOOL, "%d");
2896 SetLastError(0xdeadbeef);
2897 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), FALSE, BOOL, "%d");
2898 expect_eq(GetLastError(), ERROR_INVALID_PARAMETER, int, "%d");
2899 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), FALSE, BOOL, "%d");
2900 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend), FALSE, BOOL, "%d");
2901 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
2902 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
2904 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
2905 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), TRUE, BOOL, "%d");
2906 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), TRUE, BOOL, "%d");
2907 SetMapMode(hdcSrc, MM_ANISOTROPIC);
2908 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
2909 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend), TRUE, BOOL, "%d");
2910 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend), TRUE, BOOL, "%d");
2912 SetLastError(0xdeadbeef);
2913 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend), FALSE, BOOL, "%d");
2914 expect_eq(GetLastError(), 0xdeadbeef, int, "%d");
2916 SelectObject(hdcDst, oldDst);
2917 SelectObject(hdcSrc, oldSrc);
2918 DeleteObject(bmpSrc);
2919 DeleteObject(bmpDst);
2920 DeleteDC(hdcDst);
2921 DeleteDC(hdcSrc);
2923 ReleaseDC(NULL, hdcNull);
2927 static void test_clipping(void)
2929 HBITMAP bmpDst;
2930 HBITMAP bmpSrc;
2931 HRGN hRgn;
2932 LPVOID bits;
2933 BOOL result;
2935 HDC hdcDst = CreateCompatibleDC( NULL );
2936 HDC hdcSrc = CreateCompatibleDC( NULL );
2938 BITMAPINFO bmpinfo={{0}};
2939 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2940 bmpinfo.bmiHeader.biWidth = 100;
2941 bmpinfo.bmiHeader.biHeight = 100;
2942 bmpinfo.bmiHeader.biPlanes = 1;
2943 bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
2944 bmpinfo.bmiHeader.biCompression = BI_RGB;
2946 bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
2947 ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
2948 SelectObject( hdcDst, bmpDst );
2950 bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
2951 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
2952 SelectObject( hdcSrc, bmpSrc );
2954 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
2955 ok(result, "BitBlt failed\n");
2957 hRgn = CreateRectRgn( 0,0,0,0 );
2958 SelectClipRgn( hdcDst, hRgn );
2960 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
2961 ok(result, "BitBlt failed\n");
2963 DeleteObject( bmpDst );
2964 DeleteObject( bmpSrc );
2965 DeleteObject( hRgn );
2966 DeleteDC( hdcDst );
2967 DeleteDC( hdcSrc );
2970 static void test_32bit_bitmap_blt(void)
2972 BITMAPINFO biDst;
2973 HBITMAP bmpSrc, bmpDst;
2974 HBITMAP oldSrc, oldDst;
2975 HDC hdcSrc, hdcDst, hdcScreen;
2976 UINT32 *dstBuffer;
2977 DWORD colorSrc = 0x11223344;
2979 memset(&biDst, 0, sizeof(BITMAPINFO));
2980 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2981 biDst.bmiHeader.biWidth = 2;
2982 biDst.bmiHeader.biHeight = -2;
2983 biDst.bmiHeader.biPlanes = 1;
2984 biDst.bmiHeader.biBitCount = 32;
2985 biDst.bmiHeader.biCompression = BI_RGB;
2987 hdcScreen = CreateCompatibleDC(0);
2988 if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
2990 DeleteDC(hdcScreen);
2991 trace("Skipping 32-bit DDB test\n");
2992 return;
2995 hdcSrc = CreateCompatibleDC(hdcScreen);
2996 bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
2997 oldSrc = SelectObject(hdcSrc, bmpSrc);
2999 hdcDst = CreateCompatibleDC(hdcScreen);
3000 bmpDst = CreateDIBSection(hdcDst, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3001 oldDst = SelectObject(hdcDst, bmpDst);
3003 StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3004 ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3006 /* Tidy up */
3007 SelectObject(hdcDst, oldDst);
3008 DeleteObject(bmpDst);
3009 DeleteDC(hdcDst);
3011 SelectObject(hdcSrc, oldSrc);
3012 DeleteObject(bmpSrc);
3013 DeleteDC(hdcSrc);
3015 DeleteDC(hdcScreen);
3019 * Used by test_GetDIBits_top_down to create the bitmap to test against.
3021 static void setup_picture(char *picture, int bpp)
3023 int i;
3025 switch(bpp)
3027 case 16:
3028 case 32:
3029 /*Set the first byte in each pixel to the index of that pixel.*/
3030 for (i = 0; i < 4; i++)
3031 picture[i * (bpp / 8)] = i;
3032 break;
3033 case 24:
3034 picture[0] = 0;
3035 picture[3] = 1;
3036 /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
3037 picture[8] = 2;
3038 picture[11] = 3;
3039 break;
3043 static void test_GetDIBits_top_down(int bpp)
3045 BITMAPINFO bi;
3046 HBITMAP bmptb, bmpbt;
3047 HDC hdc;
3048 int pictureOut[4];
3049 int *picture;
3050 int statusCode;
3052 bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
3053 bi.bmiHeader.biWidth=2;
3054 bi.bmiHeader.biHeight=2;
3055 bi.bmiHeader.biPlanes=1;
3056 bi.bmiHeader.biBitCount=bpp;
3057 bi.bmiHeader.biCompression=BI_RGB;
3059 /*Get the device context for the screen.*/
3060 hdc = GetDC(NULL);
3061 ok(hdc != NULL, "Could not get a handle to a device context.\n");
3063 /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
3064 bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3065 ok(bmpbt != NULL, "Could not create a DIB section.\n");
3066 /*Now that we have a pointer to the pixels, we write to them.*/
3067 setup_picture((char*)picture, bpp);
3068 /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
3069 bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
3070 bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3071 ok(bmptb != NULL, "Could not create a DIB section.\n");
3072 /*Write to this top to bottom bitmap.*/
3073 setup_picture((char*)picture, bpp);
3075 bi.bmiHeader.biWidth = 1;
3077 bi.bmiHeader.biHeight = 2;
3078 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3079 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3080 /*Check the first byte of the pixel.*/
3081 ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3082 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3083 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3084 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3085 /*Check second scanline.*/
3086 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3087 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3088 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3089 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3090 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3091 ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3092 /*Check both scanlines.*/
3093 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3094 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3095 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3096 ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3097 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3098 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3099 ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3100 ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3102 /*Make destination bitmap top-down.*/
3103 bi.bmiHeader.biHeight = -2;
3104 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3105 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3106 ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3107 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3108 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3109 ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3110 /*Check second scanline.*/
3111 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3112 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3113 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3114 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3115 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3116 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3117 /*Check both scanlines.*/
3118 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3119 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3120 ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3121 ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3122 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3123 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3124 ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3125 ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3127 DeleteObject(bmpbt);
3128 DeleteObject(bmptb);
3131 static void test_GetSetDIBits_rtl(void)
3133 HDC hdc, hdc_mem;
3134 HBITMAP bitmap, orig_bitmap;
3135 BITMAPINFO info;
3136 int ret;
3137 DWORD bits_1[8 * 8], bits_2[8 * 8];
3139 if(!pSetLayout)
3141 win_skip("Don't have SetLayout\n");
3142 return;
3145 hdc = GetDC( NULL );
3146 hdc_mem = CreateCompatibleDC( hdc );
3147 pSetLayout( hdc_mem, LAYOUT_LTR );
3149 bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
3150 orig_bitmap = SelectObject( hdc_mem, bitmap );
3151 SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
3152 SelectObject( hdc_mem, orig_bitmap );
3154 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3155 info.bmiHeader.biWidth = 8;
3156 info.bmiHeader.biHeight = 8;
3157 info.bmiHeader.biPlanes = 1;
3158 info.bmiHeader.biBitCount = 32;
3159 info.bmiHeader.biCompression = BI_RGB;
3161 /* First show that GetDIBits ignores the layout mode. */
3163 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3164 ok(ret == 8, "got %d\n", ret);
3165 ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
3167 pSetLayout( hdc_mem, LAYOUT_RTL );
3169 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3170 ok(ret == 8, "got %d\n", ret);
3172 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3174 /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
3175 followed by a GetDIBits and show that the bits remain unchanged. */
3177 pSetLayout( hdc_mem, LAYOUT_LTR );
3179 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3180 ok(ret == 8, "got %d\n", ret);
3181 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3182 ok(ret == 8, "got %d\n", ret);
3183 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3185 pSetLayout( hdc_mem, LAYOUT_RTL );
3187 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3188 ok(ret == 8, "got %d\n", ret);
3189 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3190 ok(ret == 8, "got %d\n", ret);
3191 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3193 DeleteObject( bitmap );
3194 DeleteDC( hdc_mem );
3195 ReleaseDC( NULL, hdc );
3198 static void test_GetDIBits_scanlines(void)
3200 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3201 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3202 DWORD *dib_bits;
3203 HDC hdc = GetDC( NULL );
3204 HBITMAP dib;
3205 DWORD data[128], inverted_bits[64];
3206 int i, ret;
3208 memset( info, 0, sizeof(bmi_buf) );
3210 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3211 info->bmiHeader.biWidth = 8;
3212 info->bmiHeader.biHeight = 8;
3213 info->bmiHeader.biPlanes = 1;
3214 info->bmiHeader.biBitCount = 32;
3215 info->bmiHeader.biCompression = BI_RGB;
3217 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3219 for (i = 0; i < 64; i++)
3221 dib_bits[i] = i;
3222 inverted_bits[56 - (i & ~7) + (i & 7)] = i;
3225 /* b-u -> b-u */
3227 memset( data, 0xaa, sizeof(data) );
3229 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3230 ok( ret == 8, "got %d\n", ret );
3231 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3232 memset( data, 0xaa, sizeof(data) );
3234 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3235 ok( ret == 5, "got %d\n", ret );
3236 ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
3237 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3238 memset( data, 0xaa, sizeof(data) );
3240 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3241 ok( ret == 7, "got %d\n", ret );
3242 ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
3243 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3244 memset( data, 0xaa, sizeof(data) );
3246 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3247 ok( ret == 1, "got %d\n", ret );
3248 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3249 memset( data, 0xaa, sizeof(data) );
3251 info->bmiHeader.biHeight = 16;
3252 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3253 ok( ret == 5, "got %d\n", ret );
3254 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3255 ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
3256 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3257 memset( data, 0xaa, sizeof(data) );
3259 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3260 ok( ret == 6, "got %d\n", ret );
3261 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3262 ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
3263 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3264 memset( data, 0xaa, sizeof(data) );
3266 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3267 ok( ret == 0, "got %d\n", ret );
3268 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3269 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3270 memset( data, 0xaa, sizeof(data) );
3272 info->bmiHeader.biHeight = 5;
3273 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3274 ok( ret == 2, "got %d\n", ret );
3275 ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
3276 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3277 memset( data, 0xaa, sizeof(data) );
3279 /* b-u -> t-d */
3281 info->bmiHeader.biHeight = -8;
3282 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3283 ok( ret == 8, "got %d\n", ret );
3284 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3285 memset( data, 0xaa, sizeof(data) );
3287 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3288 ok( ret == 5, "got %d\n", ret );
3289 ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
3290 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3291 memset( data, 0xaa, sizeof(data) );
3293 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3294 ok( ret == 7, "got %d\n", ret );
3295 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3296 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3297 memset( data, 0xaa, sizeof(data) );
3299 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3300 ok( ret == 4, "got %d\n", ret );
3301 ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
3302 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3303 memset( data, 0xaa, sizeof(data) );
3305 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3306 ok( ret == 5, "got %d\n", ret );
3307 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3308 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3309 memset( data, 0xaa, sizeof(data) );
3311 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3312 ok( ret == 5, "got %d\n", ret );
3313 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3314 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3315 memset( data, 0xaa, sizeof(data) );
3317 info->bmiHeader.biHeight = -16;
3318 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3319 ok( ret == 8, "got %d\n", ret );
3320 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3321 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3322 memset( data, 0xaa, sizeof(data) );
3324 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3325 ok( ret == 5, "got %d\n", ret );
3326 ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
3327 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3328 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3329 memset( data, 0xaa, sizeof(data) );
3331 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3332 ok( ret == 8, "got %d\n", ret );
3333 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3334 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3335 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3336 memset( data, 0xaa, sizeof(data) );
3338 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3339 ok( ret == 8, "got %d\n", ret );
3340 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3341 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3342 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3343 memset( data, 0xaa, sizeof(data) );
3345 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3346 ok( ret == 7, "got %d\n", ret );
3347 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3348 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3349 memset( data, 0xaa, sizeof(data) );
3351 ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
3352 ok( ret == 1, "got %d\n", ret );
3353 for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3354 memset( data, 0xaa, sizeof(data) );
3356 info->bmiHeader.biHeight = -5;
3357 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3358 ok( ret == 2, "got %d\n", ret );
3359 ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
3360 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3361 memset( data, 0xaa, sizeof(data) );
3363 DeleteObject( dib );
3365 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3366 info->bmiHeader.biWidth = 8;
3367 info->bmiHeader.biHeight = -8;
3368 info->bmiHeader.biPlanes = 1;
3369 info->bmiHeader.biBitCount = 32;
3370 info->bmiHeader.biCompression = BI_RGB;
3372 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3374 for (i = 0; i < 64; i++) dib_bits[i] = i;
3376 /* t-d -> t-d */
3378 info->bmiHeader.biHeight = -8;
3379 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3380 ok( ret == 8, "got %d\n", ret );
3381 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3382 memset( data, 0xaa, sizeof(data) );
3384 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3385 ok( ret == 5, "got %d\n", ret );
3386 ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
3387 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3388 memset( data, 0xaa, sizeof(data) );
3390 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3391 ok( ret == 7, "got %d\n", ret );
3392 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3393 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3394 memset( data, 0xaa, sizeof(data) );
3396 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3397 ok( ret == 4, "got %d\n", ret );
3398 ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
3399 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3400 memset( data, 0xaa, sizeof(data) );
3402 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3403 ok( ret == 5, "got %d\n", ret );
3404 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3405 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3406 memset( data, 0xaa, sizeof(data) );
3408 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3409 ok( ret == 5, "got %d\n", ret );
3410 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3411 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3412 memset( data, 0xaa, sizeof(data) );
3414 info->bmiHeader.biHeight = -16;
3415 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3416 ok( ret == 8, "got %d\n", ret );
3417 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3418 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3419 memset( data, 0xaa, sizeof(data) );
3421 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3422 ok( ret == 5, "got %d\n", ret );
3423 ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
3424 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3425 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3426 memset( data, 0xaa, sizeof(data) );
3428 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3429 ok( ret == 8, "got %d\n", ret );
3430 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3431 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3432 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3433 memset( data, 0xaa, sizeof(data) );
3435 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3436 ok( ret == 8, "got %d\n", ret );
3437 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3438 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3439 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3440 memset( data, 0xaa, sizeof(data) );
3442 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3443 ok( ret == 7, "got %d\n", ret );
3444 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3445 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3446 memset( data, 0xaa, sizeof(data) );
3448 info->bmiHeader.biHeight = -5;
3449 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3450 ok( ret == 2, "got %d\n", ret );
3451 ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
3452 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3453 memset( data, 0xaa, sizeof(data) );
3456 /* t-d -> b-u */
3458 info->bmiHeader.biHeight = 8;
3460 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3461 ok( ret == 8, "got %d\n", ret );
3462 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3463 memset( data, 0xaa, sizeof(data) );
3465 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3466 ok( ret == 5, "got %d\n", ret );
3467 ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
3468 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3469 memset( data, 0xaa, sizeof(data) );
3471 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3472 ok( ret == 7, "got %d\n", ret );
3473 ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
3474 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3475 memset( data, 0xaa, sizeof(data) );
3477 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3478 ok( ret == 1, "got %d\n", ret );
3479 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3480 memset( data, 0xaa, sizeof(data) );
3482 info->bmiHeader.biHeight = 16;
3483 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3484 ok( ret == 5, "got %d\n", ret );
3485 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3486 ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
3487 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3488 memset( data, 0xaa, sizeof(data) );
3490 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3491 ok( ret == 6, "got %d\n", ret );
3492 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3493 ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
3494 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3495 memset( data, 0xaa, sizeof(data) );
3497 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3498 ok( ret == 0, "got %d\n", ret );
3499 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3500 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3501 memset( data, 0xaa, sizeof(data) );
3503 info->bmiHeader.biHeight = 5;
3504 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3505 ok( ret == 2, "got %d\n", ret );
3506 ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
3507 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3508 memset( data, 0xaa, sizeof(data) );
3510 DeleteObject( dib );
3512 ReleaseDC( NULL, hdc );
3516 static void test_SetDIBits(void)
3518 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3519 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3520 DWORD *dib_bits;
3521 HDC hdc = GetDC( NULL );
3522 DWORD data[128], inverted_data[128];
3523 HBITMAP dib;
3524 int i, ret;
3526 memset( info, 0, sizeof(bmi_buf) );
3528 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3529 info->bmiHeader.biWidth = 8;
3530 info->bmiHeader.biHeight = 8;
3531 info->bmiHeader.biPlanes = 1;
3532 info->bmiHeader.biBitCount = 32;
3533 info->bmiHeader.biCompression = BI_RGB;
3535 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3536 memset( dib_bits, 0xaa, 64 * 4 );
3538 for (i = 0; i < 128; i++)
3540 data[i] = i;
3541 inverted_data[120 - (i & ~7) + (i & 7)] = i;
3544 /* b-u -> b-u */
3546 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3547 ok( ret == 8, "got %d\n", ret );
3548 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
3549 memset( dib_bits, 0xaa, 64 * 4 );
3551 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3552 ok( ret == 5, "got %d\n", ret );
3553 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3554 ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
3555 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3556 memset( dib_bits, 0xaa, 64 * 4 );
3558 /* top of dst is aligned with startscans down for the top of the src.
3559 Then starting from the bottom of src, lines rows are copied across. */
3561 info->bmiHeader.biHeight = 16;
3562 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3563 ok( ret == 12, "got %d\n", ret );
3564 ok( !memcmp( dib_bits, data + 56, 40 * 4 ), "bits differ\n");
3565 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3566 memset( dib_bits, 0xaa, 64 * 4 );
3568 info->bmiHeader.biHeight = 5;
3569 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3570 ok( ret == 2, "got %d\n", ret );
3571 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3572 ok( !memcmp( dib_bits + 32, data, 16 * 4 ), "bits differ\n");
3573 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3574 memset( dib_bits, 0xaa, 64 * 4 );
3576 /* t-d -> b-u */
3577 info->bmiHeader.biHeight = -8;
3578 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3579 ok( ret == 8, "got %d\n", ret );
3580 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3581 memset( dib_bits, 0xaa, 64 * 4 );
3583 /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
3584 we copy lines rows from the top of the src */
3586 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3587 ok( ret == 5, "got %d\n", ret );
3588 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3589 ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
3590 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3591 memset( dib_bits, 0xaa, 64 * 4 );
3593 info->bmiHeader.biHeight = -16;
3594 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3595 ok( ret == 12, "got %d\n", ret );
3596 ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
3597 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3598 memset( dib_bits, 0xaa, 64 * 4 );
3600 ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3601 ok( ret == 12, "got %d\n", ret );
3602 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3603 memset( dib_bits, 0xaa, 64 * 4 );
3605 ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3606 ok( ret == 12, "got %d\n", ret );
3607 ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
3608 memset( dib_bits, 0xaa, 64 * 4 );
3610 info->bmiHeader.biHeight = -5;
3611 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3612 ok( ret == 2, "got %d\n", ret );
3613 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3614 ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
3615 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3616 memset( dib_bits, 0xaa, 64 * 4 );
3618 DeleteObject( dib );
3620 info->bmiHeader.biHeight = -8;
3622 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3623 memset( dib_bits, 0xaa, 16 * 16 * 4 );
3625 /* t-d -> t-d */
3627 /* like the t-d -> b-u case. */
3629 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3630 ok( ret == 8, "got %d\n", ret );
3631 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
3632 memset( dib_bits, 0xaa, 64 * 4 );
3634 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3635 ok( ret == 5, "got %d\n", ret );
3636 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3637 ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
3638 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3639 memset( dib_bits, 0xaa, 64 * 4 );
3641 info->bmiHeader.biHeight = -16;
3642 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3643 ok( ret == 12, "got %d\n", ret );
3644 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3645 ok( !memcmp( dib_bits + 24, data, 40 * 4 ), "bits differ\n");
3646 memset( dib_bits, 0xaa, 64 * 4 );
3648 info->bmiHeader.biHeight = -5;
3649 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3650 ok( ret == 2, "got %d\n", ret );
3651 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3652 ok( !memcmp( dib_bits + 16, data, 16 * 4 ), "bits differ\n");
3653 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3654 memset( dib_bits, 0xaa, 64 * 4 );
3656 /* b-u -> t-d */
3657 /* like the b-u -> b-u case */
3659 info->bmiHeader.biHeight = 8;
3660 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3661 ok( ret == 8, "got %d\n", ret );
3662 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3663 memset( dib_bits, 0xaa, 64 * 4 );
3665 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3666 ok( ret == 5, "got %d\n", ret );
3667 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3668 ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
3669 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3670 memset( dib_bits, 0xaa, 64 * 4 );
3672 info->bmiHeader.biHeight = 16;
3673 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3674 ok( ret == 12, "got %d\n", ret );
3675 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3676 ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
3677 memset( dib_bits, 0xaa, 64 * 4 );
3679 info->bmiHeader.biHeight = 5;
3680 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3681 ok( ret == 2, "got %d\n", ret );
3682 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3683 ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
3684 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3685 memset( dib_bits, 0xaa, 64 * 4 );
3687 DeleteObject( dib );
3688 ReleaseDC( NULL, hdc );
3691 static void test_SetDIBits_RLE4(void)
3693 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3694 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3695 DWORD *dib_bits;
3696 HDC hdc = GetDC( NULL );
3697 BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00, /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
3698 0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
3699 0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00, /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
3700 0x00, 0x02, 0x01, 0x02, 0x05, 0x87, /* dx=1, dy=2, 8, 7, 8, 7, 8 */
3701 0x00, 0x01 }; /* <eod> */
3702 HBITMAP dib;
3703 int i, ret;
3704 DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
3705 0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
3706 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3707 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3708 0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
3709 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3710 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3711 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
3713 memset( info, 0, sizeof(bmi_buf) );
3715 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3716 info->bmiHeader.biWidth = 8;
3717 info->bmiHeader.biHeight = 8;
3718 info->bmiHeader.biPlanes = 1;
3719 info->bmiHeader.biBitCount = 32;
3720 info->bmiHeader.biCompression = BI_RGB;
3722 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3723 memset( dib_bits, 0xaa, 64 * 4 );
3725 info->bmiHeader.biBitCount = 4;
3726 info->bmiHeader.biCompression = BI_RLE4;
3727 info->bmiHeader.biSizeImage = sizeof(rle4_data);
3729 for (i = 0; i < 16; i++)
3731 info->bmiColors[i].rgbRed = i;
3732 info->bmiColors[i].rgbGreen = i;
3733 info->bmiColors[i].rgbBlue = i;
3734 info->bmiColors[i].rgbReserved = 0;
3737 ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
3738 ok( ret == 8, "got %d\n", ret );
3739 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
3740 memset( dib_bits, 0xaa, 64 * 4 );
3742 DeleteObject( dib );
3743 ReleaseDC( NULL, hdc );
3746 static void test_SetDIBits_RLE8(void)
3748 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3749 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3750 DWORD *dib_bits;
3751 HDC hdc = GetDC( NULL );
3752 BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00, /* 2, 2, 2, f0, f0, f0, f0, <eol> */
3753 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
3754 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
3755 0x00, 0x01 }; /* <eod> */
3756 HBITMAP dib;
3757 int i, ret;
3758 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
3759 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3760 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3761 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
3762 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3763 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3764 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3765 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
3766 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3767 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3768 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3769 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3770 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
3771 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3772 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3773 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
3775 memset( info, 0, sizeof(bmi_buf) );
3777 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3778 info->bmiHeader.biWidth = 8;
3779 info->bmiHeader.biHeight = 8;
3780 info->bmiHeader.biPlanes = 1;
3781 info->bmiHeader.biBitCount = 32;
3782 info->bmiHeader.biCompression = BI_RGB;
3784 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3785 memset( dib_bits, 0xaa, 64 * 4 );
3787 info->bmiHeader.biBitCount = 8;
3788 info->bmiHeader.biCompression = BI_RLE8;
3789 info->bmiHeader.biSizeImage = sizeof(rle8_data);
3791 for (i = 0; i < 256; i++)
3793 info->bmiColors[i].rgbRed = i;
3794 info->bmiColors[i].rgbGreen = i;
3795 info->bmiColors[i].rgbBlue = i;
3796 info->bmiColors[i].rgbReserved = 0;
3799 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
3800 ok( ret == 8, "got %d\n", ret );
3801 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
3802 memset( dib_bits, 0xaa, 64 * 4 );
3804 /* startscan and lines are ignored, unless lines == 0 */
3805 ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
3806 ok( ret == 8, "got %d\n", ret );
3807 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
3808 memset( dib_bits, 0xaa, 64 * 4 );
3810 ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
3811 ok( ret == 8, "got %d\n", ret );
3812 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
3813 memset( dib_bits, 0xaa, 64 * 4 );
3815 ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
3816 ok( ret == 0, "got %d\n", ret );
3817 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3818 memset( dib_bits, 0xaa, 64 * 4 );
3820 /* reduce width to 4, left-hand side of dst is touched. */
3821 info->bmiHeader.biWidth = 4;
3822 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
3823 ok( ret == 8, "got %d\n", ret );
3824 for (i = 0; i < 64; i++)
3826 DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
3827 ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
3829 memset( dib_bits, 0xaa, 64 * 4 );
3831 /* Show that the top lines are aligned by adjusting the height of the src */
3833 /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
3834 info->bmiHeader.biWidth = 8;
3835 info->bmiHeader.biHeight = 4;
3836 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
3837 ok( ret == 4, "got %d\n", ret );
3838 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3839 ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
3840 memset( dib_bits, 0xaa, 64 * 4 );
3842 /* increase the height to 9 -> everything moves down one row. */
3843 info->bmiHeader.biHeight = 9;
3844 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
3845 ok( ret == 9, "got %d\n", ret );
3846 ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
3847 for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
3848 memset( dib_bits, 0xaa, 64 * 4 );
3850 /* top-down compressed dibs are invalid */
3851 info->bmiHeader.biHeight = -8;
3852 SetLastError( 0xdeadbeef );
3853 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
3854 ok( ret == 0, "got %d\n", ret );
3855 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
3856 DeleteObject( dib );
3858 /* top-down dst */
3860 info->bmiHeader.biHeight = -8;
3861 info->bmiHeader.biBitCount = 32;
3862 info->bmiHeader.biCompression = BI_RGB;
3863 info->bmiHeader.biSizeImage = 0;
3865 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3866 memset( dib_bits, 0xaa, 16 * 16 * 4 );
3868 info->bmiHeader.biHeight = 8;
3869 info->bmiHeader.biBitCount = 8;
3870 info->bmiHeader.biCompression = BI_RLE8;
3871 info->bmiHeader.biSizeImage = sizeof(rle8_data);
3873 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
3874 ok( ret == 8, "got %d\n", ret );
3875 ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
3876 memset( dib_bits, 0xaa, 64 * 4 );
3878 info->bmiHeader.biHeight = 4;
3879 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
3880 ok( ret == 4, "got %d\n", ret );
3881 ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
3882 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3883 memset( dib_bits, 0xaa, 64 * 4 );
3885 info->bmiHeader.biHeight = 9;
3886 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
3887 ok( ret == 9, "got %d\n", ret );
3888 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3889 ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
3890 memset( dib_bits, 0xaa, 64 * 4 );
3892 DeleteObject( dib );
3894 ReleaseDC( NULL, hdc );
3897 START_TEST(bitmap)
3899 HMODULE hdll;
3901 hdll = GetModuleHandle("gdi32.dll");
3902 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
3903 pSetLayout = (void*)GetProcAddress(hdll, "SetLayout");
3905 test_createdibitmap();
3906 test_dibsections();
3907 test_mono_dibsection();
3908 test_bitmap();
3909 test_bmBits();
3910 test_GetDIBits_selected_DIB(1);
3911 test_GetDIBits_selected_DIB(4);
3912 test_GetDIBits_selected_DIB(8);
3913 test_GetDIBits_selected_DDB(TRUE);
3914 test_GetDIBits_selected_DDB(FALSE);
3915 test_GetDIBits();
3916 test_GetDIBits_BI_BITFIELDS();
3917 test_select_object();
3918 test_CreateBitmap();
3919 test_BitBlt();
3920 test_StretchBlt();
3921 test_StretchDIBits();
3922 test_GdiAlphaBlend();
3923 test_32bit_bitmap_blt();
3924 test_bitmapinfoheadersize();
3925 test_get16dibits();
3926 test_clipping();
3927 test_GetDIBits_top_down(16);
3928 test_GetDIBits_top_down(24);
3929 test_GetDIBits_top_down(32);
3930 test_GetSetDIBits_rtl();
3931 test_GetDIBits_scanlines();
3932 test_SetDIBits();
3933 test_SetDIBits_RLE4();
3934 test_SetDIBits_RLE8();