gdi32: Validate the DIB parameters in functions that take a BITMAPINFO.
[wine/multimedia.git] / dlls / gdi32 / tests / bitmap.c
blob29f2c8c8dcae1adcd43d3ff51a388b5d1d9e1b1e
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 pbmi->bmiHeader.biBitCount = 16;
535 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
536 ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
537 ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
538 ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
539 SetLastError(0xdeadbeef);
540 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
541 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
543 /* test the DIB memory */
544 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
545 "VirtualQuery failed\n");
546 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
547 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
548 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
549 ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
550 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
551 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
552 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
554 test_dib_info(hdib, bits, &pbmi->bmiHeader);
555 DeleteObject(hdib);
557 memset(pbmi, 0, sizeof(bmibuf));
558 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
559 pbmi->bmiHeader.biHeight = 16;
560 pbmi->bmiHeader.biWidth = 16;
561 pbmi->bmiHeader.biBitCount = 1;
562 pbmi->bmiHeader.biPlanes = 1;
563 pbmi->bmiHeader.biCompression = BI_RGB;
564 pbmi->bmiColors[0].rgbRed = 0xff;
565 pbmi->bmiColors[0].rgbGreen = 0;
566 pbmi->bmiColors[0].rgbBlue = 0;
567 pbmi->bmiColors[1].rgbRed = 0;
568 pbmi->bmiColors[1].rgbGreen = 0;
569 pbmi->bmiColors[1].rgbBlue = 0xff;
571 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
572 ok(hdib != NULL, "CreateDIBSection failed\n");
573 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
574 ok(dibsec.dsBmih.biClrUsed == 2,
575 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
577 /* Test if the old BITMAPCOREINFO structure is supported */
579 pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
580 pbci->bmciHeader.bcBitCount = 0;
582 ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
583 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
584 ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
585 && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
586 "GetDIBits didn't fill in the BITMAPCOREHEADER structure properly\n");
588 ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
589 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
590 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
591 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
592 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
593 "The color table has not been translated to the old BITMAPCOREINFO format\n");
595 hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
596 ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
598 ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
599 ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
600 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
601 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
602 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
603 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
604 "The color table has not been translated to the old BITMAPCOREINFO format\n");
606 DeleteObject(hcoredib);
608 hdcmem = CreateCompatibleDC(hdc);
609 oldbm = SelectObject(hdcmem, hdib);
611 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
612 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
613 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
614 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
615 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
616 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
618 c0 = RGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen, pbmi->bmiColors[0].rgbBlue);
619 c1 = RGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen, pbmi->bmiColors[1].rgbBlue);
621 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
622 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
623 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
624 test_color(hdcmem, PALETTEINDEX(0), c0, 1, 1);
625 test_color(hdcmem, PALETTEINDEX(1), c0, 1, 1);
626 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
627 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen,
628 pbmi->bmiColors[0].rgbBlue), c0, 1, 1);
629 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen,
630 pbmi->bmiColors[1].rgbBlue), c1, 1, 1);
631 test_color(hdcmem, PALETTERGB(0, 0, 0), c0, 1, 1);
632 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
633 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1, 1, 1);
635 SelectObject(hdcmem, oldbm);
636 DeleteObject(hdib);
638 pbmi->bmiColors[0].rgbRed = 0xff;
639 pbmi->bmiColors[0].rgbGreen = 0xff;
640 pbmi->bmiColors[0].rgbBlue = 0xff;
641 pbmi->bmiColors[1].rgbRed = 0;
642 pbmi->bmiColors[1].rgbGreen = 0;
643 pbmi->bmiColors[1].rgbBlue = 0;
645 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
646 ok(hdib != NULL, "CreateDIBSection failed\n");
648 test_dib_info(hdib, bits, &pbmi->bmiHeader);
650 oldbm = SelectObject(hdcmem, hdib);
652 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
653 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
654 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
655 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
656 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
657 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
659 SelectObject(hdcmem, oldbm);
660 test_dib_info(hdib, bits, &pbmi->bmiHeader);
661 DeleteObject(hdib);
663 pbmi->bmiHeader.biBitCount = 4;
664 for (i = 0; i < 16; i++) {
665 pbmi->bmiColors[i].rgbRed = i;
666 pbmi->bmiColors[i].rgbGreen = 16-i;
667 pbmi->bmiColors[i].rgbBlue = 0;
669 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
670 ok(hdib != NULL, "CreateDIBSection failed\n");
671 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
672 ok(dibsec.dsBmih.biClrUsed == 16,
673 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
674 test_dib_info(hdib, bits, &pbmi->bmiHeader);
675 DeleteObject(hdib);
677 pbmi->bmiHeader.biBitCount = 8;
679 for (i = 0; i < 128; i++) {
680 pbmi->bmiColors[i].rgbRed = 255 - i * 2;
681 pbmi->bmiColors[i].rgbGreen = i * 2;
682 pbmi->bmiColors[i].rgbBlue = 0;
683 pbmi->bmiColors[255 - i].rgbRed = 0;
684 pbmi->bmiColors[255 - i].rgbGreen = i * 2;
685 pbmi->bmiColors[255 - i].rgbBlue = 255 - i * 2;
687 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
688 ok(hdib != NULL, "CreateDIBSection failed\n");
689 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
690 ok(dibsec.dsBmih.biClrUsed == 256,
691 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
693 oldbm = SelectObject(hdcmem, hdib);
695 for (i = 0; i < 256; i++) {
696 test_color(hdcmem, DIBINDEX(i),
697 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
698 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue),
699 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
702 SelectObject(hdcmem, oldbm);
703 test_dib_info(hdib, bits, &pbmi->bmiHeader);
704 DeleteObject(hdib);
706 pbmi->bmiHeader.biBitCount = 1;
708 /* Now create a palette and a palette indexed dib section */
709 memset(plogpal, 0, sizeof(logpalbuf));
710 plogpal->palVersion = 0x300;
711 plogpal->palNumEntries = 2;
712 plogpal->palPalEntry[0].peRed = 0xff;
713 plogpal->palPalEntry[0].peBlue = 0xff;
714 plogpal->palPalEntry[1].peGreen = 0xff;
716 index = (WORD*)pbmi->bmiColors;
717 *index++ = 0;
718 *index = 1;
719 hpal = CreatePalette(plogpal);
720 ok(hpal != NULL, "CreatePalette failed\n");
721 oldpal = SelectPalette(hdc, hpal, TRUE);
722 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
723 ok(hdib != NULL, "CreateDIBSection failed\n");
724 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
725 ok(dibsec.dsBmih.biClrUsed == 2, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
727 /* The colour table has already been grabbed from the dc, so we select back the
728 old palette */
730 SelectPalette(hdc, oldpal, TRUE);
731 oldbm = SelectObject(hdcmem, hdib);
732 oldpal = SelectPalette(hdcmem, hpal, TRUE);
734 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
735 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
736 ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
737 rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
738 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
739 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
740 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
742 c0 = RGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen, plogpal->palPalEntry[0].peBlue);
743 c1 = RGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen, plogpal->palPalEntry[1].peBlue);
745 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
746 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
747 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
748 test_color(hdcmem, PALETTEINDEX(0), c0, 0, 1);
749 test_color(hdcmem, PALETTEINDEX(1), c1, 0, 1);
750 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
751 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen,
752 plogpal->palPalEntry[0].peBlue), c0, 1, 1);
753 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen,
754 plogpal->palPalEntry[1].peBlue), c1, 1, 1);
755 test_color(hdcmem, PALETTERGB(0, 0, 0), c1, 1, 1);
756 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
757 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0, 1, 1);
758 test_color(hdcmem, PALETTERGB(0, 1, 0), c1, 1, 1);
759 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1, 1, 1);
760 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0, 1, 1);
762 /* Bottom and 2nd row from top green, everything else magenta */
763 bits[0] = bits[1] = 0xff;
764 bits[13 * 4] = bits[13*4 + 1] = 0xff;
766 test_dib_info(hdib, bits, &pbmi->bmiHeader);
768 pbmi->bmiHeader.biBitCount = 32;
770 hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
771 ok(hdib2 != NULL, "CreateDIBSection failed\n");
772 hdcmem2 = CreateCompatibleDC(hdc);
773 oldbm2 = SelectObject(hdcmem2, hdib2);
775 BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
777 ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
778 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
780 SelectObject(hdcmem2, oldbm2);
781 test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
782 DeleteObject(hdib2);
784 SelectObject(hdcmem, oldbm);
785 SelectPalette(hdcmem, oldpal, TRUE);
786 DeleteObject(hdib);
787 DeleteObject(hpal);
790 pbmi->bmiHeader.biBitCount = 8;
792 memset(plogpal, 0, sizeof(logpalbuf));
793 plogpal->palVersion = 0x300;
794 plogpal->palNumEntries = 256;
796 for (i = 0; i < 128; i++) {
797 plogpal->palPalEntry[i].peRed = 255 - i * 2;
798 plogpal->palPalEntry[i].peBlue = i * 2;
799 plogpal->palPalEntry[i].peGreen = 0;
800 plogpal->palPalEntry[255 - i].peRed = 0;
801 plogpal->palPalEntry[255 - i].peGreen = i * 2;
802 plogpal->palPalEntry[255 - i].peBlue = 255 - i * 2;
805 index = (WORD*)pbmi->bmiColors;
806 for (i = 0; i < 256; i++) {
807 *index++ = i;
810 hpal = CreatePalette(plogpal);
811 ok(hpal != NULL, "CreatePalette failed\n");
812 oldpal = SelectPalette(hdc, hpal, TRUE);
813 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
814 ok(hdib != NULL, "CreateDIBSection failed\n");
815 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
816 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
818 test_dib_info(hdib, bits, &pbmi->bmiHeader);
820 SelectPalette(hdc, oldpal, TRUE);
821 oldbm = SelectObject(hdcmem, hdib);
822 oldpal = SelectPalette(hdcmem, hpal, TRUE);
824 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
825 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
826 for (i = 0; i < 256; i++) {
827 ok(rgb[i].rgbRed == plogpal->palPalEntry[i].peRed &&
828 rgb[i].rgbBlue == plogpal->palPalEntry[i].peBlue &&
829 rgb[i].rgbGreen == plogpal->palPalEntry[i].peGreen,
830 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
831 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
834 for (i = 0; i < 256; i++) {
835 test_color(hdcmem, DIBINDEX(i),
836 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
837 test_color(hdcmem, PALETTEINDEX(i),
838 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
839 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue),
840 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
843 SelectPalette(hdcmem, oldpal, TRUE);
844 SelectObject(hdcmem, oldbm);
845 DeleteObject(hdib);
846 DeleteObject(hpal);
848 DeleteDC(hdcmem);
849 DeleteDC(hdcmem2);
850 ReleaseDC(0, hdc);
853 static void test_dib_formats(void)
855 char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256])];
856 BITMAPINFO *bi = (BITMAPINFO *)buffer;
857 char data[256];
858 void *bits;
859 int planes, bpp, compr;
860 HBITMAP hdib, hbmp;
861 HDC hdc, memdc;
862 UINT ret;
863 BOOL expect_ok, todo;
865 hdc = GetDC( 0 );
866 memdc = CreateCompatibleDC( 0 );
867 hbmp = CreateCompatibleBitmap( hdc, 10, 10 );
869 memset( data, 0xaa, sizeof(data) );
871 for (bpp = 0; bpp <= 64; bpp++)
873 for (planes = 0; planes <= 64; planes++)
875 for (compr = 0; compr < 8; compr++)
877 switch (bpp)
879 case 1:
880 case 4:
881 case 8:
882 case 24: expect_ok = (compr == BI_RGB); break;
883 case 16:
884 case 32: expect_ok = (compr == BI_RGB || compr == BI_BITFIELDS); break;
885 default: expect_ok = FALSE; break;
887 if (!planes) expect_ok = FALSE;
888 todo = (compr == BI_BITFIELDS); /* wine doesn't like strange bitfields */
890 memset( bi, 0, sizeof(bi->bmiHeader) );
891 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
892 bi->bmiHeader.biWidth = 2;
893 bi->bmiHeader.biHeight = 2;
894 bi->bmiHeader.biPlanes = planes;
895 bi->bmiHeader.biBitCount = bpp;
896 bi->bmiHeader.biCompression = compr;
897 bi->bmiHeader.biSizeImage = 0;
898 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
900 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
901 if (expect_ok && (planes == 1 || planes * bpp <= 16))
902 ok( hdib != NULL, "CreateDIBSection failed for %u/%u/%u\n", bpp, planes, compr );
903 else
904 ok( hdib == NULL, "CreateDIBSection succeeded for %u/%u/%u\n", bpp, planes, compr );
905 if (hdib) DeleteObject( hdib );
907 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, data, bi, DIB_RGB_COLORS );
908 /* no sanity checks in CreateDIBitmap except compression */
909 if (compr == BI_JPEG || compr == BI_PNG)
910 ok( hdib == NULL || broken(hdib != NULL), /* nt4 */
911 "CreateDIBitmap succeeded for %u/%u/%u\n", bpp, planes, compr );
912 else
913 ok( hdib != NULL, "CreateDIBitmap failed for %u/%u/%u\n", bpp, planes, compr );
914 if (hdib) DeleteObject( hdib );
916 /* RLE needs a size */
917 bi->bmiHeader.biSizeImage = 0;
918 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
919 if (expect_ok)
921 if (todo)
922 todo_wine ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
923 else
924 ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
926 else
927 ok( !ret ||
928 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
929 "SetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
930 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
931 if (expect_ok)
932 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
933 else
934 ok( !ret ||
935 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
936 "SetDIBitsToDevice succeeded for %u/%u/%u\n", bpp, planes, compr );
937 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
938 if (expect_ok)
940 if (todo)
941 todo_wine ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
942 else
943 ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
945 else
946 ok( !ret ||
947 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
948 "StretchDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
950 bi->bmiHeader.biSizeImage = 1;
951 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
952 if (expect_ok || (bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8))
954 if (todo)
955 todo_wine ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
956 else
957 ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
959 else
960 ok( !ret, "SetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
961 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
962 if (expect_ok || (bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8))
963 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
964 else
965 ok( !ret, "SetDIBitsToDevice succeeded for %u/%u/%u\n", bpp, planes, compr );
966 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
967 if (expect_ok || (bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8))
969 if (todo)
970 todo_wine ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
971 else
972 ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
974 else
975 ok( !ret, "StretchDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
980 memset( bi, 0, sizeof(bi->bmiHeader) );
981 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
982 bi->bmiHeader.biWidth = 2;
983 bi->bmiHeader.biHeight = 2;
984 bi->bmiHeader.biPlanes = 1;
985 bi->bmiHeader.biBitCount = 16;
986 bi->bmiHeader.biCompression = BI_BITFIELDS;
987 bi->bmiHeader.biSizeImage = 0;
988 *(DWORD *)&bi->bmiColors[0] = 0;
989 *(DWORD *)&bi->bmiColors[1] = 0;
990 *(DWORD *)&bi->bmiColors[2] = 0;
992 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
993 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
994 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
995 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
996 /* other functions don't check */
997 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
998 ok( hdib != NULL, "CreateDIBitmap failed with null bitfields\n" );
999 DeleteObject( hdib );
1000 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1001 ok( ret, "SetDIBitsToDevice failed with null bitfields\n" );
1002 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1003 todo_wine ok( ret, "StretchDIBits failed with null bitfields\n" );
1005 /* all fields must be non-zero */
1006 *(DWORD *)&bi->bmiColors[0] = 3;
1007 *(DWORD *)&bi->bmiColors[1] = 0;
1008 *(DWORD *)&bi->bmiColors[2] = 7;
1009 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1010 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1011 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1012 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1014 /* garbage is ok though */
1015 *(DWORD *)&bi->bmiColors[0] = 0x55;
1016 *(DWORD *)&bi->bmiColors[1] = 0x44;
1017 *(DWORD *)&bi->bmiColors[2] = 0x33;
1018 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1019 ok( hdib != NULL, "CreateDIBSection failed with bad bitfields\n" );
1020 if (hdib) DeleteObject( hdib );
1021 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1022 todo_wine ok( ret, "SetDIBits failed with bad bitfields\n" );
1024 bi->bmiHeader.biWidth = -2;
1025 bi->bmiHeader.biHeight = 2;
1026 bi->bmiHeader.biBitCount = 32;
1027 bi->bmiHeader.biCompression = BI_RGB;
1028 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1029 ok( hdib == NULL, "CreateDIBSection succeeded with negative width\n" );
1030 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1031 ok( hdib == NULL, "CreateDIBitmap succeeded with negative width\n" );
1032 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1033 ok( !ret, "SetDIBits succeeded with negative width\n" );
1034 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1035 ok( !ret, "SetDIBitsToDevice succeeded with negative width\n" );
1036 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1037 ok( !ret, "StretchDIBits succeeded with negative width\n" );
1039 bi->bmiHeader.biWidth = 0;
1040 bi->bmiHeader.biHeight = 2;
1041 bi->bmiHeader.biBitCount = 32;
1042 bi->bmiHeader.biCompression = BI_RGB;
1043 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1044 ok( hdib == NULL, "CreateDIBSection succeeded with zero width\n" );
1045 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1046 ok( hdib != NULL, "CreateDIBitmap failed with zero width\n" );
1047 DeleteObject( hdib );
1048 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1049 ok( !ret || broken(ret), /* nt4 */ "SetDIBits succeeded with zero width\n" );
1050 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1051 ok( !ret || broken(ret), /* nt4 */ "SetDIBitsToDevice succeeded with zero width\n" );
1052 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1053 ok( !ret || broken(ret), /* nt4 */ "StretchDIBits succeeded with zero width\n" );
1055 bi->bmiHeader.biWidth = 2;
1056 bi->bmiHeader.biHeight = 0;
1057 bi->bmiHeader.biBitCount = 32;
1058 bi->bmiHeader.biCompression = BI_RGB;
1059 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1060 ok( hdib == NULL, "CreateDIBSection succeeded with zero height\n" );
1061 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1062 ok( hdib != NULL, "CreateDIBitmap failed with zero height\n" );
1063 DeleteObject( hdib );
1064 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1065 ok( !ret, "SetDIBits succeeded with zero height\n" );
1066 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1067 ok( !ret, "SetDIBitsToDevice succeeded with zero height\n" );
1068 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1069 ok( !ret, "StretchDIBits succeeded with zero height\n" );
1071 DeleteDC( memdc );
1072 DeleteObject( hbmp );
1073 ReleaseDC( 0, hdc );
1076 static void test_mono_dibsection(void)
1078 HDC hdc, memdc;
1079 HBITMAP old_bm, mono_ds;
1080 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
1081 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
1082 BYTE bits[10 * 4];
1083 BYTE *ds_bits;
1084 int num;
1086 hdc = GetDC(0);
1088 memdc = CreateCompatibleDC(hdc);
1090 memset(pbmi, 0, sizeof(bmibuf));
1091 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
1092 pbmi->bmiHeader.biHeight = 10;
1093 pbmi->bmiHeader.biWidth = 10;
1094 pbmi->bmiHeader.biBitCount = 1;
1095 pbmi->bmiHeader.biPlanes = 1;
1096 pbmi->bmiHeader.biCompression = BI_RGB;
1097 pbmi->bmiColors[0].rgbRed = 0xff;
1098 pbmi->bmiColors[0].rgbGreen = 0xff;
1099 pbmi->bmiColors[0].rgbBlue = 0xff;
1100 pbmi->bmiColors[1].rgbRed = 0x0;
1101 pbmi->bmiColors[1].rgbGreen = 0x0;
1102 pbmi->bmiColors[1].rgbBlue = 0x0;
1105 * First dib section is 'inverted' ie color[0] is white, color[1] is black
1108 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1109 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1110 old_bm = SelectObject(memdc, mono_ds);
1112 /* black border, white interior */
1113 Rectangle(memdc, 0, 0, 10, 10);
1114 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1115 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1117 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1119 memset(bits, 0, sizeof(bits));
1120 bits[0] = 0xaa;
1122 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1123 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1125 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1127 pbmi->bmiColors[0].rgbRed = 0x0;
1128 pbmi->bmiColors[0].rgbGreen = 0x0;
1129 pbmi->bmiColors[0].rgbBlue = 0x0;
1130 pbmi->bmiColors[1].rgbRed = 0xff;
1131 pbmi->bmiColors[1].rgbGreen = 0xff;
1132 pbmi->bmiColors[1].rgbBlue = 0xff;
1134 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1135 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1137 SelectObject(memdc, old_bm);
1138 DeleteObject(mono_ds);
1141 * Next dib section is 'normal' ie color[0] is black, color[1] is white
1144 pbmi->bmiColors[0].rgbRed = 0x0;
1145 pbmi->bmiColors[0].rgbGreen = 0x0;
1146 pbmi->bmiColors[0].rgbBlue = 0x0;
1147 pbmi->bmiColors[1].rgbRed = 0xff;
1148 pbmi->bmiColors[1].rgbGreen = 0xff;
1149 pbmi->bmiColors[1].rgbBlue = 0xff;
1151 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1152 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1153 old_bm = SelectObject(memdc, mono_ds);
1155 /* black border, white interior */
1156 Rectangle(memdc, 0, 0, 10, 10);
1157 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
1158 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
1160 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
1162 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1163 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1165 /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
1167 pbmi->bmiColors[0].rgbRed = 0xff;
1168 pbmi->bmiColors[0].rgbGreen = 0xff;
1169 pbmi->bmiColors[0].rgbBlue = 0xff;
1170 pbmi->bmiColors[1].rgbRed = 0x0;
1171 pbmi->bmiColors[1].rgbGreen = 0x0;
1172 pbmi->bmiColors[1].rgbBlue = 0x0;
1174 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1175 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1178 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
1181 pbmi->bmiColors[0].rgbRed = 0xff;
1182 pbmi->bmiColors[0].rgbGreen = 0xff;
1183 pbmi->bmiColors[0].rgbBlue = 0xff;
1184 pbmi->bmiColors[1].rgbRed = 0x0;
1185 pbmi->bmiColors[1].rgbGreen = 0x0;
1186 pbmi->bmiColors[1].rgbBlue = 0x0;
1187 num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors);
1188 ok(num == 2, "num = %d\n", num);
1190 /* black border, white interior */
1191 Rectangle(memdc, 0, 0, 10, 10);
1192 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1193 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1195 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1197 memset(bits, 0, sizeof(bits));
1198 bits[0] = 0xaa;
1200 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1201 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1203 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1205 pbmi->bmiColors[0].rgbRed = 0x0;
1206 pbmi->bmiColors[0].rgbGreen = 0x0;
1207 pbmi->bmiColors[0].rgbBlue = 0x0;
1208 pbmi->bmiColors[1].rgbRed = 0xff;
1209 pbmi->bmiColors[1].rgbGreen = 0xff;
1210 pbmi->bmiColors[1].rgbBlue = 0xff;
1212 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1213 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1215 SelectObject(memdc, old_bm);
1216 DeleteObject(mono_ds);
1219 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
1222 pbmi->bmiColors[0].rgbRed = 0xff;
1223 pbmi->bmiColors[0].rgbGreen = 0x0;
1224 pbmi->bmiColors[0].rgbBlue = 0x0;
1225 pbmi->bmiColors[1].rgbRed = 0xfe;
1226 pbmi->bmiColors[1].rgbGreen = 0x0;
1227 pbmi->bmiColors[1].rgbBlue = 0x0;
1229 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1230 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1231 old_bm = SelectObject(memdc, mono_ds);
1233 /* black border, white interior */
1234 Rectangle(memdc, 0, 0, 10, 10);
1235 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1236 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1238 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1240 pbmi->bmiColors[0].rgbRed = 0x0;
1241 pbmi->bmiColors[0].rgbGreen = 0x0;
1242 pbmi->bmiColors[0].rgbBlue = 0x0;
1243 pbmi->bmiColors[1].rgbRed = 0xff;
1244 pbmi->bmiColors[1].rgbGreen = 0xff;
1245 pbmi->bmiColors[1].rgbBlue = 0xff;
1247 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1248 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1250 /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
1252 pbmi->bmiColors[0].rgbRed = 0xff;
1253 pbmi->bmiColors[0].rgbGreen = 0xff;
1254 pbmi->bmiColors[0].rgbBlue = 0xff;
1255 pbmi->bmiColors[1].rgbRed = 0x0;
1256 pbmi->bmiColors[1].rgbGreen = 0x0;
1257 pbmi->bmiColors[1].rgbBlue = 0x0;
1259 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1260 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1262 SelectObject(memdc, old_bm);
1263 DeleteObject(mono_ds);
1265 DeleteDC(memdc);
1266 ReleaseDC(0, hdc);
1269 static void test_bitmap(void)
1271 char buf[256], buf_cmp[256];
1272 HBITMAP hbmp, hbmp_old;
1273 HDC hdc;
1274 BITMAP bm;
1275 BITMAP bma[2];
1276 INT ret;
1278 hdc = CreateCompatibleDC(0);
1279 assert(hdc != 0);
1281 SetLastError(0xdeadbeef);
1282 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1283 if (!hbmp)
1285 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1286 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1287 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1289 else
1290 DeleteObject(hbmp);
1292 SetLastError(0xdeadbeef);
1293 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1294 if (!hbmp)
1296 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1297 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1298 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1300 else
1301 DeleteObject(hbmp);
1303 SetLastError(0xdeadbeef);
1304 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1305 ok(!hbmp, "CreateBitmap should fail\n");
1306 if (!hbmp)
1307 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1308 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1309 else
1310 DeleteObject(hbmp);
1312 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1313 assert(hbmp != NULL);
1315 ret = GetObject(hbmp, sizeof(bm), &bm);
1316 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1318 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1319 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1320 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1321 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1322 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1323 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1324 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1326 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1327 assert(sizeof(buf) == sizeof(buf_cmp));
1329 ret = GetBitmapBits(hbmp, 0, NULL);
1330 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1332 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1333 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1335 memset(buf, 0xAA, sizeof(buf));
1336 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1337 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1338 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1340 hbmp_old = SelectObject(hdc, hbmp);
1342 ret = GetObject(hbmp, sizeof(bm), &bm);
1343 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1345 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1346 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1347 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1348 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1349 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1350 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1351 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1353 memset(buf, 0xAA, sizeof(buf));
1354 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1355 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1356 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1358 hbmp_old = SelectObject(hdc, hbmp_old);
1359 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1361 /* test various buffer sizes for GetObject */
1362 ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
1363 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1365 ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1366 ok(ret == 0, "%d != 0\n", ret);
1368 ret = GetObject(hbmp, 0, &bm);
1369 ok(ret == 0, "%d != 0\n", ret);
1371 ret = GetObject(hbmp, 1, &bm);
1372 ok(ret == 0, "%d != 0\n", ret);
1374 DeleteObject(hbmp);
1375 DeleteDC(hdc);
1378 static void test_bmBits(void)
1380 BYTE bits[4];
1381 HBITMAP hbmp;
1382 BITMAP bmp;
1384 memset(bits, 0, sizeof(bits));
1385 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1386 ok(hbmp != NULL, "CreateBitmap failed\n");
1388 memset(&bmp, 0xFF, sizeof(bmp));
1389 ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1390 "GetObject failed or returned a wrong structure size\n");
1391 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1393 DeleteObject(hbmp);
1396 static void test_GetDIBits_selected_DIB(UINT bpp)
1398 HBITMAP dib;
1399 char bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1400 char bmibuf2[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1401 BITMAPINFO *info = (BITMAPINFO *)bmibuf;
1402 BITMAPINFO *info2 = (BITMAPINFO *)bmibuf2;
1403 void * bits;
1404 void * bits2;
1405 UINT dib_size, dib32_size;
1406 DWORD pixel;
1407 HDC dib_dc, dc;
1408 HBITMAP old_bmp;
1409 UINT i;
1410 int res;
1412 /* Create a DIB section with a color table */
1414 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1415 info->bmiHeader.biWidth = 32;
1416 info->bmiHeader.biHeight = 32;
1417 info->bmiHeader.biPlanes = 1;
1418 info->bmiHeader.biBitCount = bpp;
1419 info->bmiHeader.biCompression = BI_RGB;
1420 info->bmiHeader.biXPelsPerMeter = 0;
1421 info->bmiHeader.biYPelsPerMeter = 0;
1422 info->bmiHeader.biClrUsed = 0;
1423 info->bmiHeader.biClrImportant = 0;
1425 for (i=0; i < (1u << bpp); i++)
1427 BYTE c = i * (1 << (8 - bpp));
1428 info->bmiColors[i].rgbRed = c;
1429 info->bmiColors[i].rgbGreen = c;
1430 info->bmiColors[i].rgbBlue = c;
1431 info->bmiColors[i].rgbReserved = 0;
1434 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1435 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1436 dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1438 /* Set the bits of the DIB section */
1439 for (i=0; i < dib_size; i++)
1441 ((BYTE *)bits)[i] = i % 256;
1444 /* Select the DIB into a DC */
1445 dib_dc = CreateCompatibleDC(NULL);
1446 old_bmp = SelectObject(dib_dc, dib);
1447 dc = CreateCompatibleDC(NULL);
1448 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
1450 /* Copy the DIB attributes but not the color table */
1451 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1453 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1454 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1456 /* Compare the color table and the bits */
1457 for (i=0; i < (1u << bpp); i++)
1458 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1459 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1460 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1461 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1462 "color table entry %d differs (bpp %d)\n", i, bpp );
1464 ok( !memcmp( bits, bits2, dib_size ), "bit mismatch (bpp %d)\n", bpp );
1466 /* Test various combinations of lines = 0 and bits2 = NULL */
1467 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1468 res = GetDIBits( dc, dib, 0, 0, bits2, info2, DIB_RGB_COLORS );
1469 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1470 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1471 "color table mismatch (bpp %d)\n", bpp );
1473 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1474 res = GetDIBits( dc, dib, 0, 0, NULL, info2, DIB_RGB_COLORS );
1475 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1476 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1477 "color table mismatch (bpp %d)\n", bpp );
1479 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1480 res = GetDIBits( dc, dib, 0, info->bmiHeader.biHeight, NULL, info2, DIB_RGB_COLORS );
1481 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1482 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1483 "color table mismatch (bpp %d)\n", bpp );
1485 /* Map into a 32bit-DIB */
1486 info2->bmiHeader.biBitCount = 32;
1487 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1488 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1490 /* Check if last pixel was set */
1491 pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
1492 ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
1494 HeapFree(GetProcessHeap(), 0, bits2);
1495 DeleteDC(dc);
1497 SelectObject(dib_dc, old_bmp);
1498 DeleteDC(dib_dc);
1499 DeleteObject(dib);
1502 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1504 HBITMAP ddb;
1505 char bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1506 char bmibuf2[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1507 BITMAPINFO *info = (BITMAPINFO *)bmibuf;
1508 BITMAPINFO *info2 = (BITMAPINFO *)bmibuf2;
1509 void * bits;
1510 void * bits2;
1511 HDC ddb_dc, dc;
1512 HBITMAP old_bmp;
1513 UINT width, height;
1514 UINT bpp;
1515 UINT i, j;
1516 int res;
1518 width = height = 16;
1520 /* Create a DDB (device-dependent bitmap) */
1521 if (monochrome)
1523 bpp = 1;
1524 ddb = CreateBitmap(width, height, 1, 1, NULL);
1526 else
1528 HDC screen_dc = GetDC(NULL);
1529 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1530 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1531 ReleaseDC(NULL, screen_dc);
1534 /* Set the pixels */
1535 ddb_dc = CreateCompatibleDC(NULL);
1536 old_bmp = SelectObject(ddb_dc, ddb);
1537 for (i = 0; i < width; i++)
1539 for (j=0; j < height; j++)
1541 BYTE c = (i * width + j) % 256;
1542 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1545 SelectObject(ddb_dc, old_bmp);
1547 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1548 info->bmiHeader.biWidth = width;
1549 info->bmiHeader.biHeight = height;
1550 info->bmiHeader.biPlanes = 1;
1551 info->bmiHeader.biBitCount = bpp;
1552 info->bmiHeader.biCompression = BI_RGB;
1554 dc = CreateCompatibleDC(NULL);
1556 /* Fill in biSizeImage */
1557 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1558 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1560 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1561 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1563 /* Get the bits */
1564 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1565 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1567 /* Copy the DIB attributes but not the color table */
1568 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1570 /* Select the DDB into another DC */
1571 old_bmp = SelectObject(ddb_dc, ddb);
1573 /* Get the bits */
1574 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1575 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1577 /* Compare the color table and the bits */
1578 if (bpp <= 8)
1580 for (i=0; i < (1u << bpp); i++)
1581 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1582 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1583 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1584 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1585 "color table entry %d differs (bpp %d)\n", i, bpp );
1588 ok( !memcmp( bits, bits2, info->bmiHeader.biSizeImage ), "bit mismatch (bpp %d)\n", bpp );
1590 /* Test the palette */
1591 if (info2->bmiHeader.biBitCount <= 8)
1593 WORD *colors = (WORD*)info2->bmiColors;
1595 /* Get the palette indices */
1596 res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1597 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1599 for (i = 0; i < (1 << info->bmiHeader.biBitCount); i++)
1600 ok( colors[i] == i, "%d: got %d (bpp %d)\n", i, colors[i], bpp );
1603 HeapFree(GetProcessHeap(), 0, bits2);
1604 HeapFree(GetProcessHeap(), 0, bits);
1605 DeleteDC(dc);
1607 SelectObject(ddb_dc, old_bmp);
1608 DeleteDC(ddb_dc);
1609 DeleteObject(ddb);
1612 static void test_GetDIBits(void)
1614 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1615 static const BYTE bmp_bits_1[16 * 2] =
1617 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1618 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1619 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1620 0xff,0xff, 0,0, 0xff,0xff, 0,0
1622 /* 4-bytes aligned 1-bit DIB data: 16x16 */
1623 static const BYTE dib_bits_1[16 * 4] =
1625 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1626 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1627 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1628 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1630 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1631 static const BYTE bmp_bits_24[16 * 16*3] =
1633 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1634 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1635 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1636 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1637 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1638 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1639 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1640 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1641 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1642 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1643 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1644 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1645 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1646 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1647 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1648 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1649 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1650 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1651 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1652 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1653 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1654 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1655 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1656 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1657 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1658 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1659 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1660 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1661 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1662 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1663 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1664 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1666 /* 4-bytes aligned 24-bit DIB data: 16x16 */
1667 static const BYTE dib_bits_24[16 * 16*3] =
1669 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1670 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1671 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1672 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1673 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1674 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1675 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1676 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1677 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1678 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1679 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1680 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1681 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1682 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1683 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1684 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1685 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1686 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1687 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1688 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1689 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1690 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1691 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1692 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1693 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1694 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1695 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1696 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1697 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1698 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1699 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1700 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1702 HBITMAP hbmp;
1703 BITMAP bm;
1704 HDC hdc;
1705 int i, bytes, lines;
1706 BYTE buf[1024];
1707 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1708 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1709 PALETTEENTRY pal_ents[20];
1711 hdc = GetDC(0);
1713 /* 1-bit source bitmap data */
1714 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1715 ok(hbmp != 0, "CreateBitmap failed\n");
1717 memset(&bm, 0xAA, sizeof(bm));
1718 bytes = GetObject(hbmp, sizeof(bm), &bm);
1719 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1720 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1721 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1722 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1723 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1724 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1725 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1726 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1728 bytes = GetBitmapBits(hbmp, 0, NULL);
1729 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1730 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1731 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1732 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1734 /* retrieve 1-bit DIB data */
1735 memset(bi, 0, sizeof(*bi));
1736 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1737 bi->bmiHeader.biWidth = bm.bmWidth;
1738 bi->bmiHeader.biHeight = bm.bmHeight;
1739 bi->bmiHeader.biPlanes = 1;
1740 bi->bmiHeader.biBitCount = 1;
1741 bi->bmiHeader.biCompression = BI_RGB;
1742 bi->bmiHeader.biSizeImage = 0;
1743 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1744 SetLastError(0xdeadbeef);
1745 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1746 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1747 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1748 broken(GetLastError() == 0xdeadbeef), /* winnt */
1749 "wrong error %u\n", GetLastError());
1750 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1752 memset(buf, 0xAA, sizeof(buf));
1753 SetLastError(0xdeadbeef);
1754 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1755 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1756 lines, bm.bmHeight, GetLastError());
1757 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1759 /* the color table consists of black and white */
1760 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1761 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1762 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1763 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1764 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1765 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1766 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1767 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1768 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1769 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1770 for (i = 2; i < 256; i++)
1772 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1773 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1774 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1775 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1776 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1779 /* returned bits are DWORD aligned and upside down */
1780 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1782 /* Test the palette indices */
1783 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1784 SetLastError(0xdeadbeef);
1785 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1786 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1787 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1788 for (i = 2; i < 256; i++)
1789 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[1]);
1791 /* retrieve 24-bit DIB data */
1792 memset(bi, 0, sizeof(*bi));
1793 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1794 bi->bmiHeader.biWidth = bm.bmWidth;
1795 bi->bmiHeader.biHeight = bm.bmHeight;
1796 bi->bmiHeader.biPlanes = 1;
1797 bi->bmiHeader.biBitCount = 24;
1798 bi->bmiHeader.biCompression = BI_RGB;
1799 bi->bmiHeader.biSizeImage = 0;
1800 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1801 memset(buf, 0xAA, sizeof(buf));
1802 SetLastError(0xdeadbeef);
1803 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1804 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1805 lines, bm.bmHeight, GetLastError());
1806 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1808 /* the color table doesn't exist for 24-bit images */
1809 for (i = 0; i < 256; i++)
1811 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1812 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1813 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1814 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1815 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1818 /* returned bits are DWORD aligned and upside down */
1819 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1820 DeleteObject(hbmp);
1822 /* 24-bit source bitmap data */
1823 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1824 ok(hbmp != 0, "CreateBitmap failed\n");
1825 SetLastError(0xdeadbeef);
1826 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1827 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1828 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1829 lines, bm.bmHeight, GetLastError());
1831 memset(&bm, 0xAA, sizeof(bm));
1832 bytes = GetObject(hbmp, sizeof(bm), &bm);
1833 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1834 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1835 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1836 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1837 ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1838 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1839 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1840 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1842 bytes = GetBitmapBits(hbmp, 0, NULL);
1843 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
1844 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1845 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1846 bm.bmWidthBytes * bm.bmHeight, bytes);
1848 /* retrieve 1-bit DIB data */
1849 memset(bi, 0, sizeof(*bi));
1850 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1851 bi->bmiHeader.biWidth = bm.bmWidth;
1852 bi->bmiHeader.biHeight = bm.bmHeight;
1853 bi->bmiHeader.biPlanes = 1;
1854 bi->bmiHeader.biBitCount = 1;
1855 bi->bmiHeader.biCompression = BI_RGB;
1856 bi->bmiHeader.biSizeImage = 0;
1857 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1858 memset(buf, 0xAA, sizeof(buf));
1859 SetLastError(0xdeadbeef);
1860 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1861 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1862 lines, bm.bmHeight, GetLastError());
1863 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1865 /* the color table consists of black and white */
1866 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1867 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1868 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1869 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1870 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1871 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1872 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1873 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1874 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1875 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1876 for (i = 2; i < 256; i++)
1878 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1879 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1880 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1881 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1882 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1885 /* returned bits are DWORD aligned and upside down */
1886 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1888 /* Test the palette indices */
1889 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1890 SetLastError(0xdeadbeef);
1891 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1892 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1893 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1894 for (i = 2; i < 256; i++)
1895 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[i]);
1897 /* retrieve 4-bit DIB data */
1898 memset(bi, 0, sizeof(*bi));
1899 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1900 bi->bmiHeader.biWidth = bm.bmWidth;
1901 bi->bmiHeader.biHeight = bm.bmHeight;
1902 bi->bmiHeader.biPlanes = 1;
1903 bi->bmiHeader.biBitCount = 4;
1904 bi->bmiHeader.biCompression = BI_RGB;
1905 bi->bmiHeader.biSizeImage = 0;
1906 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1907 memset(buf, 0xAA, sizeof(buf));
1908 SetLastError(0xdeadbeef);
1909 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1910 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1911 lines, bm.bmHeight, GetLastError());
1913 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
1915 for (i = 0; i < 16; i++)
1917 RGBQUAD expect;
1918 int entry = i < 8 ? i : i + 4;
1920 if(entry == 7) entry = 12;
1921 else if(entry == 12) entry = 7;
1923 expect.rgbRed = pal_ents[entry].peRed;
1924 expect.rgbGreen = pal_ents[entry].peGreen;
1925 expect.rgbBlue = pal_ents[entry].peBlue;
1926 expect.rgbReserved = 0;
1928 ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
1929 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
1930 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
1931 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1932 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1935 /* retrieve 8-bit DIB data */
1936 memset(bi, 0, sizeof(*bi));
1937 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1938 bi->bmiHeader.biWidth = bm.bmWidth;
1939 bi->bmiHeader.biHeight = bm.bmHeight;
1940 bi->bmiHeader.biPlanes = 1;
1941 bi->bmiHeader.biBitCount = 8;
1942 bi->bmiHeader.biCompression = BI_RGB;
1943 bi->bmiHeader.biSizeImage = 0;
1944 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1945 memset(buf, 0xAA, sizeof(buf));
1946 SetLastError(0xdeadbeef);
1947 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1948 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1949 lines, bm.bmHeight, GetLastError());
1951 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
1953 for (i = 0; i < 256; i++)
1955 RGBQUAD expect;
1957 if (i < 10 || i >= 246)
1959 int entry = i < 10 ? i : i - 236;
1960 expect.rgbRed = pal_ents[entry].peRed;
1961 expect.rgbGreen = pal_ents[entry].peGreen;
1962 expect.rgbBlue = pal_ents[entry].peBlue;
1964 else
1966 expect.rgbRed = (i & 0x07) << 5;
1967 expect.rgbGreen = (i & 0x38) << 2;
1968 expect.rgbBlue = i & 0xc0;
1970 expect.rgbReserved = 0;
1972 ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
1973 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
1974 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
1975 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1976 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1979 /* retrieve 24-bit DIB data */
1980 memset(bi, 0, sizeof(*bi));
1981 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1982 bi->bmiHeader.biWidth = bm.bmWidth;
1983 bi->bmiHeader.biHeight = bm.bmHeight;
1984 bi->bmiHeader.biPlanes = 1;
1985 bi->bmiHeader.biBitCount = 24;
1986 bi->bmiHeader.biCompression = BI_RGB;
1987 bi->bmiHeader.biSizeImage = 0;
1988 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1989 memset(buf, 0xAA, sizeof(buf));
1990 SetLastError(0xdeadbeef);
1991 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1992 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1993 lines, bm.bmHeight, GetLastError());
1994 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1996 /* the color table doesn't exist for 24-bit images */
1997 for (i = 0; i < 256; i++)
1999 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
2000 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
2001 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2002 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
2003 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
2006 /* returned bits are DWORD aligned and upside down */
2007 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2008 DeleteObject(hbmp);
2010 ReleaseDC(0, hdc);
2013 static void test_GetDIBits_BI_BITFIELDS(void)
2015 /* Try a screen resolution detection technique
2016 * from the September 1999 issue of Windows Developer's Journal
2017 * which seems to be in widespread use.
2018 * http://www.lesher.ws/highcolor.html
2019 * http://www.lesher.ws/vidfmt.c
2020 * It hinges on being able to retrieve the bitmaps
2021 * for the three primary colors in non-paletted 16 bit mode.
2023 char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
2024 DWORD bits[32];
2025 LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
2026 DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
2027 HDC hdc;
2028 HBITMAP hbm;
2029 int ret;
2030 void *ptr;
2032 memset(dibinfo, 0, sizeof(dibinfo_buf));
2033 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2035 hdc = GetDC(NULL);
2036 ok(hdc != NULL, "GetDC failed?\n");
2037 hbm = CreateCompatibleBitmap(hdc, 1, 1);
2038 ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
2040 /* Call GetDIBits to fill in bmiHeader. */
2041 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2042 ok(ret == 1, "GetDIBits failed\n");
2043 if (dibinfo->bmiHeader.biBitCount > 8)
2045 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2046 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2047 "compression is %u (%d bpp)\n", dibinfo->bmiHeader.biCompression, dibinfo->bmiHeader.biBitCount );
2049 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2051 ok( !bitmasks[0], "red mask is set\n" );
2052 ok( !bitmasks[1], "green mask is set\n" );
2053 ok( !bitmasks[2], "blue mask is set\n" );
2055 /* test with NULL bits pointer and correct bpp */
2056 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2057 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2058 ok(ret == 1, "GetDIBits failed\n");
2060 ok( bitmasks[0] != 0, "red mask is not set\n" );
2061 ok( bitmasks[1] != 0, "green mask is not set\n" );
2062 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2063 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2065 /* test with valid bits pointer */
2066 memset(dibinfo, 0, sizeof(dibinfo_buf));
2067 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2068 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2069 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2070 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2071 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2072 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2074 ok( bitmasks[0] != 0, "red mask is not set\n" );
2075 ok( bitmasks[1] != 0, "green mask is not set\n" );
2076 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2077 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2079 /* now with bits and 0 lines */
2080 memset(dibinfo, 0, sizeof(dibinfo_buf));
2081 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2082 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2083 SetLastError(0xdeadbeef);
2084 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2085 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2087 ok( !bitmasks[0], "red mask is set\n" );
2088 ok( !bitmasks[1], "green mask is set\n" );
2089 ok( !bitmasks[2], "blue mask is set\n" );
2090 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2092 memset(bitmasks, 0, 3*sizeof(DWORD));
2093 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2094 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2095 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2097 ok( bitmasks[0] != 0, "red mask is not set\n" );
2098 ok( bitmasks[1] != 0, "green mask is not set\n" );
2099 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2100 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2103 else skip("bitmap in colortable mode, skipping BI_BITFIELDS tests\n");
2105 DeleteObject(hbm);
2107 /* same thing now with a 32-bpp DIB section */
2109 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2110 dibinfo->bmiHeader.biWidth = 1;
2111 dibinfo->bmiHeader.biHeight = 1;
2112 dibinfo->bmiHeader.biPlanes = 1;
2113 dibinfo->bmiHeader.biBitCount = 32;
2114 dibinfo->bmiHeader.biCompression = BI_RGB;
2115 dibinfo->bmiHeader.biSizeImage = 0;
2116 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2117 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2118 dibinfo->bmiHeader.biClrUsed = 0;
2119 dibinfo->bmiHeader.biClrImportant = 0;
2120 bitmasks[0] = 0x0000ff;
2121 bitmasks[1] = 0x00ff00;
2122 bitmasks[2] = 0xff0000;
2123 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2124 ok( hbm != 0, "failed to create bitmap\n" );
2126 memset(dibinfo, 0, sizeof(dibinfo_buf));
2127 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2128 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2129 ok(ret == 1, "GetDIBits failed\n");
2130 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2132 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2133 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2134 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2135 ok( !bitmasks[0], "red mask is set\n" );
2136 ok( !bitmasks[1], "green mask is set\n" );
2137 ok( !bitmasks[2], "blue mask is set\n" );
2139 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2140 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2141 ok(ret == 1, "GetDIBits failed\n");
2142 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2143 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2144 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2145 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2146 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2148 ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
2149 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2150 ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
2152 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2154 DeleteObject(hbm);
2156 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2157 dibinfo->bmiHeader.biWidth = 1;
2158 dibinfo->bmiHeader.biHeight = 1;
2159 dibinfo->bmiHeader.biPlanes = 1;
2160 dibinfo->bmiHeader.biBitCount = 32;
2161 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2162 dibinfo->bmiHeader.biSizeImage = 0;
2163 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2164 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2165 dibinfo->bmiHeader.biClrUsed = 0;
2166 dibinfo->bmiHeader.biClrImportant = 0;
2167 bitmasks[0] = 0x0000ff;
2168 bitmasks[1] = 0x00ff00;
2169 bitmasks[2] = 0xff0000;
2170 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2171 ok( hbm != 0, "failed to create bitmap\n" );
2173 if (hbm)
2175 memset(dibinfo, 0, sizeof(dibinfo_buf));
2176 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2177 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2178 ok(ret == 1, "GetDIBits failed\n");
2180 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
2181 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2182 ok( !bitmasks[0], "red mask is set\n" );
2183 ok( !bitmasks[1], "green mask is set\n" );
2184 ok( !bitmasks[2], "blue mask is set\n" );
2186 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2187 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2188 ok(ret == 1, "GetDIBits failed\n");
2189 ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
2190 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2191 ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
2192 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2194 DeleteObject(hbm);
2197 /* 24-bpp DIB sections don't have bitfields */
2199 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2200 dibinfo->bmiHeader.biWidth = 1;
2201 dibinfo->bmiHeader.biHeight = 1;
2202 dibinfo->bmiHeader.biPlanes = 1;
2203 dibinfo->bmiHeader.biBitCount = 24;
2204 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2205 dibinfo->bmiHeader.biSizeImage = 0;
2206 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2207 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2208 dibinfo->bmiHeader.biClrUsed = 0;
2209 dibinfo->bmiHeader.biClrImportant = 0;
2210 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2211 ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
2212 dibinfo->bmiHeader.biCompression = BI_RGB;
2213 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2214 ok( hbm != 0, "failed to create bitmap\n" );
2216 memset(dibinfo, 0, sizeof(dibinfo_buf));
2217 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2218 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2219 ok(ret == 1, "GetDIBits failed\n");
2220 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2222 ok( dibinfo->bmiHeader.biCompression == BI_RGB,
2223 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2224 ok( !bitmasks[0], "red mask is set\n" );
2225 ok( !bitmasks[1], "green mask is set\n" );
2226 ok( !bitmasks[2], "blue mask is set\n" );
2228 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2229 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2230 ok(ret == 1, "GetDIBits failed\n");
2231 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2232 ok( !bitmasks[0], "red mask is set\n" );
2233 ok( !bitmasks[1], "green mask is set\n" );
2234 ok( !bitmasks[2], "blue mask is set\n" );
2235 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2237 DeleteObject(hbm);
2238 ReleaseDC(NULL, hdc);
2241 static void test_select_object(void)
2243 HDC hdc;
2244 HBITMAP hbm, hbm_old;
2245 INT planes, bpp, i;
2246 DWORD depths[] = {8, 15, 16, 24, 32};
2247 BITMAP bm;
2248 DWORD bytes;
2250 hdc = GetDC(0);
2251 ok(hdc != 0, "GetDC(0) failed\n");
2252 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2253 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2255 hbm_old = SelectObject(hdc, hbm);
2256 ok(hbm_old == 0, "SelectObject should fail\n");
2258 DeleteObject(hbm);
2259 ReleaseDC(0, hdc);
2261 hdc = CreateCompatibleDC(0);
2262 ok(hdc != 0, "GetDC(0) failed\n");
2263 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2264 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2266 hbm_old = SelectObject(hdc, hbm);
2267 ok(hbm_old != 0, "SelectObject failed\n");
2268 hbm_old = SelectObject(hdc, hbm_old);
2269 ok(hbm_old == hbm, "SelectObject failed\n");
2271 DeleteObject(hbm);
2273 /* test an 1-bpp bitmap */
2274 planes = GetDeviceCaps(hdc, PLANES);
2275 bpp = 1;
2277 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
2278 ok(hbm != 0, "CreateBitmap failed\n");
2280 hbm_old = SelectObject(hdc, hbm);
2281 ok(hbm_old != 0, "SelectObject failed\n");
2282 hbm_old = SelectObject(hdc, hbm_old);
2283 ok(hbm_old == hbm, "SelectObject failed\n");
2285 DeleteObject(hbm);
2287 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
2288 /* test a color bitmap to dc bpp matching */
2289 planes = GetDeviceCaps(hdc, PLANES);
2290 bpp = GetDeviceCaps(hdc, BITSPIXEL);
2292 hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
2293 ok(hbm != 0, "CreateBitmap failed\n");
2295 hbm_old = SelectObject(hdc, hbm);
2296 if(depths[i] == bpp ||
2297 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
2299 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
2300 SelectObject(hdc, hbm_old);
2301 } else {
2302 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
2305 memset(&bm, 0xAA, sizeof(bm));
2306 bytes = GetObject(hbm, sizeof(bm), &bm);
2307 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2308 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2309 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
2310 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
2311 ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2312 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
2313 if(depths[i] == 15) {
2314 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
2315 } else {
2316 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2318 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2320 DeleteObject(hbm);
2323 DeleteDC(hdc);
2326 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
2328 INT ret;
2329 BITMAP bm;
2331 ret = GetObjectType(hbmp);
2332 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
2334 ret = GetObject(hbmp, 0, 0);
2335 ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
2337 memset(&bm, 0xDA, sizeof(bm));
2338 SetLastError(0xdeadbeef);
2339 ret = GetObject(hbmp, sizeof(bm), &bm);
2340 if (!ret) /* XP, only for curObj2 */ return;
2341 ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
2342 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2343 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2344 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2345 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2346 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2347 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2348 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2351 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2353 static void test_CreateBitmap(void)
2355 BITMAP bmp;
2356 HDC screenDC = GetDC(0);
2357 HDC hdc = CreateCompatibleDC(screenDC);
2358 UINT i, expect = 0;
2360 /* all of these are the stock monochrome bitmap */
2361 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2362 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2363 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2364 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2365 HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2366 HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2368 /* these 2 are not the stock monochrome bitmap */
2369 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2370 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2372 HBITMAP old1 = SelectObject(hdc, bm2);
2373 HBITMAP old2 = SelectObject(screenDC, bm3);
2374 SelectObject(hdc, old1);
2375 SelectObject(screenDC, old2);
2377 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2378 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2379 bm, bm1, bm4, bm5, curObj1, old1);
2380 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2381 todo_wine
2382 ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
2383 ok(old2 == 0, "old2 %p\n", old2);
2385 test_mono_1x1_bmp(bm);
2386 test_mono_1x1_bmp(bm1);
2387 test_mono_1x1_bmp(bm2);
2388 test_mono_1x1_bmp(bm3);
2389 test_mono_1x1_bmp(bm4);
2390 test_mono_1x1_bmp(bm5);
2391 test_mono_1x1_bmp(old1);
2392 test_mono_1x1_bmp(curObj1);
2394 DeleteObject(bm);
2395 DeleteObject(bm1);
2396 DeleteObject(bm2);
2397 DeleteObject(bm3);
2398 DeleteObject(bm4);
2399 DeleteObject(bm5);
2401 DeleteDC(hdc);
2402 ReleaseDC(0, screenDC);
2404 /* show that Windows ignores the provided bm.bmWidthBytes */
2405 bmp.bmType = 0;
2406 bmp.bmWidth = 1;
2407 bmp.bmHeight = 1;
2408 bmp.bmWidthBytes = 28;
2409 bmp.bmPlanes = 1;
2410 bmp.bmBitsPixel = 1;
2411 bmp.bmBits = NULL;
2412 bm = CreateBitmapIndirect(&bmp);
2413 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2414 test_mono_1x1_bmp(bm);
2415 DeleteObject(bm);
2417 /* Test how the bmBitsPixel field is treated */
2418 for(i = 1; i <= 33; i++) {
2419 bmp.bmType = 0;
2420 bmp.bmWidth = 1;
2421 bmp.bmHeight = 1;
2422 bmp.bmWidthBytes = 28;
2423 bmp.bmPlanes = 1;
2424 bmp.bmBitsPixel = i;
2425 bmp.bmBits = NULL;
2426 SetLastError(0xdeadbeef);
2427 bm = CreateBitmapIndirect(&bmp);
2428 if(i > 32) {
2429 DWORD error = GetLastError();
2430 ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
2431 ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2432 DeleteObject(bm);
2433 continue;
2435 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2436 GetObject(bm, sizeof(bmp), &bmp);
2437 if(i == 1) {
2438 expect = 1;
2439 } else if(i <= 4) {
2440 expect = 4;
2441 } else if(i <= 8) {
2442 expect = 8;
2443 } else if(i <= 16) {
2444 expect = 16;
2445 } else if(i <= 24) {
2446 expect = 24;
2447 } else if(i <= 32) {
2448 expect = 32;
2450 ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2451 i, bmp.bmBitsPixel, expect);
2452 DeleteObject(bm);
2456 static void test_bitmapinfoheadersize(void)
2458 HBITMAP hdib;
2459 BITMAPINFO bmi;
2460 BITMAPCOREINFO bci;
2461 HDC hdc = GetDC(0);
2463 memset(&bmi, 0, sizeof(BITMAPINFO));
2464 bmi.bmiHeader.biHeight = 100;
2465 bmi.bmiHeader.biWidth = 512;
2466 bmi.bmiHeader.biBitCount = 24;
2467 bmi.bmiHeader.biPlanes = 1;
2469 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2471 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2472 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2474 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2476 SetLastError(0xdeadbeef);
2477 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2478 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2479 DeleteObject(hdib);
2481 bmi.bmiHeader.biSize++;
2483 SetLastError(0xdeadbeef);
2484 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2485 ok(hdib != NULL ||
2486 broken(!hdib), /* Win98, WinMe */
2487 "CreateDIBSection error %d\n", GetLastError());
2488 DeleteObject(hdib);
2490 bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2492 SetLastError(0xdeadbeef);
2493 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2494 ok(hdib != NULL ||
2495 broken(!hdib), /* Win98, WinMe */
2496 "CreateDIBSection error %d\n", GetLastError());
2497 DeleteObject(hdib);
2499 bmi.bmiHeader.biSize++;
2501 SetLastError(0xdeadbeef);
2502 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2503 ok(hdib != NULL ||
2504 broken(!hdib), /* Win98, WinMe */
2505 "CreateDIBSection error %d\n", GetLastError());
2506 DeleteObject(hdib);
2508 bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2510 SetLastError(0xdeadbeef);
2511 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2512 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2513 DeleteObject(hdib);
2515 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2517 SetLastError(0xdeadbeef);
2518 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2519 ok(hdib != NULL ||
2520 broken(!hdib), /* Win95 */
2521 "CreateDIBSection error %d\n", GetLastError());
2522 DeleteObject(hdib);
2524 memset(&bci, 0, sizeof(BITMAPCOREINFO));
2525 bci.bmciHeader.bcHeight = 100;
2526 bci.bmciHeader.bcWidth = 512;
2527 bci.bmciHeader.bcBitCount = 24;
2528 bci.bmciHeader.bcPlanes = 1;
2530 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2532 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2533 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2535 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2537 SetLastError(0xdeadbeef);
2538 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2539 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2540 DeleteObject(hdib);
2542 bci.bmciHeader.bcSize++;
2544 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2545 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2547 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2549 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2550 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2552 ReleaseDC(0, hdc);
2555 static void test_get16dibits(void)
2557 BYTE bits[4 * (16 / sizeof(BYTE))];
2558 HBITMAP hbmp;
2559 HDC screen_dc = GetDC(NULL);
2560 int ret;
2561 BITMAPINFO * info;
2562 int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2563 BYTE *p;
2564 int overwritten_bytes = 0;
2566 memset(bits, 0, sizeof(bits));
2567 hbmp = CreateBitmap(2, 2, 1, 16, bits);
2568 ok(hbmp != NULL, "CreateBitmap failed\n");
2570 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2571 assert(info);
2573 memset(info, '!', info_len);
2574 memset(info, 0, sizeof(info->bmiHeader));
2576 info->bmiHeader.biSize = sizeof(info->bmiHeader);
2577 info->bmiHeader.biWidth = 2;
2578 info->bmiHeader.biHeight = 2;
2579 info->bmiHeader.biPlanes = 1;
2580 info->bmiHeader.biCompression = BI_RGB;
2582 ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2583 ok(ret != 0, "GetDIBits failed got %d\n", ret);
2585 for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2586 if (*p != '!')
2587 overwritten_bytes++;
2588 ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2590 HeapFree(GetProcessHeap(), 0, info);
2591 DeleteObject(hbmp);
2592 ReleaseDC(NULL, screen_dc);
2595 static BOOL compare_buffers_no_alpha(UINT32 *a, UINT32 *b, int length)
2597 int i;
2598 for(i = 0; i < length; i++)
2599 if((a[i] & 0x00FFFFFF) != (b[i] & 0x00FFFFFF))
2600 return FALSE;
2601 return TRUE;
2604 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2605 DWORD dwRop, UINT32 expected, int line)
2607 *srcBuffer = 0xFEDCBA98;
2608 *dstBuffer = 0x89ABCDEF;
2609 Rectangle(hdcSrc, 0, 0, 1, 1); /* A null operation to ensure dibs are coerced to X11 */
2610 BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
2611 ok(expected == *dstBuffer,
2612 "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2613 dwRop, expected, *dstBuffer, line);
2616 static void test_BitBlt(void)
2618 HBITMAP bmpDst, bmpSrc;
2619 HBITMAP oldDst, oldSrc;
2620 HDC hdcScreen, hdcDst, hdcSrc;
2621 UINT32 *dstBuffer, *srcBuffer;
2622 HBRUSH hBrush, hOldBrush;
2623 BITMAPINFO bitmapInfo;
2625 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2626 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2627 bitmapInfo.bmiHeader.biWidth = 1;
2628 bitmapInfo.bmiHeader.biHeight = 1;
2629 bitmapInfo.bmiHeader.biPlanes = 1;
2630 bitmapInfo.bmiHeader.biBitCount = 32;
2631 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2632 bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2634 hdcScreen = CreateCompatibleDC(0);
2635 hdcDst = CreateCompatibleDC(hdcScreen);
2636 hdcSrc = CreateCompatibleDC(hdcDst);
2638 /* Setup the destination dib section */
2639 bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
2640 NULL, 0);
2641 oldDst = SelectObject(hdcDst, bmpDst);
2643 hBrush = CreateSolidBrush(0x012345678);
2644 hOldBrush = SelectObject(hdcDst, hBrush);
2646 /* Setup the source dib section */
2647 bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
2648 NULL, 0);
2649 oldSrc = SelectObject(hdcSrc, bmpSrc);
2651 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2652 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2653 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2654 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2655 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2656 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2657 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2658 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2659 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2660 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2661 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2662 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2663 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2664 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2665 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2667 /* Tidy up */
2668 SelectObject(hdcSrc, oldSrc);
2669 DeleteObject(bmpSrc);
2670 DeleteDC(hdcSrc);
2672 SelectObject(hdcDst, hOldBrush);
2673 DeleteObject(hBrush);
2674 SelectObject(hdcDst, oldDst);
2675 DeleteObject(bmpDst);
2676 DeleteDC(hdcDst);
2679 DeleteDC(hdcScreen);
2682 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2683 DWORD dwRop, UINT32 expected, int line)
2685 *srcBuffer = 0xFEDCBA98;
2686 *dstBuffer = 0x89ABCDEF;
2687 StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
2688 ok(expected == *dstBuffer,
2689 "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2690 dwRop, expected, *dstBuffer, line);
2693 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2694 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2695 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2696 UINT32 expected[4], UINT32 legacy_expected[4], int line)
2698 memset(dstBuffer, 0, 16);
2699 StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2700 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
2701 ok(memcmp(dstBuffer, expected, 16) == 0 ||
2702 broken(compare_buffers_no_alpha(dstBuffer, legacy_expected, 4)),
2703 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2704 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2705 expected[0], expected[1], expected[2], expected[3],
2706 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2707 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2708 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2711 static void test_StretchBlt(void)
2713 HBITMAP bmpDst, bmpSrc;
2714 HBITMAP oldDst, oldSrc;
2715 HDC hdcScreen, hdcDst, hdcSrc;
2716 UINT32 *dstBuffer, *srcBuffer;
2717 HBRUSH hBrush, hOldBrush;
2718 BITMAPINFO biDst, biSrc;
2719 UINT32 expected[4], legacy_expected[4];
2721 memset(&biDst, 0, sizeof(BITMAPINFO));
2722 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2723 biDst.bmiHeader.biWidth = 2;
2724 biDst.bmiHeader.biHeight = -2;
2725 biDst.bmiHeader.biPlanes = 1;
2726 biDst.bmiHeader.biBitCount = 32;
2727 biDst.bmiHeader.biCompression = BI_RGB;
2728 memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
2730 hdcScreen = CreateCompatibleDC(0);
2731 hdcDst = CreateCompatibleDC(hdcScreen);
2732 hdcSrc = CreateCompatibleDC(hdcDst);
2734 /* Pixel Tests */
2735 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2736 NULL, 0);
2737 oldDst = SelectObject(hdcDst, bmpDst);
2739 bmpSrc = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&srcBuffer,
2740 NULL, 0);
2741 oldSrc = SelectObject(hdcSrc, bmpSrc);
2743 hBrush = CreateSolidBrush(0x012345678);
2744 hOldBrush = SelectObject(hdcDst, hBrush);
2746 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2747 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2748 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2749 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2750 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2751 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2752 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2753 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2754 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2755 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2756 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2757 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2758 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2759 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2760 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2762 SelectObject(hdcDst, hOldBrush);
2763 DeleteObject(hBrush);
2765 /* Top-down to top-down tests */
2766 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2767 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
2769 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2770 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2771 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2772 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2774 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2775 expected[2] = 0x00000000, expected[3] = 0x00000000;
2776 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2777 0, 0, 1, 1, 0, 0, 1, 1, expected, expected, __LINE__);
2779 expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
2780 expected[2] = 0xCAFED00D, expected[3] = 0xCAFED00D;
2781 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2782 0, 0, 2, 2, 0, 0, 1, 1, expected, expected, __LINE__);
2784 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2785 expected[2] = 0x00000000, expected[3] = 0x00000000;
2786 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2787 0, 0, 1, 1, 0, 0, 2, 2, expected, expected, __LINE__);
2789 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2790 expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2791 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2792 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2794 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2795 expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2796 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2797 1, 1, -2, -2, 0, 0, 2, 2, expected, expected, __LINE__);
2799 /* This result seems broken. One might expect the following result:
2800 * 0xCAFED00D 0xFEEDFACE
2801 * 0xFEDCBA98 0x76543210
2803 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2804 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2805 legacy_expected[0] = 0xCAFED00D, legacy_expected[1] = 0x00000000;
2806 legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
2807 todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2808 1, 1, -2, -2, 1, 1, -2, -2, expected,
2809 legacy_expected, __LINE__);
2811 expected[0] = 0x00000000, expected[1] = 0x00000000;
2812 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
2813 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2814 1, 1, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2816 SelectObject(hdcDst, oldDst);
2817 DeleteObject(bmpDst);
2819 /* Top-down to bottom-up tests */
2820 biDst.bmiHeader.biHeight = 2;
2821 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2822 NULL, 0);
2823 oldDst = SelectObject(hdcDst, bmpDst);
2825 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2826 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
2827 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2828 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2830 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2831 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2832 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2833 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2835 SelectObject(hdcSrc, oldSrc);
2836 DeleteObject(bmpSrc);
2838 /* Bottom-up to bottom-up tests */
2839 biSrc.bmiHeader.biHeight = 2;
2840 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2841 NULL, 0);
2842 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2843 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
2844 oldSrc = SelectObject(hdcSrc, bmpSrc);
2846 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2847 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2848 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2849 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2851 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2852 expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2853 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2854 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2856 SelectObject(hdcDst, oldDst);
2857 DeleteObject(bmpDst);
2859 /* Bottom-up to top-down tests */
2860 biDst.bmiHeader.biHeight = -2;
2861 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2862 NULL, 0);
2863 oldDst = SelectObject(hdcDst, bmpDst);
2865 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2866 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
2867 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2868 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2870 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2871 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2872 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2873 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2875 /* Tidy up */
2876 SelectObject(hdcSrc, oldSrc);
2877 DeleteObject(bmpSrc);
2878 DeleteDC(hdcSrc);
2880 SelectObject(hdcDst, oldDst);
2881 DeleteObject(bmpDst);
2882 DeleteDC(hdcDst);
2884 DeleteDC(hdcScreen);
2887 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
2888 DWORD dwRop, UINT32 expected, int line)
2890 const UINT32 buffer[2] = { 0xFEDCBA98, 0 };
2891 BITMAPINFO bitmapInfo;
2893 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2894 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2895 bitmapInfo.bmiHeader.biWidth = 2;
2896 bitmapInfo.bmiHeader.biHeight = 1;
2897 bitmapInfo.bmiHeader.biPlanes = 1;
2898 bitmapInfo.bmiHeader.biBitCount = 32;
2899 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2900 bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer);
2902 *dstBuffer = 0x89ABCDEF;
2904 StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop);
2905 ok(expected == *dstBuffer,
2906 "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2907 dwRop, expected, *dstBuffer, line);
2910 static void check_StretchDIBits_stretch(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
2911 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2912 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2913 UINT32 expected[4], UINT32 legacy_expected[4], int line)
2915 BITMAPINFO bitmapInfo;
2917 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2918 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2919 bitmapInfo.bmiHeader.biWidth = 2;
2920 bitmapInfo.bmiHeader.biHeight = -2;
2921 bitmapInfo.bmiHeader.biPlanes = 1;
2922 bitmapInfo.bmiHeader.biBitCount = 32;
2923 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2925 memset(dstBuffer, 0, 16);
2926 StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2927 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2928 srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
2929 ok(memcmp(dstBuffer, expected, 16) == 0,
2930 "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2931 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2932 expected[0], expected[1], expected[2], expected[3],
2933 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2934 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2935 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2938 static void test_StretchDIBits(void)
2940 HBITMAP bmpDst;
2941 HBITMAP oldDst;
2942 HDC hdcScreen, hdcDst;
2943 UINT32 *dstBuffer, srcBuffer[4];
2944 HBRUSH hBrush, hOldBrush;
2945 BITMAPINFO biDst;
2946 UINT32 expected[4], legacy_expected[4];
2948 memset(&biDst, 0, sizeof(BITMAPINFO));
2949 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2950 biDst.bmiHeader.biWidth = 2;
2951 biDst.bmiHeader.biHeight = -2;
2952 biDst.bmiHeader.biPlanes = 1;
2953 biDst.bmiHeader.biBitCount = 32;
2954 biDst.bmiHeader.biCompression = BI_RGB;
2956 hdcScreen = CreateCompatibleDC(0);
2957 hdcDst = CreateCompatibleDC(hdcScreen);
2959 /* Pixel Tests */
2960 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2961 NULL, 0);
2962 oldDst = SelectObject(hdcDst, bmpDst);
2964 hBrush = CreateSolidBrush(0x012345678);
2965 hOldBrush = SelectObject(hdcDst, hBrush);
2967 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2968 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2969 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2970 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2971 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2972 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2973 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2974 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2975 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2976 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2977 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2978 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2979 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2980 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2981 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2983 SelectObject(hdcDst, hOldBrush);
2984 DeleteObject(hBrush);
2986 /* Top-down destination tests */
2987 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2988 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
2990 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2991 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2992 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2993 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2995 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2996 expected[2] = 0x00000000, expected[3] = 0x00000000;
2997 legacy_expected[0] = 0xFEDCBA98, legacy_expected[1] = 0x00000000;
2998 legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
2999 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3000 0, 0, 1, 1, 0, 0, 1, 1, expected, legacy_expected, __LINE__);
3002 expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
3003 expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
3004 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3005 0, 0, 2, 2, 0, 0, 1, 1, expected, expected, __LINE__);
3007 expected[0] = 0x42441000, expected[1] = 0x00000000;
3008 expected[2] = 0x00000000, expected[3] = 0x00000000;
3009 legacy_expected[0] = 0x00543210, legacy_expected[1] = 0x00000000;
3010 legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
3011 todo_wine check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3012 0, 0, 1, 1, 0, 0, 2, 2, expected, legacy_expected, __LINE__);
3014 expected[0] = 0x00000000, expected[1] = 0x00000000;
3015 expected[2] = 0x00000000, expected[3] = 0x00000000;
3016 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3017 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
3019 expected[0] = 0x00000000, expected[1] = 0x00000000;
3020 expected[2] = 0x00000000, expected[3] = 0x00000000;
3021 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3022 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
3024 expected[0] = 0x00000000, expected[1] = 0x00000000;
3025 expected[2] = 0x00000000, expected[3] = 0x00000000;
3026 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3027 1, 1, -2, -2, 1, 1, -2, -2, expected, expected, __LINE__);
3029 expected[0] = 0x00000000, expected[1] = 0x00000000;
3030 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
3031 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3032 1, 1, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
3034 SelectObject(hdcDst, oldDst);
3035 DeleteObject(bmpDst);
3037 /* Bottom up destination tests */
3038 biDst.bmiHeader.biHeight = 2;
3039 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3040 NULL, 0);
3041 oldDst = SelectObject(hdcDst, bmpDst);
3043 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3044 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
3045 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3046 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
3048 /* Tidy up */
3049 SelectObject(hdcDst, oldDst);
3050 DeleteObject(bmpDst);
3051 DeleteDC(hdcDst);
3053 DeleteDC(hdcScreen);
3056 static void test_GdiAlphaBlend(void)
3058 /* test out-of-bound parameters for GdiAlphaBlend */
3059 HDC hdcNull;
3061 HDC hdcDst;
3062 HBITMAP bmpDst;
3063 HBITMAP oldDst;
3065 BITMAPINFO bmi;
3066 HDC hdcSrc;
3067 HBITMAP bmpSrc;
3068 HBITMAP oldSrc;
3069 LPVOID bits;
3071 BLENDFUNCTION blend;
3073 if (!pGdiAlphaBlend)
3075 win_skip("GdiAlphaBlend() is not implemented\n");
3076 return;
3079 hdcNull = GetDC(NULL);
3080 hdcDst = CreateCompatibleDC(hdcNull);
3081 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
3082 hdcSrc = CreateCompatibleDC(hdcNull);
3084 memset(&bmi, 0, sizeof(bmi)); /* as of Wine 0.9.44 we require the src to be a DIB section */
3085 bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
3086 bmi.bmiHeader.biHeight = 20;
3087 bmi.bmiHeader.biWidth = 20;
3088 bmi.bmiHeader.biBitCount = 32;
3089 bmi.bmiHeader.biPlanes = 1;
3090 bmi.bmiHeader.biCompression = BI_RGB;
3091 bmpSrc = CreateDIBSection(hdcDst, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3092 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3094 oldDst = SelectObject(hdcDst, bmpDst);
3095 oldSrc = SelectObject(hdcSrc, bmpSrc);
3097 blend.BlendOp = AC_SRC_OVER;
3098 blend.BlendFlags = 0;
3099 blend.SourceConstantAlpha = 128;
3100 blend.AlphaFormat = 0;
3102 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend), TRUE, BOOL, "%d");
3103 SetLastError(0xdeadbeef);
3104 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), FALSE, BOOL, "%d");
3105 expect_eq(GetLastError(), ERROR_INVALID_PARAMETER, int, "%d");
3106 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), FALSE, BOOL, "%d");
3107 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend), FALSE, BOOL, "%d");
3108 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
3109 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
3111 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
3112 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), TRUE, BOOL, "%d");
3113 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), TRUE, BOOL, "%d");
3114 SetMapMode(hdcSrc, MM_ANISOTROPIC);
3115 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
3116 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend), TRUE, BOOL, "%d");
3117 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend), TRUE, BOOL, "%d");
3119 SetLastError(0xdeadbeef);
3120 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend), FALSE, BOOL, "%d");
3121 expect_eq(GetLastError(), 0xdeadbeef, int, "%d");
3123 SelectObject(hdcDst, oldDst);
3124 SelectObject(hdcSrc, oldSrc);
3125 DeleteObject(bmpSrc);
3126 DeleteObject(bmpDst);
3127 DeleteDC(hdcDst);
3128 DeleteDC(hdcSrc);
3130 ReleaseDC(NULL, hdcNull);
3134 static void test_clipping(void)
3136 HBITMAP bmpDst;
3137 HBITMAP bmpSrc;
3138 HRGN hRgn;
3139 LPVOID bits;
3140 BOOL result;
3142 HDC hdcDst = CreateCompatibleDC( NULL );
3143 HDC hdcSrc = CreateCompatibleDC( NULL );
3145 BITMAPINFO bmpinfo={{0}};
3146 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3147 bmpinfo.bmiHeader.biWidth = 100;
3148 bmpinfo.bmiHeader.biHeight = 100;
3149 bmpinfo.bmiHeader.biPlanes = 1;
3150 bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3151 bmpinfo.bmiHeader.biCompression = BI_RGB;
3153 bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3154 ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3155 SelectObject( hdcDst, bmpDst );
3157 bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3158 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3159 SelectObject( hdcSrc, bmpSrc );
3161 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3162 ok(result, "BitBlt failed\n");
3164 hRgn = CreateRectRgn( 0,0,0,0 );
3165 SelectClipRgn( hdcDst, hRgn );
3167 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3168 ok(result, "BitBlt failed\n");
3170 DeleteObject( bmpDst );
3171 DeleteObject( bmpSrc );
3172 DeleteObject( hRgn );
3173 DeleteDC( hdcDst );
3174 DeleteDC( hdcSrc );
3177 static void test_32bit_bitmap_blt(void)
3179 BITMAPINFO biDst;
3180 HBITMAP bmpSrc, bmpDst;
3181 HBITMAP oldSrc, oldDst;
3182 HDC hdcSrc, hdcDst, hdcScreen;
3183 UINT32 *dstBuffer;
3184 DWORD colorSrc = 0x11223344;
3186 memset(&biDst, 0, sizeof(BITMAPINFO));
3187 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3188 biDst.bmiHeader.biWidth = 2;
3189 biDst.bmiHeader.biHeight = -2;
3190 biDst.bmiHeader.biPlanes = 1;
3191 biDst.bmiHeader.biBitCount = 32;
3192 biDst.bmiHeader.biCompression = BI_RGB;
3194 hdcScreen = CreateCompatibleDC(0);
3195 if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3197 DeleteDC(hdcScreen);
3198 trace("Skipping 32-bit DDB test\n");
3199 return;
3202 hdcSrc = CreateCompatibleDC(hdcScreen);
3203 bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3204 oldSrc = SelectObject(hdcSrc, bmpSrc);
3206 hdcDst = CreateCompatibleDC(hdcScreen);
3207 bmpDst = CreateDIBSection(hdcDst, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3208 oldDst = SelectObject(hdcDst, bmpDst);
3210 StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3211 ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3213 /* Tidy up */
3214 SelectObject(hdcDst, oldDst);
3215 DeleteObject(bmpDst);
3216 DeleteDC(hdcDst);
3218 SelectObject(hdcSrc, oldSrc);
3219 DeleteObject(bmpSrc);
3220 DeleteDC(hdcSrc);
3222 DeleteDC(hdcScreen);
3226 * Used by test_GetDIBits_top_down to create the bitmap to test against.
3228 static void setup_picture(char *picture, int bpp)
3230 int i;
3232 switch(bpp)
3234 case 16:
3235 case 32:
3236 /*Set the first byte in each pixel to the index of that pixel.*/
3237 for (i = 0; i < 4; i++)
3238 picture[i * (bpp / 8)] = i;
3239 break;
3240 case 24:
3241 picture[0] = 0;
3242 picture[3] = 1;
3243 /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
3244 picture[8] = 2;
3245 picture[11] = 3;
3246 break;
3250 static void test_GetDIBits_top_down(int bpp)
3252 BITMAPINFO bi;
3253 HBITMAP bmptb, bmpbt;
3254 HDC hdc;
3255 int pictureOut[4];
3256 int *picture;
3257 int statusCode;
3259 bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
3260 bi.bmiHeader.biWidth=2;
3261 bi.bmiHeader.biHeight=2;
3262 bi.bmiHeader.biPlanes=1;
3263 bi.bmiHeader.biBitCount=bpp;
3264 bi.bmiHeader.biCompression=BI_RGB;
3266 /*Get the device context for the screen.*/
3267 hdc = GetDC(NULL);
3268 ok(hdc != NULL, "Could not get a handle to a device context.\n");
3270 /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
3271 bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3272 ok(bmpbt != NULL, "Could not create a DIB section.\n");
3273 /*Now that we have a pointer to the pixels, we write to them.*/
3274 setup_picture((char*)picture, bpp);
3275 /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
3276 bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
3277 bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3278 ok(bmptb != NULL, "Could not create a DIB section.\n");
3279 /*Write to this top to bottom bitmap.*/
3280 setup_picture((char*)picture, bpp);
3282 bi.bmiHeader.biWidth = 1;
3284 bi.bmiHeader.biHeight = 2;
3285 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3286 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3287 /*Check the first byte of the pixel.*/
3288 ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3289 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3290 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3291 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3292 /*Check second scanline.*/
3293 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3294 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3295 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3296 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3297 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3298 ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3299 /*Check both scanlines.*/
3300 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3301 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3302 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3303 ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3304 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3305 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3306 ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3307 ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3309 /*Make destination bitmap top-down.*/
3310 bi.bmiHeader.biHeight = -2;
3311 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3312 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3313 ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3314 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3315 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3316 ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3317 /*Check second scanline.*/
3318 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3319 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3320 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3321 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3322 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3323 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3324 /*Check both scanlines.*/
3325 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3326 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3327 ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3328 ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3329 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3330 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3331 ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3332 ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3334 DeleteObject(bmpbt);
3335 DeleteObject(bmptb);
3338 static void test_GetSetDIBits_rtl(void)
3340 HDC hdc, hdc_mem;
3341 HBITMAP bitmap, orig_bitmap;
3342 BITMAPINFO info;
3343 int ret;
3344 DWORD bits_1[8 * 8], bits_2[8 * 8];
3346 if(!pSetLayout)
3348 win_skip("Don't have SetLayout\n");
3349 return;
3352 hdc = GetDC( NULL );
3353 hdc_mem = CreateCompatibleDC( hdc );
3354 pSetLayout( hdc_mem, LAYOUT_LTR );
3356 bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
3357 orig_bitmap = SelectObject( hdc_mem, bitmap );
3358 SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
3359 SelectObject( hdc_mem, orig_bitmap );
3361 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3362 info.bmiHeader.biWidth = 8;
3363 info.bmiHeader.biHeight = 8;
3364 info.bmiHeader.biPlanes = 1;
3365 info.bmiHeader.biBitCount = 32;
3366 info.bmiHeader.biCompression = BI_RGB;
3368 /* First show that GetDIBits ignores the layout mode. */
3370 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3371 ok(ret == 8, "got %d\n", ret);
3372 ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
3374 pSetLayout( hdc_mem, LAYOUT_RTL );
3376 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3377 ok(ret == 8, "got %d\n", ret);
3379 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3381 /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
3382 followed by a GetDIBits and show that the bits remain unchanged. */
3384 pSetLayout( hdc_mem, LAYOUT_LTR );
3386 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3387 ok(ret == 8, "got %d\n", ret);
3388 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3389 ok(ret == 8, "got %d\n", ret);
3390 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3392 pSetLayout( hdc_mem, LAYOUT_RTL );
3394 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3395 ok(ret == 8, "got %d\n", ret);
3396 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3397 ok(ret == 8, "got %d\n", ret);
3398 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3400 DeleteObject( bitmap );
3401 DeleteDC( hdc_mem );
3402 ReleaseDC( NULL, hdc );
3405 static void test_GetDIBits_scanlines(void)
3407 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3408 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3409 DWORD *dib_bits;
3410 HDC hdc = GetDC( NULL );
3411 HBITMAP dib;
3412 DWORD data[128], inverted_bits[64];
3413 int i, ret;
3415 memset( info, 0, sizeof(bmi_buf) );
3417 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3418 info->bmiHeader.biWidth = 8;
3419 info->bmiHeader.biHeight = 8;
3420 info->bmiHeader.biPlanes = 1;
3421 info->bmiHeader.biBitCount = 32;
3422 info->bmiHeader.biCompression = BI_RGB;
3424 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3426 for (i = 0; i < 64; i++)
3428 dib_bits[i] = i;
3429 inverted_bits[56 - (i & ~7) + (i & 7)] = i;
3432 /* b-u -> b-u */
3434 memset( data, 0xaa, sizeof(data) );
3436 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3437 ok( ret == 8, "got %d\n", ret );
3438 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3439 memset( data, 0xaa, sizeof(data) );
3441 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3442 ok( ret == 5, "got %d\n", ret );
3443 ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
3444 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3445 memset( data, 0xaa, sizeof(data) );
3447 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3448 ok( ret == 7, "got %d\n", ret );
3449 ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
3450 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3451 memset( data, 0xaa, sizeof(data) );
3453 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3454 ok( ret == 1, "got %d\n", ret );
3455 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3456 memset( data, 0xaa, sizeof(data) );
3458 info->bmiHeader.biHeight = 16;
3459 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3460 ok( ret == 5, "got %d\n", ret );
3461 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3462 ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
3463 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3464 memset( data, 0xaa, sizeof(data) );
3466 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3467 ok( ret == 6, "got %d\n", ret );
3468 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3469 ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
3470 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3471 memset( data, 0xaa, sizeof(data) );
3473 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3474 ok( ret == 0, "got %d\n", ret );
3475 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3476 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3477 memset( data, 0xaa, sizeof(data) );
3479 info->bmiHeader.biHeight = 5;
3480 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3481 ok( ret == 2, "got %d\n", ret );
3482 ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
3483 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3484 memset( data, 0xaa, sizeof(data) );
3486 /* b-u -> t-d */
3488 info->bmiHeader.biHeight = -8;
3489 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3490 ok( ret == 8, "got %d\n", ret );
3491 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3492 memset( data, 0xaa, sizeof(data) );
3494 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3495 ok( ret == 5, "got %d\n", ret );
3496 ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
3497 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3498 memset( data, 0xaa, sizeof(data) );
3500 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3501 ok( ret == 7, "got %d\n", ret );
3502 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3503 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3504 memset( data, 0xaa, sizeof(data) );
3506 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3507 ok( ret == 4, "got %d\n", ret );
3508 ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
3509 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3510 memset( data, 0xaa, sizeof(data) );
3512 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3513 ok( ret == 5, "got %d\n", ret );
3514 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3515 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3516 memset( data, 0xaa, sizeof(data) );
3518 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3519 ok( ret == 5, "got %d\n", ret );
3520 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3521 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3522 memset( data, 0xaa, sizeof(data) );
3524 info->bmiHeader.biHeight = -16;
3525 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3526 ok( ret == 8, "got %d\n", ret );
3527 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3528 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3529 memset( data, 0xaa, sizeof(data) );
3531 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3532 ok( ret == 5, "got %d\n", ret );
3533 ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
3534 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3535 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3536 memset( data, 0xaa, sizeof(data) );
3538 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3539 ok( ret == 8, "got %d\n", ret );
3540 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3541 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3542 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3543 memset( data, 0xaa, sizeof(data) );
3545 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3546 ok( ret == 8, "got %d\n", ret );
3547 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3548 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3549 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3550 memset( data, 0xaa, sizeof(data) );
3552 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3553 ok( ret == 7, "got %d\n", ret );
3554 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3555 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3556 memset( data, 0xaa, sizeof(data) );
3558 ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
3559 ok( ret == 1, "got %d\n", ret );
3560 for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3561 memset( data, 0xaa, sizeof(data) );
3563 info->bmiHeader.biHeight = -5;
3564 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3565 ok( ret == 2, "got %d\n", ret );
3566 ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
3567 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3568 memset( data, 0xaa, sizeof(data) );
3570 DeleteObject( dib );
3572 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3573 info->bmiHeader.biWidth = 8;
3574 info->bmiHeader.biHeight = -8;
3575 info->bmiHeader.biPlanes = 1;
3576 info->bmiHeader.biBitCount = 32;
3577 info->bmiHeader.biCompression = BI_RGB;
3579 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3581 for (i = 0; i < 64; i++) dib_bits[i] = i;
3583 /* t-d -> t-d */
3585 info->bmiHeader.biHeight = -8;
3586 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3587 ok( ret == 8, "got %d\n", ret );
3588 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3589 memset( data, 0xaa, sizeof(data) );
3591 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3592 ok( ret == 5, "got %d\n", ret );
3593 ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
3594 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3595 memset( data, 0xaa, sizeof(data) );
3597 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3598 ok( ret == 7, "got %d\n", ret );
3599 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3600 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3601 memset( data, 0xaa, sizeof(data) );
3603 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3604 ok( ret == 4, "got %d\n", ret );
3605 ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
3606 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3607 memset( data, 0xaa, sizeof(data) );
3609 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3610 ok( ret == 5, "got %d\n", ret );
3611 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3612 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3613 memset( data, 0xaa, sizeof(data) );
3615 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3616 ok( ret == 5, "got %d\n", ret );
3617 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3618 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3619 memset( data, 0xaa, sizeof(data) );
3621 info->bmiHeader.biHeight = -16;
3622 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3623 ok( ret == 8, "got %d\n", ret );
3624 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3625 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3626 memset( data, 0xaa, sizeof(data) );
3628 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3629 ok( ret == 5, "got %d\n", ret );
3630 ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
3631 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3632 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3633 memset( data, 0xaa, sizeof(data) );
3635 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3636 ok( ret == 8, "got %d\n", ret );
3637 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3638 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3639 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3640 memset( data, 0xaa, sizeof(data) );
3642 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3643 ok( ret == 8, "got %d\n", ret );
3644 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3645 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3646 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3647 memset( data, 0xaa, sizeof(data) );
3649 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3650 ok( ret == 7, "got %d\n", ret );
3651 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3652 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3653 memset( data, 0xaa, sizeof(data) );
3655 info->bmiHeader.biHeight = -5;
3656 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3657 ok( ret == 2, "got %d\n", ret );
3658 ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
3659 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3660 memset( data, 0xaa, sizeof(data) );
3663 /* t-d -> b-u */
3665 info->bmiHeader.biHeight = 8;
3667 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3668 ok( ret == 8, "got %d\n", ret );
3669 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3670 memset( data, 0xaa, sizeof(data) );
3672 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3673 ok( ret == 5, "got %d\n", ret );
3674 ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
3675 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3676 memset( data, 0xaa, sizeof(data) );
3678 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3679 ok( ret == 7, "got %d\n", ret );
3680 ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
3681 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3682 memset( data, 0xaa, sizeof(data) );
3684 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3685 ok( ret == 1, "got %d\n", ret );
3686 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3687 memset( data, 0xaa, sizeof(data) );
3689 info->bmiHeader.biHeight = 16;
3690 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3691 ok( ret == 5, "got %d\n", ret );
3692 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3693 ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
3694 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3695 memset( data, 0xaa, sizeof(data) );
3697 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3698 ok( ret == 6, "got %d\n", ret );
3699 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3700 ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
3701 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3702 memset( data, 0xaa, sizeof(data) );
3704 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3705 ok( ret == 0, "got %d\n", ret );
3706 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3707 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3708 memset( data, 0xaa, sizeof(data) );
3710 info->bmiHeader.biHeight = 5;
3711 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3712 ok( ret == 2, "got %d\n", ret );
3713 ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
3714 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3715 memset( data, 0xaa, sizeof(data) );
3717 DeleteObject( dib );
3719 ReleaseDC( NULL, hdc );
3723 static void test_SetDIBits(void)
3725 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3726 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3727 DWORD *dib_bits;
3728 HDC hdc = GetDC( NULL );
3729 DWORD data[128], inverted_data[128];
3730 HBITMAP dib;
3731 int i, ret;
3733 memset( info, 0, sizeof(bmi_buf) );
3735 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3736 info->bmiHeader.biWidth = 8;
3737 info->bmiHeader.biHeight = 8;
3738 info->bmiHeader.biPlanes = 1;
3739 info->bmiHeader.biBitCount = 32;
3740 info->bmiHeader.biCompression = BI_RGB;
3742 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3743 memset( dib_bits, 0xaa, 64 * 4 );
3745 for (i = 0; i < 128; i++)
3747 data[i] = i;
3748 inverted_data[120 - (i & ~7) + (i & 7)] = i;
3751 /* b-u -> b-u */
3753 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3754 ok( ret == 8, "got %d\n", ret );
3755 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
3756 memset( dib_bits, 0xaa, 64 * 4 );
3758 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3759 ok( ret == 5, "got %d\n", ret );
3760 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3761 ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
3762 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3763 memset( dib_bits, 0xaa, 64 * 4 );
3765 /* top of dst is aligned with startscans down for the top of the src.
3766 Then starting from the bottom of src, lines rows are copied across. */
3768 info->bmiHeader.biHeight = 16;
3769 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3770 ok( ret == 12, "got %d\n", ret );
3771 ok( !memcmp( dib_bits, data + 56, 40 * 4 ), "bits differ\n");
3772 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3773 memset( dib_bits, 0xaa, 64 * 4 );
3775 info->bmiHeader.biHeight = 5;
3776 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3777 ok( ret == 2, "got %d\n", ret );
3778 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3779 ok( !memcmp( dib_bits + 32, data, 16 * 4 ), "bits differ\n");
3780 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3781 memset( dib_bits, 0xaa, 64 * 4 );
3783 /* t-d -> b-u */
3784 info->bmiHeader.biHeight = -8;
3785 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3786 ok( ret == 8, "got %d\n", ret );
3787 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3788 memset( dib_bits, 0xaa, 64 * 4 );
3790 /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
3791 we copy lines rows from the top of the src */
3793 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3794 ok( ret == 5, "got %d\n", ret );
3795 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3796 ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
3797 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3798 memset( dib_bits, 0xaa, 64 * 4 );
3800 info->bmiHeader.biHeight = -16;
3801 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3802 ok( ret == 12, "got %d\n", ret );
3803 ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
3804 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3805 memset( dib_bits, 0xaa, 64 * 4 );
3807 ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3808 ok( ret == 12, "got %d\n", ret );
3809 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3810 memset( dib_bits, 0xaa, 64 * 4 );
3812 ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3813 ok( ret == 12, "got %d\n", ret );
3814 ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
3815 memset( dib_bits, 0xaa, 64 * 4 );
3817 info->bmiHeader.biHeight = -5;
3818 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3819 ok( ret == 2, "got %d\n", ret );
3820 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3821 ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
3822 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3823 memset( dib_bits, 0xaa, 64 * 4 );
3825 DeleteObject( dib );
3827 info->bmiHeader.biHeight = -8;
3829 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3830 memset( dib_bits, 0xaa, 16 * 16 * 4 );
3832 /* t-d -> t-d */
3834 /* like the t-d -> b-u case. */
3836 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3837 ok( ret == 8, "got %d\n", ret );
3838 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
3839 memset( dib_bits, 0xaa, 64 * 4 );
3841 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3842 ok( ret == 5, "got %d\n", ret );
3843 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3844 ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
3845 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3846 memset( dib_bits, 0xaa, 64 * 4 );
3848 info->bmiHeader.biHeight = -16;
3849 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3850 ok( ret == 12, "got %d\n", ret );
3851 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3852 ok( !memcmp( dib_bits + 24, data, 40 * 4 ), "bits differ\n");
3853 memset( dib_bits, 0xaa, 64 * 4 );
3855 info->bmiHeader.biHeight = -5;
3856 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3857 ok( ret == 2, "got %d\n", ret );
3858 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3859 ok( !memcmp( dib_bits + 16, data, 16 * 4 ), "bits differ\n");
3860 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3861 memset( dib_bits, 0xaa, 64 * 4 );
3863 /* b-u -> t-d */
3864 /* like the b-u -> b-u case */
3866 info->bmiHeader.biHeight = 8;
3867 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3868 ok( ret == 8, "got %d\n", ret );
3869 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3870 memset( dib_bits, 0xaa, 64 * 4 );
3872 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3873 ok( ret == 5, "got %d\n", ret );
3874 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3875 ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
3876 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3877 memset( dib_bits, 0xaa, 64 * 4 );
3879 info->bmiHeader.biHeight = 16;
3880 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3881 ok( ret == 12, "got %d\n", ret );
3882 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3883 ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
3884 memset( dib_bits, 0xaa, 64 * 4 );
3886 info->bmiHeader.biHeight = 5;
3887 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3888 ok( ret == 2, "got %d\n", ret );
3889 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3890 ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
3891 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3892 memset( dib_bits, 0xaa, 64 * 4 );
3894 DeleteObject( dib );
3895 ReleaseDC( NULL, hdc );
3898 static void test_SetDIBits_RLE4(void)
3900 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3901 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3902 DWORD *dib_bits;
3903 HDC hdc = GetDC( NULL );
3904 BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00, /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
3905 0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
3906 0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00, /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
3907 0x00, 0x02, 0x01, 0x02, 0x05, 0x87, /* dx=1, dy=2, 8, 7, 8, 7, 8 */
3908 0x00, 0x01 }; /* <eod> */
3909 HBITMAP dib;
3910 int i, ret;
3911 DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
3912 0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
3913 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3914 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3915 0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
3916 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3917 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3918 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
3920 memset( info, 0, sizeof(bmi_buf) );
3922 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3923 info->bmiHeader.biWidth = 8;
3924 info->bmiHeader.biHeight = 8;
3925 info->bmiHeader.biPlanes = 1;
3926 info->bmiHeader.biBitCount = 32;
3927 info->bmiHeader.biCompression = BI_RGB;
3929 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3930 memset( dib_bits, 0xaa, 64 * 4 );
3932 info->bmiHeader.biBitCount = 4;
3933 info->bmiHeader.biCompression = BI_RLE4;
3934 info->bmiHeader.biSizeImage = sizeof(rle4_data);
3936 for (i = 0; i < 16; i++)
3938 info->bmiColors[i].rgbRed = i;
3939 info->bmiColors[i].rgbGreen = i;
3940 info->bmiColors[i].rgbBlue = i;
3941 info->bmiColors[i].rgbReserved = 0;
3944 ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
3945 ok( ret == 8, "got %d\n", ret );
3946 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
3947 memset( dib_bits, 0xaa, 64 * 4 );
3949 DeleteObject( dib );
3950 ReleaseDC( NULL, hdc );
3953 static void test_SetDIBits_RLE8(void)
3955 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3956 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3957 DWORD *dib_bits;
3958 HDC hdc = GetDC( NULL );
3959 BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00, /* 2, 2, 2, f0, f0, f0, f0, <eol> */
3960 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
3961 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
3962 0x00, 0x01 }; /* <eod> */
3963 HBITMAP dib;
3964 int i, ret;
3965 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
3966 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3967 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3968 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
3969 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3970 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3971 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3972 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
3973 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3974 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3975 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3976 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3977 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
3978 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3979 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3980 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
3982 memset( info, 0, sizeof(bmi_buf) );
3984 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3985 info->bmiHeader.biWidth = 8;
3986 info->bmiHeader.biHeight = 8;
3987 info->bmiHeader.biPlanes = 1;
3988 info->bmiHeader.biBitCount = 32;
3989 info->bmiHeader.biCompression = BI_RGB;
3991 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3992 memset( dib_bits, 0xaa, 64 * 4 );
3994 info->bmiHeader.biBitCount = 8;
3995 info->bmiHeader.biCompression = BI_RLE8;
3996 info->bmiHeader.biSizeImage = sizeof(rle8_data);
3998 for (i = 0; i < 256; i++)
4000 info->bmiColors[i].rgbRed = i;
4001 info->bmiColors[i].rgbGreen = i;
4002 info->bmiColors[i].rgbBlue = i;
4003 info->bmiColors[i].rgbReserved = 0;
4006 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4007 ok( ret == 8, "got %d\n", ret );
4008 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4009 memset( dib_bits, 0xaa, 64 * 4 );
4011 /* startscan and lines are ignored, unless lines == 0 */
4012 ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4013 ok( ret == 8, "got %d\n", ret );
4014 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4015 memset( dib_bits, 0xaa, 64 * 4 );
4017 ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4018 ok( ret == 8, "got %d\n", ret );
4019 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4020 memset( dib_bits, 0xaa, 64 * 4 );
4022 ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4023 ok( ret == 0, "got %d\n", ret );
4024 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4025 memset( dib_bits, 0xaa, 64 * 4 );
4027 /* reduce width to 4, left-hand side of dst is touched. */
4028 info->bmiHeader.biWidth = 4;
4029 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4030 ok( ret == 8, "got %d\n", ret );
4031 for (i = 0; i < 64; i++)
4033 DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4034 ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4036 memset( dib_bits, 0xaa, 64 * 4 );
4038 /* Show that the top lines are aligned by adjusting the height of the src */
4040 /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4041 info->bmiHeader.biWidth = 8;
4042 info->bmiHeader.biHeight = 4;
4043 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4044 ok( ret == 4, "got %d\n", ret );
4045 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4046 ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4047 memset( dib_bits, 0xaa, 64 * 4 );
4049 /* increase the height to 9 -> everything moves down one row. */
4050 info->bmiHeader.biHeight = 9;
4051 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4052 ok( ret == 9, "got %d\n", ret );
4053 ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4054 for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4055 memset( dib_bits, 0xaa, 64 * 4 );
4057 /* top-down compressed dibs are invalid */
4058 info->bmiHeader.biHeight = -8;
4059 SetLastError( 0xdeadbeef );
4060 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4061 ok( ret == 0, "got %d\n", ret );
4062 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4063 DeleteObject( dib );
4065 /* top-down dst */
4067 info->bmiHeader.biHeight = -8;
4068 info->bmiHeader.biBitCount = 32;
4069 info->bmiHeader.biCompression = BI_RGB;
4070 info->bmiHeader.biSizeImage = 0;
4072 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4073 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4075 info->bmiHeader.biHeight = 8;
4076 info->bmiHeader.biBitCount = 8;
4077 info->bmiHeader.biCompression = BI_RLE8;
4078 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4080 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4081 ok( ret == 8, "got %d\n", ret );
4082 ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4083 memset( dib_bits, 0xaa, 64 * 4 );
4085 info->bmiHeader.biHeight = 4;
4086 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4087 ok( ret == 4, "got %d\n", ret );
4088 ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4089 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4090 memset( dib_bits, 0xaa, 64 * 4 );
4092 info->bmiHeader.biHeight = 9;
4093 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4094 ok( ret == 9, "got %d\n", ret );
4095 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4096 ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4097 memset( dib_bits, 0xaa, 64 * 4 );
4099 DeleteObject( dib );
4101 ReleaseDC( NULL, hdc );
4104 START_TEST(bitmap)
4106 HMODULE hdll;
4108 hdll = GetModuleHandle("gdi32.dll");
4109 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
4110 pSetLayout = (void*)GetProcAddress(hdll, "SetLayout");
4112 test_createdibitmap();
4113 test_dibsections();
4114 test_dib_formats();
4115 test_mono_dibsection();
4116 test_bitmap();
4117 test_bmBits();
4118 test_GetDIBits_selected_DIB(1);
4119 test_GetDIBits_selected_DIB(4);
4120 test_GetDIBits_selected_DIB(8);
4121 test_GetDIBits_selected_DDB(TRUE);
4122 test_GetDIBits_selected_DDB(FALSE);
4123 test_GetDIBits();
4124 test_GetDIBits_BI_BITFIELDS();
4125 test_select_object();
4126 test_CreateBitmap();
4127 test_BitBlt();
4128 test_StretchBlt();
4129 test_StretchDIBits();
4130 test_GdiAlphaBlend();
4131 test_32bit_bitmap_blt();
4132 test_bitmapinfoheadersize();
4133 test_get16dibits();
4134 test_clipping();
4135 test_GetDIBits_top_down(16);
4136 test_GetDIBits_top_down(24);
4137 test_GetDIBits_top_down(32);
4138 test_GetSetDIBits_rtl();
4139 test_GetDIBits_scanlines();
4140 test_SetDIBits();
4141 test_SetDIBits_RLE4();
4142 test_SetDIBits_RLE8();