gdi32/tests: Remove legacy support from the StretchBlt tests and fix the expected...
[wine.git] / dlls / gdi32 / tests / bitmap.c
blobbdc0d4dba16dcbc3087fc5c2da2a15d21ef9a842
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 return ((width * bpp + 31) / 8) & ~3;
261 static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
263 BITMAP bm;
264 BITMAP bma[2];
265 DIBSECTION ds;
266 DIBSECTION dsa[2];
267 INT ret, bm_width_bytes, dib_width_bytes;
268 BYTE *buf;
270 ret = GetObject(hbm, sizeof(bm), &bm);
271 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
273 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
274 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
275 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
276 dib_width_bytes = DIB_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
277 bm_width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
278 if (bm.bmWidthBytes != dib_width_bytes) /* Win2k bug */
279 ok(bm.bmWidthBytes == bm_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, bm_width_bytes);
280 else
281 ok(bm.bmWidthBytes == dib_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, dib_width_bytes);
282 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
283 ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount);
284 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
286 buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);
288 /* GetBitmapBits returns not 32-bit aligned data */
289 SetLastError(0xdeadbeef);
290 ret = GetBitmapBits(hbm, 0, NULL);
291 ok(ret == bm_width_bytes * bm.bmHeight,
292 "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
294 memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
295 ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
296 ok(ret == bm_width_bytes * bm.bmHeight, "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
298 HeapFree(GetProcessHeap(), 0, buf);
300 /* test various buffer sizes for GetObject */
301 memset(&ds, 0xAA, sizeof(ds));
302 ret = GetObject(hbm, sizeof(*bma) * 2, bma);
303 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
304 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
305 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
306 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
308 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
309 ok(ret == 0, "%d != 0\n", ret);
311 ret = GetObject(hbm, 0, &bm);
312 ok(ret == 0, "%d != 0\n", ret);
314 ret = GetObject(hbm, 1, &bm);
315 ok(ret == 0, "%d != 0\n", ret);
317 /* test various buffer sizes for GetObject */
318 ret = GetObject(hbm, 0, NULL);
319 ok(ret == sizeof(bm), "wrong size %d\n", ret);
321 ret = GetObject(hbm, sizeof(*dsa) * 2, dsa);
322 ok(ret == sizeof(*dsa), "wrong size %d\n", ret);
324 memset(&ds, 0xAA, sizeof(ds));
325 ret = GetObject(hbm, sizeof(ds), &ds);
326 ok(ret == sizeof(ds), "wrong size %d\n", ret);
328 ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
329 if (ds.dsBm.bmWidthBytes != bm_width_bytes) /* Win2k bug */
330 ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%u != %u\n",
331 ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
332 ok(bmih->biSizeImage == 0, "%u != 0\n", bmih->biSizeImage);
333 ds.dsBmih.biSizeImage = 0;
335 ok(ds.dsBmih.biSize == bmih->biSize, "%u != %u\n", ds.dsBmih.biSize, bmih->biSize);
336 ok(ds.dsBmih.biWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
337 ok(ds.dsBmih.biHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
338 ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes);
339 ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount);
340 ok(ds.dsBmih.biCompression == bmih->biCompression ||
341 ((bmih->biBitCount == 32) && broken(ds.dsBmih.biCompression == BI_BITFIELDS)), /* nt4 sp1 and 2 */
342 "%u != %u\n", ds.dsBmih.biCompression, bmih->biCompression);
343 ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%u != %u\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
344 ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%d != %d\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
345 ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%d != %d\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);
347 memset(&ds, 0xAA, sizeof(ds));
348 ret = GetObject(hbm, sizeof(ds) - 4, &ds);
349 ok(ret == sizeof(ds.dsBm), "wrong size %d\n", ret);
350 ok(ds.dsBm.bmWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
351 ok(ds.dsBm.bmHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
352 ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);
354 ret = GetObject(hbm, 0, &ds);
355 ok(ret == 0, "%d != 0\n", ret);
357 ret = GetObject(hbm, 1, &ds);
358 ok(ret == 0, "%d != 0\n", ret);
361 #define test_color_todo(got, exp, txt, todo) \
362 if (!todo && got != exp && screen_depth < 24) { \
363 todo_wine ok(0, #txt " failed at %d-bit screen depth: got 0x%06x expected 0x%06x - skipping DIB tests\n", \
364 screen_depth, (UINT)got, (UINT)exp); \
365 return; \
366 } else if (todo) todo_wine { ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp); } \
367 else ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp) \
369 #define test_color(hdc, color, exp, todo_setp, todo_getp) \
371 COLORREF c; \
372 c = SetPixel(hdc, 0, 0, color); \
373 test_color_todo(c, exp, SetPixel, todo_setp); \
374 c = GetPixel(hdc, 0, 0); \
375 test_color_todo(c, exp, GetPixel, todo_getp); \
378 static void test_dib_bits_access( HBITMAP hdib, void *bits )
380 MEMORY_BASIC_INFORMATION info;
381 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
382 DWORD data[256];
383 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
384 HDC hdc;
385 char filename[MAX_PATH];
386 HANDLE file;
387 DWORD written;
388 INT ret;
390 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
391 "VirtualQuery failed\n");
392 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
393 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
394 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
395 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
396 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
397 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
399 memset( pbmi, 0, sizeof(bmibuf) );
400 memset( data, 0xcc, sizeof(data) );
401 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
402 pbmi->bmiHeader.biHeight = 16;
403 pbmi->bmiHeader.biWidth = 16;
404 pbmi->bmiHeader.biBitCount = 32;
405 pbmi->bmiHeader.biPlanes = 1;
406 pbmi->bmiHeader.biCompression = BI_RGB;
408 hdc = GetDC(0);
410 ret = SetDIBits( hdc, hdib, 0, 16, data, pbmi, DIB_RGB_COLORS );
411 ok(ret == 16, "SetDIBits failed: expected 16 got %d\n", ret);
413 ReleaseDC(0, hdc);
415 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
416 "VirtualQuery failed\n");
417 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
418 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
419 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
420 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
421 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
422 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
424 /* try writing protected bits to a file */
426 GetTempFileNameA( ".", "dib", 0, filename );
427 file = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
428 CREATE_ALWAYS, 0, 0 );
429 ok( file != INVALID_HANDLE_VALUE, "failed to open %s error %u\n", filename, GetLastError() );
430 ret = WriteFile( file, bits, 8192, &written, NULL );
431 ok( ret, "WriteFile failed error %u\n", GetLastError() );
432 if (ret) ok( written == 8192, "only wrote %u bytes\n", written );
433 CloseHandle( file );
434 DeleteFileA( filename );
437 static void test_dibsections(void)
439 HDC hdc, hdcmem, hdcmem2;
440 HBITMAP hdib, oldbm, hdib2, oldbm2;
441 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
442 char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
443 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
444 BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
445 HBITMAP hcoredib;
446 char coreBits[256];
447 BYTE *bits;
448 RGBQUAD rgb[256];
449 int ret;
450 char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
451 LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
452 WORD *index;
453 DWORD *bits32;
454 HPALETTE hpal, oldpal;
455 DIBSECTION dibsec;
456 COLORREF c0, c1;
457 int i;
458 int screen_depth;
459 MEMORY_BASIC_INFORMATION info;
461 hdc = GetDC(0);
462 screen_depth = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
464 memset(pbmi, 0, sizeof(bmibuf));
465 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
466 pbmi->bmiHeader.biHeight = 100;
467 pbmi->bmiHeader.biWidth = 512;
468 pbmi->bmiHeader.biBitCount = 24;
469 pbmi->bmiHeader.biPlanes = 1;
470 pbmi->bmiHeader.biCompression = BI_RGB;
472 SetLastError(0xdeadbeef);
474 /* invalid pointer for BITMAPINFO
475 (*bits should be NULL on error) */
476 bits = (BYTE*)0xdeadbeef;
477 hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
478 ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n");
480 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
481 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
482 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
483 ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
485 /* test the DIB memory */
486 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
487 "VirtualQuery failed\n");
488 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
489 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
490 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
491 ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
492 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
493 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
494 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
496 test_dib_bits_access( hdib, bits );
498 test_dib_info(hdib, bits, &pbmi->bmiHeader);
499 DeleteObject(hdib);
501 /* Test a top-down DIB. */
502 pbmi->bmiHeader.biHeight = -100;
503 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
504 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
505 test_dib_info(hdib, bits, &pbmi->bmiHeader);
506 DeleteObject(hdib);
508 pbmi->bmiHeader.biHeight = 100;
509 pbmi->bmiHeader.biBitCount = 8;
510 pbmi->bmiHeader.biCompression = BI_RLE8;
511 SetLastError(0xdeadbeef);
512 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
513 ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
514 ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
516 pbmi->bmiHeader.biBitCount = 16;
517 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
518 ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
519 ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
520 ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
521 SetLastError(0xdeadbeef);
522 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
523 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
525 /* test the DIB memory */
526 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
527 "VirtualQuery failed\n");
528 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
529 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
530 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
531 ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
532 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
533 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
534 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
536 test_dib_info(hdib, bits, &pbmi->bmiHeader);
537 DeleteObject(hdib);
539 memset(pbmi, 0, sizeof(bmibuf));
540 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
541 pbmi->bmiHeader.biHeight = 16;
542 pbmi->bmiHeader.biWidth = 16;
543 pbmi->bmiHeader.biBitCount = 1;
544 pbmi->bmiHeader.biPlanes = 1;
545 pbmi->bmiHeader.biCompression = BI_RGB;
546 pbmi->bmiColors[0].rgbRed = 0xff;
547 pbmi->bmiColors[0].rgbGreen = 0;
548 pbmi->bmiColors[0].rgbBlue = 0;
549 pbmi->bmiColors[1].rgbRed = 0;
550 pbmi->bmiColors[1].rgbGreen = 0;
551 pbmi->bmiColors[1].rgbBlue = 0xff;
553 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
554 ok(hdib != NULL, "CreateDIBSection failed\n");
555 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
556 ok(dibsec.dsBmih.biClrUsed == 2,
557 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
559 /* Test if the old BITMAPCOREINFO structure is supported */
561 pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
562 pbci->bmciHeader.bcBitCount = 0;
564 ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
565 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
566 ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
567 && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
568 "GetDIBits didn't fill in the BITMAPCOREHEADER structure properly\n");
570 ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
571 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
572 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
573 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
574 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
575 "The color table has not been translated to the old BITMAPCOREINFO format\n");
577 hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
578 ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
580 ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
581 ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
582 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
583 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
584 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
585 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
586 "The color table has not been translated to the old BITMAPCOREINFO format\n");
588 DeleteObject(hcoredib);
590 hdcmem = CreateCompatibleDC(hdc);
591 oldbm = SelectObject(hdcmem, hdib);
593 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
594 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
595 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
596 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
597 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
598 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
600 c0 = RGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen, pbmi->bmiColors[0].rgbBlue);
601 c1 = RGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen, pbmi->bmiColors[1].rgbBlue);
603 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
604 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
605 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
606 test_color(hdcmem, PALETTEINDEX(0), c0, 1, 1);
607 test_color(hdcmem, PALETTEINDEX(1), c0, 1, 1);
608 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
609 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen,
610 pbmi->bmiColors[0].rgbBlue), c0, 1, 1);
611 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen,
612 pbmi->bmiColors[1].rgbBlue), c1, 1, 1);
613 test_color(hdcmem, PALETTERGB(0, 0, 0), c0, 1, 1);
614 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
615 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1, 1, 1);
617 SelectObject(hdcmem, oldbm);
618 DeleteObject(hdib);
620 pbmi->bmiColors[0].rgbRed = 0xff;
621 pbmi->bmiColors[0].rgbGreen = 0xff;
622 pbmi->bmiColors[0].rgbBlue = 0xff;
623 pbmi->bmiColors[1].rgbRed = 0;
624 pbmi->bmiColors[1].rgbGreen = 0;
625 pbmi->bmiColors[1].rgbBlue = 0;
627 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
628 ok(hdib != NULL, "CreateDIBSection failed\n");
630 test_dib_info(hdib, bits, &pbmi->bmiHeader);
632 oldbm = SelectObject(hdcmem, hdib);
634 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
635 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
636 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
637 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
638 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
639 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
641 SelectObject(hdcmem, oldbm);
642 test_dib_info(hdib, bits, &pbmi->bmiHeader);
643 DeleteObject(hdib);
645 pbmi->bmiHeader.biBitCount = 4;
646 for (i = 0; i < 16; i++) {
647 pbmi->bmiColors[i].rgbRed = i;
648 pbmi->bmiColors[i].rgbGreen = 16-i;
649 pbmi->bmiColors[i].rgbBlue = 0;
651 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
652 ok(hdib != NULL, "CreateDIBSection failed\n");
653 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
654 ok(dibsec.dsBmih.biClrUsed == 16,
655 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
656 test_dib_info(hdib, bits, &pbmi->bmiHeader);
657 DeleteObject(hdib);
659 pbmi->bmiHeader.biBitCount = 8;
661 for (i = 0; i < 128; i++) {
662 pbmi->bmiColors[i].rgbRed = 255 - i * 2;
663 pbmi->bmiColors[i].rgbGreen = i * 2;
664 pbmi->bmiColors[i].rgbBlue = 0;
665 pbmi->bmiColors[255 - i].rgbRed = 0;
666 pbmi->bmiColors[255 - i].rgbGreen = i * 2;
667 pbmi->bmiColors[255 - i].rgbBlue = 255 - i * 2;
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 == 256,
673 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
675 oldbm = SelectObject(hdcmem, hdib);
677 for (i = 0; i < 256; i++) {
678 test_color(hdcmem, DIBINDEX(i),
679 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
680 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue),
681 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
684 SelectObject(hdcmem, oldbm);
685 test_dib_info(hdib, bits, &pbmi->bmiHeader);
686 DeleteObject(hdib);
688 pbmi->bmiHeader.biBitCount = 1;
690 /* Now create a palette and a palette indexed dib section */
691 memset(plogpal, 0, sizeof(logpalbuf));
692 plogpal->palVersion = 0x300;
693 plogpal->palNumEntries = 2;
694 plogpal->palPalEntry[0].peRed = 0xff;
695 plogpal->palPalEntry[0].peBlue = 0xff;
696 plogpal->palPalEntry[1].peGreen = 0xff;
698 index = (WORD*)pbmi->bmiColors;
699 *index++ = 0;
700 *index = 1;
701 hpal = CreatePalette(plogpal);
702 ok(hpal != NULL, "CreatePalette failed\n");
703 oldpal = SelectPalette(hdc, hpal, TRUE);
704 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
705 ok(hdib != NULL, "CreateDIBSection failed\n");
706 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
707 ok(dibsec.dsBmih.biClrUsed == 2, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
709 /* The colour table has already been grabbed from the dc, so we select back the
710 old palette */
712 SelectPalette(hdc, oldpal, TRUE);
713 oldbm = SelectObject(hdcmem, hdib);
714 oldpal = SelectPalette(hdcmem, hpal, TRUE);
716 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
717 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
718 ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
719 rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
720 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
721 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
722 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
724 c0 = RGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen, plogpal->palPalEntry[0].peBlue);
725 c1 = RGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen, plogpal->palPalEntry[1].peBlue);
727 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
728 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
729 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
730 test_color(hdcmem, PALETTEINDEX(0), c0, 0, 1);
731 test_color(hdcmem, PALETTEINDEX(1), c1, 0, 1);
732 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
733 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen,
734 plogpal->palPalEntry[0].peBlue), c0, 1, 1);
735 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen,
736 plogpal->palPalEntry[1].peBlue), c1, 1, 1);
737 test_color(hdcmem, PALETTERGB(0, 0, 0), c1, 1, 1);
738 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
739 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0, 1, 1);
740 test_color(hdcmem, PALETTERGB(0, 1, 0), c1, 1, 1);
741 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1, 1, 1);
742 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0, 1, 1);
744 /* Bottom and 2nd row from top green, everything else magenta */
745 bits[0] = bits[1] = 0xff;
746 bits[13 * 4] = bits[13*4 + 1] = 0xff;
748 test_dib_info(hdib, bits, &pbmi->bmiHeader);
750 pbmi->bmiHeader.biBitCount = 32;
752 hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
753 ok(hdib2 != NULL, "CreateDIBSection failed\n");
754 hdcmem2 = CreateCompatibleDC(hdc);
755 oldbm2 = SelectObject(hdcmem2, hdib2);
757 BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
759 ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
760 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
762 SelectObject(hdcmem2, oldbm2);
763 test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
764 DeleteObject(hdib2);
766 SelectObject(hdcmem, oldbm);
767 SelectPalette(hdcmem, oldpal, TRUE);
768 DeleteObject(hdib);
769 DeleteObject(hpal);
772 pbmi->bmiHeader.biBitCount = 8;
774 memset(plogpal, 0, sizeof(logpalbuf));
775 plogpal->palVersion = 0x300;
776 plogpal->palNumEntries = 256;
778 for (i = 0; i < 128; i++) {
779 plogpal->palPalEntry[i].peRed = 255 - i * 2;
780 plogpal->palPalEntry[i].peBlue = i * 2;
781 plogpal->palPalEntry[i].peGreen = 0;
782 plogpal->palPalEntry[255 - i].peRed = 0;
783 plogpal->palPalEntry[255 - i].peGreen = i * 2;
784 plogpal->palPalEntry[255 - i].peBlue = 255 - i * 2;
787 index = (WORD*)pbmi->bmiColors;
788 for (i = 0; i < 256; i++) {
789 *index++ = i;
792 hpal = CreatePalette(plogpal);
793 ok(hpal != NULL, "CreatePalette failed\n");
794 oldpal = SelectPalette(hdc, hpal, TRUE);
795 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
796 ok(hdib != NULL, "CreateDIBSection failed\n");
797 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
798 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
800 test_dib_info(hdib, bits, &pbmi->bmiHeader);
802 SelectPalette(hdc, oldpal, TRUE);
803 oldbm = SelectObject(hdcmem, hdib);
804 oldpal = SelectPalette(hdcmem, hpal, TRUE);
806 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
807 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
808 for (i = 0; i < 256; i++) {
809 ok(rgb[i].rgbRed == plogpal->palPalEntry[i].peRed &&
810 rgb[i].rgbBlue == plogpal->palPalEntry[i].peBlue &&
811 rgb[i].rgbGreen == plogpal->palPalEntry[i].peGreen,
812 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
813 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
816 for (i = 0; i < 256; i++) {
817 test_color(hdcmem, DIBINDEX(i),
818 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
819 test_color(hdcmem, PALETTEINDEX(i),
820 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
821 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue),
822 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
825 SelectPalette(hdcmem, oldpal, TRUE);
826 SelectObject(hdcmem, oldbm);
827 DeleteObject(hdib);
828 DeleteObject(hpal);
830 DeleteDC(hdcmem);
831 DeleteDC(hdcmem2);
832 ReleaseDC(0, hdc);
835 static void test_dib_formats(void)
837 char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256])];
838 BITMAPINFO *bi = (BITMAPINFO *)buffer;
839 char data[256];
840 void *bits;
841 int planes, bpp, compr;
842 HBITMAP hdib, hbmp;
843 HDC hdc, memdc;
844 UINT ret;
845 BOOL expect_ok, todo;
847 hdc = GetDC( 0 );
848 memdc = CreateCompatibleDC( 0 );
849 hbmp = CreateCompatibleBitmap( hdc, 10, 10 );
851 memset( data, 0xaa, sizeof(data) );
853 for (bpp = 0; bpp <= 64; bpp++)
855 for (planes = 0; planes <= 64; planes++)
857 for (compr = 0; compr < 8; compr++)
859 switch (bpp)
861 case 1:
862 case 4:
863 case 8:
864 case 24: expect_ok = (compr == BI_RGB); break;
865 case 16:
866 case 32: expect_ok = (compr == BI_RGB || compr == BI_BITFIELDS); break;
867 default: expect_ok = FALSE; break;
869 todo = (compr == BI_BITFIELDS); /* wine doesn't like strange bitfields */
871 memset( bi, 0, sizeof(bi->bmiHeader) );
872 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
873 bi->bmiHeader.biWidth = 2;
874 bi->bmiHeader.biHeight = 2;
875 bi->bmiHeader.biPlanes = planes;
876 bi->bmiHeader.biBitCount = bpp;
877 bi->bmiHeader.biCompression = compr;
878 bi->bmiHeader.biSizeImage = 0;
879 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
880 ret = GetDIBits(hdc, hbmp, 0, 0, data, bi, DIB_RGB_COLORS);
881 if (expect_ok || (!bpp && compr != BI_JPEG && compr != BI_PNG) ||
882 (bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8))
883 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
884 else
885 ok( !ret || broken(!bpp && (compr == BI_JPEG || compr == BI_PNG)), /* nt4 */
886 "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
888 /* all functions check planes except GetDIBits with 0 lines */
889 if (!planes) expect_ok = FALSE;
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)
933 if (todo)
934 todo_wine ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
935 else
936 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
938 else
939 ok( !ret ||
940 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
941 "SetDIBitsToDevice succeeded for %u/%u/%u\n", bpp, planes, compr );
942 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
943 if (expect_ok)
945 if (todo)
946 todo_wine ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
947 else
948 ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
950 else
951 ok( !ret ||
952 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
953 "StretchDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
955 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
956 if (expect_ok)
957 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
958 else
959 ok( !ret, "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
960 ok( bi->bmiHeader.biBitCount == bpp, "GetDIBits modified bpp %u/%u\n",
961 bpp, bi->bmiHeader.biBitCount );
963 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
964 bi->bmiHeader.biWidth = 2;
965 bi->bmiHeader.biHeight = 2;
966 bi->bmiHeader.biPlanes = planes;
967 bi->bmiHeader.biBitCount = bpp;
968 bi->bmiHeader.biCompression = compr;
969 bi->bmiHeader.biSizeImage = 1;
970 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
971 /* RLE allowed with valid biSizeImage */
972 if ((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)) expect_ok = TRUE;
974 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
975 if (expect_ok)
977 if (todo)
978 todo_wine ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
979 else
980 ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
982 else
983 ok( !ret, "SetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
984 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
985 if (expect_ok)
987 if (todo)
988 todo_wine ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
989 else
990 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
992 else
993 ok( !ret, "SetDIBitsToDevice succeeded for %u/%u/%u\n", bpp, planes, compr );
994 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
995 if (expect_ok)
997 if (todo)
998 todo_wine ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
999 else
1000 ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
1002 else
1003 ok( !ret, "StretchDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
1005 bi->bmiHeader.biSizeImage = 0;
1006 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1007 if (expect_ok || !bpp)
1008 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
1009 else
1010 ok( !ret, "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
1015 memset( bi, 0, sizeof(bi->bmiHeader) );
1016 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1017 bi->bmiHeader.biWidth = 2;
1018 bi->bmiHeader.biHeight = 2;
1019 bi->bmiHeader.biPlanes = 1;
1020 bi->bmiHeader.biBitCount = 16;
1021 bi->bmiHeader.biCompression = BI_BITFIELDS;
1022 bi->bmiHeader.biSizeImage = 0;
1023 *(DWORD *)&bi->bmiColors[0] = 0;
1024 *(DWORD *)&bi->bmiColors[1] = 0;
1025 *(DWORD *)&bi->bmiColors[2] = 0;
1027 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1028 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1029 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1030 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1031 /* other functions don't check */
1032 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1033 ok( hdib != NULL, "CreateDIBitmap failed with null bitfields\n" );
1034 DeleteObject( hdib );
1035 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1036 todo_wine ok( ret, "SetDIBitsToDevice failed with null bitfields\n" );
1037 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1038 todo_wine ok( ret, "StretchDIBits failed with null bitfields\n" );
1039 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1040 ok( ret, "GetDIBits failed with null bitfields\n" );
1041 bi->bmiHeader.biPlanes = 1;
1042 bi->bmiHeader.biBitCount = 16;
1043 bi->bmiHeader.biCompression = BI_BITFIELDS;
1044 bi->bmiHeader.biSizeImage = 0;
1045 *(DWORD *)&bi->bmiColors[0] = 0;
1046 *(DWORD *)&bi->bmiColors[1] = 0;
1047 *(DWORD *)&bi->bmiColors[2] = 0;
1048 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1049 ok( ret, "GetDIBits failed with null bitfields\n" );
1051 /* all fields must be non-zero */
1052 *(DWORD *)&bi->bmiColors[0] = 3;
1053 *(DWORD *)&bi->bmiColors[1] = 0;
1054 *(DWORD *)&bi->bmiColors[2] = 7;
1055 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1056 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1057 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1058 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1060 /* garbage is ok though */
1061 *(DWORD *)&bi->bmiColors[0] = 0x55;
1062 *(DWORD *)&bi->bmiColors[1] = 0x44;
1063 *(DWORD *)&bi->bmiColors[2] = 0x33;
1064 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1065 ok( hdib != NULL, "CreateDIBSection failed with bad bitfields\n" );
1066 if (hdib) DeleteObject( hdib );
1067 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1068 todo_wine ok( ret, "SetDIBits failed with bad bitfields\n" );
1070 bi->bmiHeader.biWidth = -2;
1071 bi->bmiHeader.biHeight = 2;
1072 bi->bmiHeader.biBitCount = 32;
1073 bi->bmiHeader.biCompression = BI_RGB;
1074 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1075 ok( hdib == NULL, "CreateDIBSection succeeded with negative width\n" );
1076 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1077 ok( hdib == NULL, "CreateDIBitmap succeeded with negative width\n" );
1078 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1079 ok( !ret, "SetDIBits succeeded with negative width\n" );
1080 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1081 ok( !ret, "SetDIBitsToDevice succeeded with negative width\n" );
1082 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1083 ok( !ret, "StretchDIBits succeeded with negative width\n" );
1084 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1085 ok( !ret, "GetDIBits succeeded with negative width\n" );
1086 bi->bmiHeader.biWidth = -2;
1087 bi->bmiHeader.biHeight = 2;
1088 bi->bmiHeader.biBitCount = 32;
1089 bi->bmiHeader.biCompression = BI_RGB;
1090 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1091 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with negative width\n" );
1093 bi->bmiHeader.biWidth = 0;
1094 bi->bmiHeader.biHeight = 2;
1095 bi->bmiHeader.biBitCount = 32;
1096 bi->bmiHeader.biCompression = BI_RGB;
1097 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1098 ok( hdib == NULL, "CreateDIBSection succeeded with zero width\n" );
1099 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1100 ok( hdib != NULL, "CreateDIBitmap failed with zero width\n" );
1101 DeleteObject( hdib );
1102 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1103 ok( !ret || broken(ret), /* nt4 */ "SetDIBits succeeded with zero width\n" );
1104 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1105 ok( !ret || broken(ret), /* nt4 */ "SetDIBitsToDevice succeeded with zero width\n" );
1106 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1107 ok( !ret || broken(ret), /* nt4 */ "StretchDIBits succeeded with zero width\n" );
1108 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1109 ok( !ret, "GetDIBits succeeded with zero width\n" );
1110 bi->bmiHeader.biWidth = 0;
1111 bi->bmiHeader.biHeight = 2;
1112 bi->bmiHeader.biBitCount = 32;
1113 bi->bmiHeader.biCompression = BI_RGB;
1114 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1115 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero width\n" );
1117 bi->bmiHeader.biWidth = 2;
1118 bi->bmiHeader.biHeight = 0;
1119 bi->bmiHeader.biBitCount = 32;
1120 bi->bmiHeader.biCompression = BI_RGB;
1121 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1122 ok( hdib == NULL, "CreateDIBSection succeeded with zero height\n" );
1123 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1124 ok( hdib != NULL, "CreateDIBitmap failed with zero height\n" );
1125 DeleteObject( hdib );
1126 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1127 ok( !ret, "SetDIBits succeeded with zero height\n" );
1128 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1129 ok( !ret, "SetDIBitsToDevice succeeded with zero height\n" );
1130 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1131 ok( !ret, "StretchDIBits succeeded with zero height\n" );
1132 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1133 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1134 bi->bmiHeader.biWidth = 2;
1135 bi->bmiHeader.biHeight = 0;
1136 bi->bmiHeader.biBitCount = 32;
1137 bi->bmiHeader.biCompression = BI_RGB;
1138 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1139 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1141 DeleteDC( memdc );
1142 DeleteObject( hbmp );
1143 ReleaseDC( 0, hdc );
1146 static void test_mono_dibsection(void)
1148 HDC hdc, memdc;
1149 HBITMAP old_bm, mono_ds;
1150 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
1151 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
1152 BYTE bits[10 * 4];
1153 BYTE *ds_bits;
1154 int num;
1156 hdc = GetDC(0);
1158 memdc = CreateCompatibleDC(hdc);
1160 memset(pbmi, 0, sizeof(bmibuf));
1161 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
1162 pbmi->bmiHeader.biHeight = 10;
1163 pbmi->bmiHeader.biWidth = 10;
1164 pbmi->bmiHeader.biBitCount = 1;
1165 pbmi->bmiHeader.biPlanes = 1;
1166 pbmi->bmiHeader.biCompression = BI_RGB;
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;
1175 * First dib section is 'inverted' ie color[0] is white, color[1] is black
1178 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1179 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1180 old_bm = SelectObject(memdc, mono_ds);
1182 /* black border, white interior */
1183 Rectangle(memdc, 0, 0, 10, 10);
1184 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1185 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1187 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1189 memset(bits, 0, sizeof(bits));
1190 bits[0] = 0xaa;
1192 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1193 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1195 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1197 pbmi->bmiColors[0].rgbRed = 0x0;
1198 pbmi->bmiColors[0].rgbGreen = 0x0;
1199 pbmi->bmiColors[0].rgbBlue = 0x0;
1200 pbmi->bmiColors[1].rgbRed = 0xff;
1201 pbmi->bmiColors[1].rgbGreen = 0xff;
1202 pbmi->bmiColors[1].rgbBlue = 0xff;
1204 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1205 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1207 SelectObject(memdc, old_bm);
1208 DeleteObject(mono_ds);
1211 * Next dib section is 'normal' ie color[0] is black, color[1] is white
1214 pbmi->bmiColors[0].rgbRed = 0x0;
1215 pbmi->bmiColors[0].rgbGreen = 0x0;
1216 pbmi->bmiColors[0].rgbBlue = 0x0;
1217 pbmi->bmiColors[1].rgbRed = 0xff;
1218 pbmi->bmiColors[1].rgbGreen = 0xff;
1219 pbmi->bmiColors[1].rgbBlue = 0xff;
1221 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1222 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1223 old_bm = SelectObject(memdc, mono_ds);
1225 /* black border, white interior */
1226 Rectangle(memdc, 0, 0, 10, 10);
1227 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
1228 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
1230 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
1232 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1233 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1235 /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
1237 pbmi->bmiColors[0].rgbRed = 0xff;
1238 pbmi->bmiColors[0].rgbGreen = 0xff;
1239 pbmi->bmiColors[0].rgbBlue = 0xff;
1240 pbmi->bmiColors[1].rgbRed = 0x0;
1241 pbmi->bmiColors[1].rgbGreen = 0x0;
1242 pbmi->bmiColors[1].rgbBlue = 0x0;
1244 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1245 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1248 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
1251 pbmi->bmiColors[0].rgbRed = 0xff;
1252 pbmi->bmiColors[0].rgbGreen = 0xff;
1253 pbmi->bmiColors[0].rgbBlue = 0xff;
1254 pbmi->bmiColors[1].rgbRed = 0x0;
1255 pbmi->bmiColors[1].rgbGreen = 0x0;
1256 pbmi->bmiColors[1].rgbBlue = 0x0;
1257 num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors);
1258 ok(num == 2, "num = %d\n", num);
1260 /* black border, white interior */
1261 Rectangle(memdc, 0, 0, 10, 10);
1262 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1263 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1265 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1267 memset(bits, 0, sizeof(bits));
1268 bits[0] = 0xaa;
1270 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1271 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1273 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1275 pbmi->bmiColors[0].rgbRed = 0x0;
1276 pbmi->bmiColors[0].rgbGreen = 0x0;
1277 pbmi->bmiColors[0].rgbBlue = 0x0;
1278 pbmi->bmiColors[1].rgbRed = 0xff;
1279 pbmi->bmiColors[1].rgbGreen = 0xff;
1280 pbmi->bmiColors[1].rgbBlue = 0xff;
1282 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1283 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1285 SelectObject(memdc, old_bm);
1286 DeleteObject(mono_ds);
1289 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
1292 pbmi->bmiColors[0].rgbRed = 0xff;
1293 pbmi->bmiColors[0].rgbGreen = 0x0;
1294 pbmi->bmiColors[0].rgbBlue = 0x0;
1295 pbmi->bmiColors[1].rgbRed = 0xfe;
1296 pbmi->bmiColors[1].rgbGreen = 0x0;
1297 pbmi->bmiColors[1].rgbBlue = 0x0;
1299 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1300 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1301 old_bm = SelectObject(memdc, mono_ds);
1303 /* black border, white interior */
1304 Rectangle(memdc, 0, 0, 10, 10);
1305 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1306 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1308 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1310 pbmi->bmiColors[0].rgbRed = 0x0;
1311 pbmi->bmiColors[0].rgbGreen = 0x0;
1312 pbmi->bmiColors[0].rgbBlue = 0x0;
1313 pbmi->bmiColors[1].rgbRed = 0xff;
1314 pbmi->bmiColors[1].rgbGreen = 0xff;
1315 pbmi->bmiColors[1].rgbBlue = 0xff;
1317 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1318 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1320 /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
1322 pbmi->bmiColors[0].rgbRed = 0xff;
1323 pbmi->bmiColors[0].rgbGreen = 0xff;
1324 pbmi->bmiColors[0].rgbBlue = 0xff;
1325 pbmi->bmiColors[1].rgbRed = 0x0;
1326 pbmi->bmiColors[1].rgbGreen = 0x0;
1327 pbmi->bmiColors[1].rgbBlue = 0x0;
1329 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1330 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1332 SelectObject(memdc, old_bm);
1333 DeleteObject(mono_ds);
1335 DeleteDC(memdc);
1336 ReleaseDC(0, hdc);
1339 static void test_bitmap(void)
1341 char buf[256], buf_cmp[256];
1342 HBITMAP hbmp, hbmp_old;
1343 HDC hdc;
1344 BITMAP bm;
1345 BITMAP bma[2];
1346 INT ret;
1348 hdc = CreateCompatibleDC(0);
1349 assert(hdc != 0);
1351 SetLastError(0xdeadbeef);
1352 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1353 if (!hbmp)
1355 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1356 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1357 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1359 else
1360 DeleteObject(hbmp);
1362 SetLastError(0xdeadbeef);
1363 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1364 if (!hbmp)
1366 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1367 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1368 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1370 else
1371 DeleteObject(hbmp);
1373 SetLastError(0xdeadbeef);
1374 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1375 ok(!hbmp, "CreateBitmap should fail\n");
1376 if (!hbmp)
1377 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1378 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1379 else
1380 DeleteObject(hbmp);
1382 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1383 assert(hbmp != NULL);
1385 ret = GetObject(hbmp, sizeof(bm), &bm);
1386 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1388 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1389 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1390 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1391 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1392 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1393 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1394 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1396 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1397 assert(sizeof(buf) == sizeof(buf_cmp));
1399 ret = GetBitmapBits(hbmp, 0, NULL);
1400 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1402 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1403 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1405 memset(buf, 0xAA, sizeof(buf));
1406 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1407 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1408 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1410 hbmp_old = SelectObject(hdc, hbmp);
1412 ret = GetObject(hbmp, sizeof(bm), &bm);
1413 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1415 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1416 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1417 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1418 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1419 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1420 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1421 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1423 memset(buf, 0xAA, sizeof(buf));
1424 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1425 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1426 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1428 hbmp_old = SelectObject(hdc, hbmp_old);
1429 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1431 /* test various buffer sizes for GetObject */
1432 ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
1433 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1435 ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1436 ok(ret == 0, "%d != 0\n", ret);
1438 ret = GetObject(hbmp, 0, &bm);
1439 ok(ret == 0, "%d != 0\n", ret);
1441 ret = GetObject(hbmp, 1, &bm);
1442 ok(ret == 0, "%d != 0\n", ret);
1444 DeleteObject(hbmp);
1445 DeleteDC(hdc);
1448 static void test_bmBits(void)
1450 BYTE bits[4];
1451 HBITMAP hbmp;
1452 BITMAP bmp;
1454 memset(bits, 0, sizeof(bits));
1455 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1456 ok(hbmp != NULL, "CreateBitmap failed\n");
1458 memset(&bmp, 0xFF, sizeof(bmp));
1459 ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1460 "GetObject failed or returned a wrong structure size\n");
1461 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1463 DeleteObject(hbmp);
1466 static void test_GetDIBits_selected_DIB(UINT bpp)
1468 HBITMAP dib;
1469 char bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1470 char bmibuf2[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1471 BITMAPINFO *info = (BITMAPINFO *)bmibuf;
1472 BITMAPINFO *info2 = (BITMAPINFO *)bmibuf2;
1473 void * bits;
1474 void * bits2;
1475 UINT dib_size, dib32_size;
1476 DWORD pixel;
1477 HDC dib_dc, dc;
1478 HBITMAP old_bmp;
1479 UINT i;
1480 int res;
1482 /* Create a DIB section with a color table */
1484 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1485 info->bmiHeader.biWidth = 32;
1486 info->bmiHeader.biHeight = 32;
1487 info->bmiHeader.biPlanes = 1;
1488 info->bmiHeader.biBitCount = bpp;
1489 info->bmiHeader.biCompression = BI_RGB;
1490 info->bmiHeader.biXPelsPerMeter = 0;
1491 info->bmiHeader.biYPelsPerMeter = 0;
1492 info->bmiHeader.biClrUsed = 0;
1493 info->bmiHeader.biClrImportant = 0;
1495 for (i=0; i < (1u << bpp); i++)
1497 BYTE c = i * (1 << (8 - bpp));
1498 info->bmiColors[i].rgbRed = c;
1499 info->bmiColors[i].rgbGreen = c;
1500 info->bmiColors[i].rgbBlue = c;
1501 info->bmiColors[i].rgbReserved = 0;
1504 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1505 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1506 dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1508 /* Set the bits of the DIB section */
1509 for (i=0; i < dib_size; i++)
1511 ((BYTE *)bits)[i] = i % 256;
1514 /* Select the DIB into a DC */
1515 dib_dc = CreateCompatibleDC(NULL);
1516 old_bmp = SelectObject(dib_dc, dib);
1517 dc = CreateCompatibleDC(NULL);
1518 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
1520 /* Copy the DIB attributes but not the color table */
1521 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1523 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1524 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1526 /* Compare the color table and the bits */
1527 for (i=0; i < (1u << bpp); i++)
1528 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1529 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1530 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1531 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1532 "color table entry %d differs (bpp %d)\n", i, bpp );
1534 ok( !memcmp( bits, bits2, dib_size ), "bit mismatch (bpp %d)\n", bpp );
1536 /* Test various combinations of lines = 0 and bits2 = NULL */
1537 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1538 res = GetDIBits( dc, dib, 0, 0, bits2, info2, DIB_RGB_COLORS );
1539 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1540 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1541 "color table mismatch (bpp %d)\n", bpp );
1543 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1544 res = GetDIBits( dc, dib, 0, 0, NULL, info2, DIB_RGB_COLORS );
1545 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1546 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1547 "color table mismatch (bpp %d)\n", bpp );
1549 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1550 res = GetDIBits( dc, dib, 0, info->bmiHeader.biHeight, NULL, info2, DIB_RGB_COLORS );
1551 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1552 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1553 "color table mismatch (bpp %d)\n", bpp );
1555 /* Map into a 32bit-DIB */
1556 info2->bmiHeader.biBitCount = 32;
1557 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1558 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1560 /* Check if last pixel was set */
1561 pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
1562 ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
1564 HeapFree(GetProcessHeap(), 0, bits2);
1565 DeleteDC(dc);
1567 SelectObject(dib_dc, old_bmp);
1568 DeleteDC(dib_dc);
1569 DeleteObject(dib);
1572 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1574 HBITMAP ddb;
1575 char bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1576 char bmibuf2[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1577 BITMAPINFO *info = (BITMAPINFO *)bmibuf;
1578 BITMAPINFO *info2 = (BITMAPINFO *)bmibuf2;
1579 void * bits;
1580 void * bits2;
1581 HDC ddb_dc, dc;
1582 HBITMAP old_bmp;
1583 UINT width, height;
1584 UINT bpp;
1585 UINT i, j;
1586 int res;
1588 width = height = 16;
1590 /* Create a DDB (device-dependent bitmap) */
1591 if (monochrome)
1593 bpp = 1;
1594 ddb = CreateBitmap(width, height, 1, 1, NULL);
1596 else
1598 HDC screen_dc = GetDC(NULL);
1599 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1600 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1601 ReleaseDC(NULL, screen_dc);
1604 /* Set the pixels */
1605 ddb_dc = CreateCompatibleDC(NULL);
1606 old_bmp = SelectObject(ddb_dc, ddb);
1607 for (i = 0; i < width; i++)
1609 for (j=0; j < height; j++)
1611 BYTE c = (i * width + j) % 256;
1612 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1615 SelectObject(ddb_dc, old_bmp);
1617 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1618 info->bmiHeader.biWidth = width;
1619 info->bmiHeader.biHeight = height;
1620 info->bmiHeader.biPlanes = 1;
1621 info->bmiHeader.biBitCount = bpp;
1622 info->bmiHeader.biCompression = BI_RGB;
1624 dc = CreateCompatibleDC(NULL);
1626 /* Fill in biSizeImage */
1627 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1628 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1630 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1631 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1633 /* Get the bits */
1634 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1635 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1637 /* Copy the DIB attributes but not the color table */
1638 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1640 /* Select the DDB into another DC */
1641 old_bmp = SelectObject(ddb_dc, ddb);
1643 /* Get the bits */
1644 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1645 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1647 /* Compare the color table and the bits */
1648 if (bpp <= 8)
1650 for (i=0; i < (1u << bpp); i++)
1651 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1652 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1653 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1654 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1655 "color table entry %d differs (bpp %d)\n", i, bpp );
1658 ok( !memcmp( bits, bits2, info->bmiHeader.biSizeImage ), "bit mismatch (bpp %d)\n", bpp );
1660 /* Test the palette */
1661 if (info2->bmiHeader.biBitCount <= 8)
1663 WORD *colors = (WORD*)info2->bmiColors;
1665 /* Get the palette indices */
1666 res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1667 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1669 for (i = 0; i < (1 << info->bmiHeader.biBitCount); i++)
1670 ok( colors[i] == i, "%d: got %d (bpp %d)\n", i, colors[i], bpp );
1673 HeapFree(GetProcessHeap(), 0, bits2);
1674 HeapFree(GetProcessHeap(), 0, bits);
1675 DeleteDC(dc);
1677 SelectObject(ddb_dc, old_bmp);
1678 DeleteDC(ddb_dc);
1679 DeleteObject(ddb);
1682 static void test_GetDIBits(void)
1684 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1685 static const BYTE bmp_bits_1[16 * 2] =
1687 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1688 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1689 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1690 0xff,0xff, 0,0, 0xff,0xff, 0,0
1692 /* 4-bytes aligned 1-bit DIB data: 16x16 */
1693 static const BYTE dib_bits_1[16 * 4] =
1695 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1696 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1697 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1698 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1700 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1701 static const BYTE bmp_bits_24[16 * 16*3] =
1703 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1704 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1705 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1706 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1707 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1708 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1709 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1710 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1711 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1712 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1713 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1714 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1715 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1716 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1717 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1718 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1719 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1720 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1721 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1722 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1723 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1724 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1725 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1726 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1727 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1728 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1729 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1730 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1731 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1732 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1733 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1734 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1736 /* 4-bytes aligned 24-bit DIB data: 16x16 */
1737 static const BYTE dib_bits_24[16 * 16*3] =
1739 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1740 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1741 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1742 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1743 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1744 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1745 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1746 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1747 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1748 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1749 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1750 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1751 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1752 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1753 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1754 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1755 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1756 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1757 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1758 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1759 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1760 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1761 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1762 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1763 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1764 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1765 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1766 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1767 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1768 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1769 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1770 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1772 HBITMAP hbmp;
1773 BITMAP bm;
1774 HDC hdc;
1775 int i, bytes, lines;
1776 BYTE buf[1024];
1777 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1778 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1779 PALETTEENTRY pal_ents[20];
1781 hdc = GetDC(0);
1783 /* 1-bit source bitmap data */
1784 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1785 ok(hbmp != 0, "CreateBitmap failed\n");
1787 memset(&bm, 0xAA, sizeof(bm));
1788 bytes = GetObject(hbmp, sizeof(bm), &bm);
1789 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1790 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1791 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1792 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1793 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1794 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1795 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1796 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1798 bytes = GetBitmapBits(hbmp, 0, NULL);
1799 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1800 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1801 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1802 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1804 /* retrieve 1-bit DIB data */
1805 memset(bi, 0, sizeof(*bi));
1806 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1807 bi->bmiHeader.biWidth = bm.bmWidth;
1808 bi->bmiHeader.biHeight = bm.bmHeight;
1809 bi->bmiHeader.biPlanes = 1;
1810 bi->bmiHeader.biBitCount = 1;
1811 bi->bmiHeader.biCompression = BI_RGB;
1812 bi->bmiHeader.biSizeImage = 0;
1813 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1814 SetLastError(0xdeadbeef);
1815 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1816 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1817 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1818 broken(GetLastError() == 0xdeadbeef), /* winnt */
1819 "wrong error %u\n", GetLastError());
1820 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1822 memset(buf, 0xAA, sizeof(buf));
1823 SetLastError(0xdeadbeef);
1824 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1825 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1826 lines, bm.bmHeight, GetLastError());
1827 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1829 /* the color table consists of black and white */
1830 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1831 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1832 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1833 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1834 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1835 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1836 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1837 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1838 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1839 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1840 for (i = 2; i < 256; i++)
1842 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1843 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1844 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1845 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1846 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1849 /* returned bits are DWORD aligned and upside down */
1850 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1852 /* Test the palette indices */
1853 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1854 SetLastError(0xdeadbeef);
1855 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1856 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1857 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1858 for (i = 2; i < 256; i++)
1859 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[1]);
1861 /* retrieve 24-bit DIB data */
1862 memset(bi, 0, sizeof(*bi));
1863 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1864 bi->bmiHeader.biWidth = bm.bmWidth;
1865 bi->bmiHeader.biHeight = bm.bmHeight;
1866 bi->bmiHeader.biPlanes = 1;
1867 bi->bmiHeader.biBitCount = 24;
1868 bi->bmiHeader.biCompression = BI_RGB;
1869 bi->bmiHeader.biSizeImage = 0;
1870 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1871 memset(buf, 0xAA, sizeof(buf));
1872 SetLastError(0xdeadbeef);
1873 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1874 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1875 lines, bm.bmHeight, GetLastError());
1876 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1878 /* the color table doesn't exist for 24-bit images */
1879 for (i = 0; i < 256; i++)
1881 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1882 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1883 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1884 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1885 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1888 /* returned bits are DWORD aligned and upside down */
1889 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1890 DeleteObject(hbmp);
1892 /* 24-bit source bitmap data */
1893 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1894 ok(hbmp != 0, "CreateBitmap failed\n");
1895 SetLastError(0xdeadbeef);
1896 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1897 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1898 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1899 lines, bm.bmHeight, GetLastError());
1901 memset(&bm, 0xAA, sizeof(bm));
1902 bytes = GetObject(hbmp, sizeof(bm), &bm);
1903 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1904 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1905 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1906 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1907 ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1908 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1909 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1910 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1912 bytes = GetBitmapBits(hbmp, 0, NULL);
1913 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
1914 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1915 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1916 bm.bmWidthBytes * bm.bmHeight, bytes);
1918 /* retrieve 1-bit DIB data */
1919 memset(bi, 0, sizeof(*bi));
1920 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1921 bi->bmiHeader.biWidth = bm.bmWidth;
1922 bi->bmiHeader.biHeight = bm.bmHeight;
1923 bi->bmiHeader.biPlanes = 1;
1924 bi->bmiHeader.biBitCount = 1;
1925 bi->bmiHeader.biCompression = BI_RGB;
1926 bi->bmiHeader.biSizeImage = 0;
1927 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1928 memset(buf, 0xAA, sizeof(buf));
1929 SetLastError(0xdeadbeef);
1930 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1931 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1932 lines, bm.bmHeight, GetLastError());
1933 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1935 /* the color table consists of black and white */
1936 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1937 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1938 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1939 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1940 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1941 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1942 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1943 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1944 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1945 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1946 for (i = 2; i < 256; i++)
1948 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1949 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1950 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1951 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1952 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1955 /* returned bits are DWORD aligned and upside down */
1956 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1958 /* Test the palette indices */
1959 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1960 SetLastError(0xdeadbeef);
1961 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1962 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1963 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1964 for (i = 2; i < 256; i++)
1965 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[i]);
1967 /* retrieve 4-bit DIB data */
1968 memset(bi, 0, sizeof(*bi));
1969 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1970 bi->bmiHeader.biWidth = bm.bmWidth;
1971 bi->bmiHeader.biHeight = bm.bmHeight;
1972 bi->bmiHeader.biPlanes = 1;
1973 bi->bmiHeader.biBitCount = 4;
1974 bi->bmiHeader.biCompression = BI_RGB;
1975 bi->bmiHeader.biSizeImage = 0;
1976 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1977 memset(buf, 0xAA, sizeof(buf));
1978 SetLastError(0xdeadbeef);
1979 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1980 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1981 lines, bm.bmHeight, GetLastError());
1983 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
1985 for (i = 0; i < 16; i++)
1987 RGBQUAD expect;
1988 int entry = i < 8 ? i : i + 4;
1990 if(entry == 7) entry = 12;
1991 else if(entry == 12) entry = 7;
1993 expect.rgbRed = pal_ents[entry].peRed;
1994 expect.rgbGreen = pal_ents[entry].peGreen;
1995 expect.rgbBlue = pal_ents[entry].peBlue;
1996 expect.rgbReserved = 0;
1998 ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
1999 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2000 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2001 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
2002 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
2005 /* retrieve 8-bit DIB data */
2006 memset(bi, 0, sizeof(*bi));
2007 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2008 bi->bmiHeader.biWidth = bm.bmWidth;
2009 bi->bmiHeader.biHeight = bm.bmHeight;
2010 bi->bmiHeader.biPlanes = 1;
2011 bi->bmiHeader.biBitCount = 8;
2012 bi->bmiHeader.biCompression = BI_RGB;
2013 bi->bmiHeader.biSizeImage = 0;
2014 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
2015 memset(buf, 0xAA, sizeof(buf));
2016 SetLastError(0xdeadbeef);
2017 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2018 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2019 lines, bm.bmHeight, GetLastError());
2021 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2023 for (i = 0; i < 256; i++)
2025 RGBQUAD expect;
2027 if (i < 10 || i >= 246)
2029 int entry = i < 10 ? i : i - 236;
2030 expect.rgbRed = pal_ents[entry].peRed;
2031 expect.rgbGreen = pal_ents[entry].peGreen;
2032 expect.rgbBlue = pal_ents[entry].peBlue;
2034 else
2036 expect.rgbRed = (i & 0x07) << 5;
2037 expect.rgbGreen = (i & 0x38) << 2;
2038 expect.rgbBlue = i & 0xc0;
2040 expect.rgbReserved = 0;
2042 ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
2043 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2044 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2045 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
2046 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
2049 /* retrieve 24-bit DIB data */
2050 memset(bi, 0, sizeof(*bi));
2051 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2052 bi->bmiHeader.biWidth = bm.bmWidth;
2053 bi->bmiHeader.biHeight = bm.bmHeight;
2054 bi->bmiHeader.biPlanes = 1;
2055 bi->bmiHeader.biBitCount = 24;
2056 bi->bmiHeader.biCompression = BI_RGB;
2057 bi->bmiHeader.biSizeImage = 0;
2058 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
2059 memset(buf, 0xAA, sizeof(buf));
2060 SetLastError(0xdeadbeef);
2061 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2062 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2063 lines, bm.bmHeight, GetLastError());
2064 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2066 /* the color table doesn't exist for 24-bit images */
2067 for (i = 0; i < 256; i++)
2069 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
2070 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
2071 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2072 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
2073 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
2076 /* returned bits are DWORD aligned and upside down */
2077 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2078 DeleteObject(hbmp);
2080 ReleaseDC(0, hdc);
2083 static void test_GetDIBits_BI_BITFIELDS(void)
2085 /* Try a screen resolution detection technique
2086 * from the September 1999 issue of Windows Developer's Journal
2087 * which seems to be in widespread use.
2088 * http://www.lesher.ws/highcolor.html
2089 * http://www.lesher.ws/vidfmt.c
2090 * It hinges on being able to retrieve the bitmaps
2091 * for the three primary colors in non-paletted 16 bit mode.
2093 char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
2094 DWORD bits[32];
2095 LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
2096 DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
2097 HDC hdc;
2098 HBITMAP hbm;
2099 int ret;
2100 void *ptr;
2102 memset(dibinfo, 0, sizeof(dibinfo_buf));
2103 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2105 hdc = GetDC(NULL);
2106 ok(hdc != NULL, "GetDC failed?\n");
2107 hbm = CreateCompatibleBitmap(hdc, 1, 1);
2108 ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
2110 /* Call GetDIBits to fill in bmiHeader. */
2111 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2112 ok(ret == 1, "GetDIBits failed\n");
2113 if (dibinfo->bmiHeader.biBitCount > 8)
2115 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2116 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2117 "compression is %u (%d bpp)\n", dibinfo->bmiHeader.biCompression, dibinfo->bmiHeader.biBitCount );
2119 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2121 ok( !bitmasks[0], "red mask is set\n" );
2122 ok( !bitmasks[1], "green mask is set\n" );
2123 ok( !bitmasks[2], "blue mask is set\n" );
2125 /* test with NULL bits pointer and correct bpp */
2126 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2127 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2128 ok(ret == 1, "GetDIBits failed\n");
2130 ok( bitmasks[0] != 0, "red mask is not set\n" );
2131 ok( bitmasks[1] != 0, "green mask is not set\n" );
2132 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2133 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2135 /* test with valid bits pointer */
2136 memset(dibinfo, 0, sizeof(dibinfo_buf));
2137 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2138 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2139 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2140 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2141 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2142 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2144 ok( bitmasks[0] != 0, "red mask is not set\n" );
2145 ok( bitmasks[1] != 0, "green mask is not set\n" );
2146 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2147 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2149 /* now with bits and 0 lines */
2150 memset(dibinfo, 0, sizeof(dibinfo_buf));
2151 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2152 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2153 SetLastError(0xdeadbeef);
2154 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2155 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2157 ok( !bitmasks[0], "red mask is set\n" );
2158 ok( !bitmasks[1], "green mask is set\n" );
2159 ok( !bitmasks[2], "blue mask is set\n" );
2160 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2162 memset(bitmasks, 0, 3*sizeof(DWORD));
2163 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2164 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2165 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2167 ok( bitmasks[0] != 0, "red mask is not set\n" );
2168 ok( bitmasks[1] != 0, "green mask is not set\n" );
2169 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2170 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2173 else skip("bitmap in colortable mode, skipping BI_BITFIELDS tests\n");
2175 DeleteObject(hbm);
2177 /* same thing now with a 32-bpp DIB section */
2179 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2180 dibinfo->bmiHeader.biWidth = 1;
2181 dibinfo->bmiHeader.biHeight = 1;
2182 dibinfo->bmiHeader.biPlanes = 1;
2183 dibinfo->bmiHeader.biBitCount = 32;
2184 dibinfo->bmiHeader.biCompression = BI_RGB;
2185 dibinfo->bmiHeader.biSizeImage = 0;
2186 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2187 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2188 dibinfo->bmiHeader.biClrUsed = 0;
2189 dibinfo->bmiHeader.biClrImportant = 0;
2190 bitmasks[0] = 0x0000ff;
2191 bitmasks[1] = 0x00ff00;
2192 bitmasks[2] = 0xff0000;
2193 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2194 ok( hbm != 0, "failed to create bitmap\n" );
2196 memset(dibinfo, 0, sizeof(dibinfo_buf));
2197 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2198 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2199 ok(ret == 1, "GetDIBits failed\n");
2200 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2202 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2203 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2204 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2205 ok( !bitmasks[0], "red mask is set\n" );
2206 ok( !bitmasks[1], "green mask is set\n" );
2207 ok( !bitmasks[2], "blue mask is set\n" );
2209 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2210 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2211 ok(ret == 1, "GetDIBits failed\n");
2212 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2213 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2214 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2215 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2216 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2218 ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
2219 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2220 ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
2222 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2224 DeleteObject(hbm);
2226 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2227 dibinfo->bmiHeader.biWidth = 1;
2228 dibinfo->bmiHeader.biHeight = 1;
2229 dibinfo->bmiHeader.biPlanes = 1;
2230 dibinfo->bmiHeader.biBitCount = 32;
2231 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2232 dibinfo->bmiHeader.biSizeImage = 0;
2233 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2234 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2235 dibinfo->bmiHeader.biClrUsed = 0;
2236 dibinfo->bmiHeader.biClrImportant = 0;
2237 bitmasks[0] = 0x0000ff;
2238 bitmasks[1] = 0x00ff00;
2239 bitmasks[2] = 0xff0000;
2240 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2241 ok( hbm != 0, "failed to create bitmap\n" );
2243 if (hbm)
2245 memset(dibinfo, 0, sizeof(dibinfo_buf));
2246 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2247 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2248 ok(ret == 1, "GetDIBits failed\n");
2250 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
2251 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2252 ok( !bitmasks[0], "red mask is set\n" );
2253 ok( !bitmasks[1], "green mask is set\n" );
2254 ok( !bitmasks[2], "blue mask is set\n" );
2256 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2257 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2258 ok(ret == 1, "GetDIBits failed\n");
2259 ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
2260 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2261 ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
2262 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2264 DeleteObject(hbm);
2267 /* 24-bpp DIB sections don't have bitfields */
2269 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2270 dibinfo->bmiHeader.biWidth = 1;
2271 dibinfo->bmiHeader.biHeight = 1;
2272 dibinfo->bmiHeader.biPlanes = 1;
2273 dibinfo->bmiHeader.biBitCount = 24;
2274 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2275 dibinfo->bmiHeader.biSizeImage = 0;
2276 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2277 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2278 dibinfo->bmiHeader.biClrUsed = 0;
2279 dibinfo->bmiHeader.biClrImportant = 0;
2280 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2281 ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
2282 dibinfo->bmiHeader.biCompression = BI_RGB;
2283 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2284 ok( hbm != 0, "failed to create bitmap\n" );
2286 memset(dibinfo, 0, sizeof(dibinfo_buf));
2287 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2288 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2289 ok(ret == 1, "GetDIBits failed\n");
2290 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2292 ok( dibinfo->bmiHeader.biCompression == BI_RGB,
2293 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2294 ok( !bitmasks[0], "red mask is set\n" );
2295 ok( !bitmasks[1], "green mask is set\n" );
2296 ok( !bitmasks[2], "blue mask is set\n" );
2298 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2299 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2300 ok(ret == 1, "GetDIBits failed\n");
2301 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2302 ok( !bitmasks[0], "red mask is set\n" );
2303 ok( !bitmasks[1], "green mask is set\n" );
2304 ok( !bitmasks[2], "blue mask is set\n" );
2305 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2307 DeleteObject(hbm);
2308 ReleaseDC(NULL, hdc);
2311 static void test_select_object(void)
2313 HDC hdc;
2314 HBITMAP hbm, hbm_old;
2315 INT planes, bpp, i;
2316 DWORD depths[] = {8, 15, 16, 24, 32};
2317 BITMAP bm;
2318 DWORD bytes;
2320 hdc = GetDC(0);
2321 ok(hdc != 0, "GetDC(0) failed\n");
2322 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2323 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2325 hbm_old = SelectObject(hdc, hbm);
2326 ok(hbm_old == 0, "SelectObject should fail\n");
2328 DeleteObject(hbm);
2329 ReleaseDC(0, hdc);
2331 hdc = CreateCompatibleDC(0);
2332 ok(hdc != 0, "GetDC(0) failed\n");
2333 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2334 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2336 hbm_old = SelectObject(hdc, hbm);
2337 ok(hbm_old != 0, "SelectObject failed\n");
2338 hbm_old = SelectObject(hdc, hbm_old);
2339 ok(hbm_old == hbm, "SelectObject failed\n");
2341 DeleteObject(hbm);
2343 /* test an 1-bpp bitmap */
2344 planes = GetDeviceCaps(hdc, PLANES);
2345 bpp = 1;
2347 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
2348 ok(hbm != 0, "CreateBitmap failed\n");
2350 hbm_old = SelectObject(hdc, hbm);
2351 ok(hbm_old != 0, "SelectObject failed\n");
2352 hbm_old = SelectObject(hdc, hbm_old);
2353 ok(hbm_old == hbm, "SelectObject failed\n");
2355 DeleteObject(hbm);
2357 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
2358 /* test a color bitmap to dc bpp matching */
2359 planes = GetDeviceCaps(hdc, PLANES);
2360 bpp = GetDeviceCaps(hdc, BITSPIXEL);
2362 hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
2363 ok(hbm != 0, "CreateBitmap failed\n");
2365 hbm_old = SelectObject(hdc, hbm);
2366 if(depths[i] == bpp ||
2367 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
2369 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
2370 SelectObject(hdc, hbm_old);
2371 } else {
2372 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
2375 memset(&bm, 0xAA, sizeof(bm));
2376 bytes = GetObject(hbm, sizeof(bm), &bm);
2377 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2378 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2379 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
2380 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
2381 ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2382 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
2383 if(depths[i] == 15) {
2384 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
2385 } else {
2386 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2388 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2390 DeleteObject(hbm);
2393 DeleteDC(hdc);
2396 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
2398 INT ret;
2399 BITMAP bm;
2401 ret = GetObjectType(hbmp);
2402 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
2404 ret = GetObject(hbmp, 0, 0);
2405 ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
2407 memset(&bm, 0xDA, sizeof(bm));
2408 SetLastError(0xdeadbeef);
2409 ret = GetObject(hbmp, sizeof(bm), &bm);
2410 if (!ret) /* XP, only for curObj2 */ return;
2411 ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
2412 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2413 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2414 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2415 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2416 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2417 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2418 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2421 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2423 static void test_CreateBitmap(void)
2425 BITMAP bmp;
2426 HDC screenDC = GetDC(0);
2427 HDC hdc = CreateCompatibleDC(screenDC);
2428 UINT i, expect = 0;
2430 /* all of these are the stock monochrome bitmap */
2431 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2432 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2433 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2434 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2435 HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2436 HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2438 /* these 2 are not the stock monochrome bitmap */
2439 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2440 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2442 HBITMAP old1 = SelectObject(hdc, bm2);
2443 HBITMAP old2 = SelectObject(screenDC, bm3);
2444 SelectObject(hdc, old1);
2445 SelectObject(screenDC, old2);
2447 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2448 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2449 bm, bm1, bm4, bm5, curObj1, old1);
2450 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2451 todo_wine
2452 ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
2453 ok(old2 == 0, "old2 %p\n", old2);
2455 test_mono_1x1_bmp(bm);
2456 test_mono_1x1_bmp(bm1);
2457 test_mono_1x1_bmp(bm2);
2458 test_mono_1x1_bmp(bm3);
2459 test_mono_1x1_bmp(bm4);
2460 test_mono_1x1_bmp(bm5);
2461 test_mono_1x1_bmp(old1);
2462 test_mono_1x1_bmp(curObj1);
2464 DeleteObject(bm);
2465 DeleteObject(bm1);
2466 DeleteObject(bm2);
2467 DeleteObject(bm3);
2468 DeleteObject(bm4);
2469 DeleteObject(bm5);
2471 DeleteDC(hdc);
2472 ReleaseDC(0, screenDC);
2474 /* show that Windows ignores the provided bm.bmWidthBytes */
2475 bmp.bmType = 0;
2476 bmp.bmWidth = 1;
2477 bmp.bmHeight = 1;
2478 bmp.bmWidthBytes = 28;
2479 bmp.bmPlanes = 1;
2480 bmp.bmBitsPixel = 1;
2481 bmp.bmBits = NULL;
2482 bm = CreateBitmapIndirect(&bmp);
2483 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2484 test_mono_1x1_bmp(bm);
2485 DeleteObject(bm);
2487 /* Test how the bmBitsPixel field is treated */
2488 for(i = 1; i <= 33; i++) {
2489 bmp.bmType = 0;
2490 bmp.bmWidth = 1;
2491 bmp.bmHeight = 1;
2492 bmp.bmWidthBytes = 28;
2493 bmp.bmPlanes = 1;
2494 bmp.bmBitsPixel = i;
2495 bmp.bmBits = NULL;
2496 SetLastError(0xdeadbeef);
2497 bm = CreateBitmapIndirect(&bmp);
2498 if(i > 32) {
2499 DWORD error = GetLastError();
2500 ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
2501 ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2502 DeleteObject(bm);
2503 continue;
2505 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2506 GetObject(bm, sizeof(bmp), &bmp);
2507 if(i == 1) {
2508 expect = 1;
2509 } else if(i <= 4) {
2510 expect = 4;
2511 } else if(i <= 8) {
2512 expect = 8;
2513 } else if(i <= 16) {
2514 expect = 16;
2515 } else if(i <= 24) {
2516 expect = 24;
2517 } else if(i <= 32) {
2518 expect = 32;
2520 ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2521 i, bmp.bmBitsPixel, expect);
2522 DeleteObject(bm);
2526 static void test_bitmapinfoheadersize(void)
2528 HBITMAP hdib;
2529 BITMAPINFO bmi;
2530 BITMAPCOREINFO bci;
2531 HDC hdc = GetDC(0);
2533 memset(&bmi, 0, sizeof(BITMAPINFO));
2534 bmi.bmiHeader.biHeight = 100;
2535 bmi.bmiHeader.biWidth = 512;
2536 bmi.bmiHeader.biBitCount = 24;
2537 bmi.bmiHeader.biPlanes = 1;
2539 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2541 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2542 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2544 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2546 SetLastError(0xdeadbeef);
2547 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2548 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2549 DeleteObject(hdib);
2551 bmi.bmiHeader.biSize++;
2553 SetLastError(0xdeadbeef);
2554 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2555 ok(hdib != NULL ||
2556 broken(!hdib), /* Win98, WinMe */
2557 "CreateDIBSection error %d\n", GetLastError());
2558 DeleteObject(hdib);
2560 bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2562 SetLastError(0xdeadbeef);
2563 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2564 ok(hdib != NULL ||
2565 broken(!hdib), /* Win98, WinMe */
2566 "CreateDIBSection error %d\n", GetLastError());
2567 DeleteObject(hdib);
2569 bmi.bmiHeader.biSize++;
2571 SetLastError(0xdeadbeef);
2572 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2573 ok(hdib != NULL ||
2574 broken(!hdib), /* Win98, WinMe */
2575 "CreateDIBSection error %d\n", GetLastError());
2576 DeleteObject(hdib);
2578 bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2580 SetLastError(0xdeadbeef);
2581 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2582 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2583 DeleteObject(hdib);
2585 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2587 SetLastError(0xdeadbeef);
2588 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2589 ok(hdib != NULL ||
2590 broken(!hdib), /* Win95 */
2591 "CreateDIBSection error %d\n", GetLastError());
2592 DeleteObject(hdib);
2594 memset(&bci, 0, sizeof(BITMAPCOREINFO));
2595 bci.bmciHeader.bcHeight = 100;
2596 bci.bmciHeader.bcWidth = 512;
2597 bci.bmciHeader.bcBitCount = 24;
2598 bci.bmciHeader.bcPlanes = 1;
2600 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2602 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2603 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2605 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2607 SetLastError(0xdeadbeef);
2608 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2609 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2610 DeleteObject(hdib);
2612 bci.bmciHeader.bcSize++;
2614 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2615 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2617 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2619 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2620 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2622 ReleaseDC(0, hdc);
2625 static void test_get16dibits(void)
2627 BYTE bits[4 * (16 / sizeof(BYTE))];
2628 HBITMAP hbmp;
2629 HDC screen_dc = GetDC(NULL);
2630 int ret;
2631 BITMAPINFO * info;
2632 int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2633 BYTE *p;
2634 int overwritten_bytes = 0;
2636 memset(bits, 0, sizeof(bits));
2637 hbmp = CreateBitmap(2, 2, 1, 16, bits);
2638 ok(hbmp != NULL, "CreateBitmap failed\n");
2640 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2641 assert(info);
2643 memset(info, '!', info_len);
2644 memset(info, 0, sizeof(info->bmiHeader));
2646 info->bmiHeader.biSize = sizeof(info->bmiHeader);
2647 info->bmiHeader.biWidth = 2;
2648 info->bmiHeader.biHeight = 2;
2649 info->bmiHeader.biPlanes = 1;
2650 info->bmiHeader.biCompression = BI_RGB;
2652 ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2653 ok(ret != 0, "GetDIBits failed got %d\n", ret);
2655 for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2656 if (*p != '!')
2657 overwritten_bytes++;
2658 ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2660 HeapFree(GetProcessHeap(), 0, info);
2661 DeleteObject(hbmp);
2662 ReleaseDC(NULL, screen_dc);
2665 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2666 DWORD dwRop, UINT32 expected, int line)
2668 *srcBuffer = 0xFEDCBA98;
2669 *dstBuffer = 0x89ABCDEF;
2670 Rectangle(hdcSrc, 0, 0, 1, 1); /* A null operation to ensure dibs are coerced to X11 */
2671 BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
2672 ok(expected == *dstBuffer,
2673 "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2674 dwRop, expected, *dstBuffer, line);
2677 static void test_BitBlt(void)
2679 HBITMAP bmpDst, bmpSrc;
2680 HBITMAP oldDst, oldSrc;
2681 HDC hdcScreen, hdcDst, hdcSrc;
2682 UINT32 *dstBuffer, *srcBuffer;
2683 HBRUSH hBrush, hOldBrush;
2684 BITMAPINFO bitmapInfo;
2686 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2687 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2688 bitmapInfo.bmiHeader.biWidth = 1;
2689 bitmapInfo.bmiHeader.biHeight = 1;
2690 bitmapInfo.bmiHeader.biPlanes = 1;
2691 bitmapInfo.bmiHeader.biBitCount = 32;
2692 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2693 bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2695 hdcScreen = CreateCompatibleDC(0);
2696 hdcDst = CreateCompatibleDC(hdcScreen);
2697 hdcSrc = CreateCompatibleDC(hdcDst);
2699 /* Setup the destination dib section */
2700 bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
2701 NULL, 0);
2702 oldDst = SelectObject(hdcDst, bmpDst);
2704 hBrush = CreateSolidBrush(0x012345678);
2705 hOldBrush = SelectObject(hdcDst, hBrush);
2707 /* Setup the source dib section */
2708 bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
2709 NULL, 0);
2710 oldSrc = SelectObject(hdcSrc, bmpSrc);
2712 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2713 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2714 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2715 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2716 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2717 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2718 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2719 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2720 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2721 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2722 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2723 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2724 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2725 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2726 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2728 /* Tidy up */
2729 SelectObject(hdcSrc, oldSrc);
2730 DeleteObject(bmpSrc);
2731 DeleteDC(hdcSrc);
2733 SelectObject(hdcDst, hOldBrush);
2734 DeleteObject(hBrush);
2735 SelectObject(hdcDst, oldDst);
2736 DeleteObject(bmpDst);
2737 DeleteDC(hdcDst);
2740 DeleteDC(hdcScreen);
2743 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2744 DWORD dwRop, UINT32 expected, int line)
2746 *srcBuffer = 0xFEDCBA98;
2747 *dstBuffer = 0x89ABCDEF;
2748 StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
2749 ok(expected == *dstBuffer,
2750 "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2751 dwRop, expected, *dstBuffer, line);
2754 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2755 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2756 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2757 UINT32 expected[4], int line)
2759 memset(dstBuffer, 0, 16);
2760 StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2761 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
2762 ok(memcmp(dstBuffer, expected, 16) == 0,
2763 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2764 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2765 expected[0], expected[1], expected[2], expected[3],
2766 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2767 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2768 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2771 static void test_StretchBlt(void)
2773 HBITMAP bmpDst, bmpSrc;
2774 HBITMAP oldDst, oldSrc;
2775 HDC hdcScreen, hdcDst, hdcSrc;
2776 UINT32 *dstBuffer, *srcBuffer;
2777 HBRUSH hBrush, hOldBrush;
2778 BITMAPINFO biDst, biSrc;
2779 UINT32 expected[4];
2781 memset(&biDst, 0, sizeof(BITMAPINFO));
2782 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2783 biDst.bmiHeader.biWidth = 2;
2784 biDst.bmiHeader.biHeight = -2;
2785 biDst.bmiHeader.biPlanes = 1;
2786 biDst.bmiHeader.biBitCount = 32;
2787 biDst.bmiHeader.biCompression = BI_RGB;
2788 memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
2790 hdcScreen = CreateCompatibleDC(0);
2791 hdcDst = CreateCompatibleDC(hdcScreen);
2792 hdcSrc = CreateCompatibleDC(hdcDst);
2794 /* Pixel Tests */
2795 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2796 NULL, 0);
2797 oldDst = SelectObject(hdcDst, bmpDst);
2799 bmpSrc = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&srcBuffer,
2800 NULL, 0);
2801 oldSrc = SelectObject(hdcSrc, bmpSrc);
2803 hBrush = CreateSolidBrush(0x012345678);
2804 hOldBrush = SelectObject(hdcDst, hBrush);
2806 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2807 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2808 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2809 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2810 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2811 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2812 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2813 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2814 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2815 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2816 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2817 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2818 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2819 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2820 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2822 SelectObject(hdcDst, hOldBrush);
2823 DeleteObject(hBrush);
2825 /* Top-down to top-down tests */
2826 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2827 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
2829 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2830 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2831 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2832 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2834 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2835 expected[2] = 0x00000000, expected[3] = 0x00000000;
2836 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2837 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
2839 expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
2840 expected[2] = 0xCAFED00D, expected[3] = 0xCAFED00D;
2841 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2842 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
2844 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2845 expected[2] = 0x00000000, expected[3] = 0x00000000;
2846 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2847 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
2849 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2850 expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2851 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2852 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2854 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2855 expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2856 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2857 1, 1, -2, -2, 0, 0, 2, 2, expected, __LINE__);
2859 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2860 expected[2] = 0x00000000, expected[3] = 0x00000000;
2861 todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2862 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
2864 expected[0] = 0x00000000, expected[1] = 0x00000000;
2865 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
2866 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2867 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2869 SelectObject(hdcDst, oldDst);
2870 DeleteObject(bmpDst);
2872 /* Top-down to bottom-up tests */
2873 biDst.bmiHeader.biHeight = 2;
2874 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2875 NULL, 0);
2876 oldDst = SelectObject(hdcDst, bmpDst);
2878 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2879 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
2880 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2881 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2883 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2884 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2885 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2886 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2888 SelectObject(hdcSrc, oldSrc);
2889 DeleteObject(bmpSrc);
2891 /* Bottom-up to bottom-up tests */
2892 biSrc.bmiHeader.biHeight = 2;
2893 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2894 NULL, 0);
2895 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2896 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
2897 oldSrc = SelectObject(hdcSrc, bmpSrc);
2899 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2900 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2901 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2902 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2904 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2905 expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2906 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2907 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2909 SelectObject(hdcDst, oldDst);
2910 DeleteObject(bmpDst);
2912 /* Bottom-up to top-down tests */
2913 biDst.bmiHeader.biHeight = -2;
2914 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2915 NULL, 0);
2916 oldDst = SelectObject(hdcDst, bmpDst);
2918 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2919 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
2920 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2921 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2923 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2924 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2925 check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2926 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2928 SelectObject(hdcSrc, oldSrc);
2929 DeleteObject(bmpSrc);
2931 biSrc.bmiHeader.biHeight = -2;
2932 biSrc.bmiHeader.biBitCount = 24;
2933 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
2934 oldSrc = SelectObject(hdcSrc, bmpSrc);
2936 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2937 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2938 memcpy(dstBuffer, expected, 4 * sizeof(*dstBuffer));
2939 StretchBlt(hdcSrc, 0, 0, 2, 2, hdcDst, 0, 0, 2, 2, SRCCOPY );
2940 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
2941 StretchBlt(hdcDst, 0, 0, 2, 2, hdcSrc, 0, 0, 2, 2, SRCCOPY );
2942 expected[0] = 0x00EDFACE, expected[1] = 0x00FED00D;
2943 expected[2] = 0x00543210, expected[3] = 0x00DCBA98;
2944 ok(!memcmp(dstBuffer, expected, 16),
2945 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
2946 expected[0], expected[1], expected[2], expected[3],
2947 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
2949 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2950 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2951 memcpy(srcBuffer, expected, 4 * sizeof(*dstBuffer));
2952 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
2953 StretchBlt(hdcDst, 0, 0, 2, 2, hdcSrc, 0, 0, 2, 2, SRCCOPY );
2954 expected[0] = 0x00EDFACE, expected[1] = 0x00D00DFE;
2955 expected[2] = 0x00543210, expected[3] = 0x00BA9876;
2956 ok(!memcmp(dstBuffer, expected, 16),
2957 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
2958 expected[0], expected[1], expected[2], expected[3],
2959 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
2961 SelectObject(hdcSrc, oldSrc);
2962 DeleteObject(bmpSrc);
2963 DeleteDC(hdcSrc);
2965 SelectObject(hdcDst, oldDst);
2966 DeleteObject(bmpDst);
2967 DeleteDC(hdcDst);
2969 DeleteDC(hdcScreen);
2972 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
2973 DWORD dwRop, UINT32 expected, int line)
2975 const UINT32 buffer[2] = { 0xFEDCBA98, 0 };
2976 BITMAPINFO bitmapInfo;
2978 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2979 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2980 bitmapInfo.bmiHeader.biWidth = 2;
2981 bitmapInfo.bmiHeader.biHeight = 1;
2982 bitmapInfo.bmiHeader.biPlanes = 1;
2983 bitmapInfo.bmiHeader.biBitCount = 32;
2984 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2985 bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer);
2987 *dstBuffer = 0x89ABCDEF;
2989 StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop);
2990 ok(expected == *dstBuffer,
2991 "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2992 dwRop, expected, *dstBuffer, line);
2995 static void check_StretchDIBits_stretch(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
2996 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2997 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2998 UINT32 expected[4], UINT32 legacy_expected[4], int line)
3000 BITMAPINFO bitmapInfo;
3002 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3003 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3004 bitmapInfo.bmiHeader.biWidth = 2;
3005 bitmapInfo.bmiHeader.biHeight = -2;
3006 bitmapInfo.bmiHeader.biPlanes = 1;
3007 bitmapInfo.bmiHeader.biBitCount = 32;
3008 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3010 memset(dstBuffer, 0, 16);
3011 StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
3012 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3013 srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
3014 ok(memcmp(dstBuffer, expected, 16) == 0,
3015 "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
3016 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
3017 expected[0], expected[1], expected[2], expected[3],
3018 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
3019 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3020 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
3023 static void test_StretchDIBits(void)
3025 HBITMAP bmpDst;
3026 HBITMAP oldDst;
3027 HDC hdcScreen, hdcDst;
3028 UINT32 *dstBuffer, srcBuffer[4];
3029 HBRUSH hBrush, hOldBrush;
3030 BITMAPINFO biDst;
3031 UINT32 expected[4], legacy_expected[4];
3033 memset(&biDst, 0, sizeof(BITMAPINFO));
3034 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3035 biDst.bmiHeader.biWidth = 2;
3036 biDst.bmiHeader.biHeight = -2;
3037 biDst.bmiHeader.biPlanes = 1;
3038 biDst.bmiHeader.biBitCount = 32;
3039 biDst.bmiHeader.biCompression = BI_RGB;
3041 hdcScreen = CreateCompatibleDC(0);
3042 hdcDst = CreateCompatibleDC(hdcScreen);
3044 /* Pixel Tests */
3045 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3046 NULL, 0);
3047 oldDst = SelectObject(hdcDst, bmpDst);
3049 hBrush = CreateSolidBrush(0x012345678);
3050 hOldBrush = SelectObject(hdcDst, hBrush);
3052 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3053 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3054 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3055 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3056 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3057 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3058 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3059 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3060 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3061 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3062 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3063 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3064 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3065 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3066 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3068 SelectObject(hdcDst, hOldBrush);
3069 DeleteObject(hBrush);
3071 /* Top-down destination tests */
3072 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3073 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
3075 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
3076 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
3077 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3078 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
3080 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3081 expected[2] = 0x00000000, expected[3] = 0x00000000;
3082 legacy_expected[0] = 0xFEDCBA98, legacy_expected[1] = 0x00000000;
3083 legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
3084 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3085 0, 0, 1, 1, 0, 0, 1, 1, expected, legacy_expected, __LINE__);
3087 expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
3088 expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
3089 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3090 0, 0, 2, 2, 0, 0, 1, 1, expected, expected, __LINE__);
3092 expected[0] = 0x42441000, expected[1] = 0x00000000;
3093 expected[2] = 0x00000000, expected[3] = 0x00000000;
3094 legacy_expected[0] = 0x00543210, legacy_expected[1] = 0x00000000;
3095 legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
3096 todo_wine check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3097 0, 0, 1, 1, 0, 0, 2, 2, expected, legacy_expected, __LINE__);
3099 expected[0] = 0x00000000, expected[1] = 0x00000000;
3100 expected[2] = 0x00000000, expected[3] = 0x00000000;
3101 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3102 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
3104 expected[0] = 0x00000000, expected[1] = 0x00000000;
3105 expected[2] = 0x00000000, expected[3] = 0x00000000;
3106 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3107 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
3109 expected[0] = 0x00000000, expected[1] = 0x00000000;
3110 expected[2] = 0x00000000, expected[3] = 0x00000000;
3111 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3112 1, 1, -2, -2, 1, 1, -2, -2, expected, expected, __LINE__);
3114 expected[0] = 0x00000000, expected[1] = 0x00000000;
3115 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
3116 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3117 1, 1, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
3119 SelectObject(hdcDst, oldDst);
3120 DeleteObject(bmpDst);
3122 /* Bottom up destination tests */
3123 biDst.bmiHeader.biHeight = 2;
3124 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3125 NULL, 0);
3126 oldDst = SelectObject(hdcDst, bmpDst);
3128 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3129 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
3130 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3131 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
3133 /* Tidy up */
3134 SelectObject(hdcDst, oldDst);
3135 DeleteObject(bmpDst);
3136 DeleteDC(hdcDst);
3138 DeleteDC(hdcScreen);
3141 static void test_GdiAlphaBlend(void)
3143 /* test out-of-bound parameters for GdiAlphaBlend */
3144 HDC hdcNull;
3146 HDC hdcDst;
3147 HBITMAP bmpDst;
3148 HBITMAP oldDst;
3150 BITMAPINFO bmi;
3151 HDC hdcSrc;
3152 HBITMAP bmpSrc;
3153 HBITMAP oldSrc;
3154 LPVOID bits;
3156 BLENDFUNCTION blend;
3158 if (!pGdiAlphaBlend)
3160 win_skip("GdiAlphaBlend() is not implemented\n");
3161 return;
3164 hdcNull = GetDC(NULL);
3165 hdcDst = CreateCompatibleDC(hdcNull);
3166 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
3167 hdcSrc = CreateCompatibleDC(hdcNull);
3169 memset(&bmi, 0, sizeof(bmi)); /* as of Wine 0.9.44 we require the src to be a DIB section */
3170 bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
3171 bmi.bmiHeader.biHeight = 20;
3172 bmi.bmiHeader.biWidth = 20;
3173 bmi.bmiHeader.biBitCount = 32;
3174 bmi.bmiHeader.biPlanes = 1;
3175 bmi.bmiHeader.biCompression = BI_RGB;
3176 bmpSrc = CreateDIBSection(hdcDst, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3177 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3179 oldDst = SelectObject(hdcDst, bmpDst);
3180 oldSrc = SelectObject(hdcSrc, bmpSrc);
3182 blend.BlendOp = AC_SRC_OVER;
3183 blend.BlendFlags = 0;
3184 blend.SourceConstantAlpha = 128;
3185 blend.AlphaFormat = 0;
3187 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend), TRUE, BOOL, "%d");
3188 SetLastError(0xdeadbeef);
3189 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), FALSE, BOOL, "%d");
3190 expect_eq(GetLastError(), ERROR_INVALID_PARAMETER, int, "%d");
3191 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), FALSE, BOOL, "%d");
3192 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend), FALSE, BOOL, "%d");
3193 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
3194 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
3196 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
3197 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), TRUE, BOOL, "%d");
3198 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), TRUE, BOOL, "%d");
3199 SetMapMode(hdcSrc, MM_ANISOTROPIC);
3200 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
3201 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend), TRUE, BOOL, "%d");
3202 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend), TRUE, BOOL, "%d");
3204 SetLastError(0xdeadbeef);
3205 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend), FALSE, BOOL, "%d");
3206 expect_eq(GetLastError(), 0xdeadbeef, int, "%d");
3208 SelectObject(hdcDst, oldDst);
3209 SelectObject(hdcSrc, oldSrc);
3210 DeleteObject(bmpSrc);
3211 DeleteObject(bmpDst);
3212 DeleteDC(hdcDst);
3213 DeleteDC(hdcSrc);
3215 ReleaseDC(NULL, hdcNull);
3219 static void test_clipping(void)
3221 HBITMAP bmpDst;
3222 HBITMAP bmpSrc;
3223 HRGN hRgn;
3224 LPVOID bits;
3225 BOOL result;
3227 HDC hdcDst = CreateCompatibleDC( NULL );
3228 HDC hdcSrc = CreateCompatibleDC( NULL );
3230 BITMAPINFO bmpinfo={{0}};
3231 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3232 bmpinfo.bmiHeader.biWidth = 100;
3233 bmpinfo.bmiHeader.biHeight = 100;
3234 bmpinfo.bmiHeader.biPlanes = 1;
3235 bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3236 bmpinfo.bmiHeader.biCompression = BI_RGB;
3238 bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3239 ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3240 SelectObject( hdcDst, bmpDst );
3242 bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3243 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3244 SelectObject( hdcSrc, bmpSrc );
3246 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3247 ok(result, "BitBlt failed\n");
3249 hRgn = CreateRectRgn( 0,0,0,0 );
3250 SelectClipRgn( hdcDst, hRgn );
3252 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3253 ok(result, "BitBlt failed\n");
3255 DeleteObject( bmpDst );
3256 DeleteObject( bmpSrc );
3257 DeleteObject( hRgn );
3258 DeleteDC( hdcDst );
3259 DeleteDC( hdcSrc );
3262 static void test_32bit_bitmap_blt(void)
3264 BITMAPINFO biDst;
3265 HBITMAP bmpSrc, bmpDst;
3266 HBITMAP oldSrc, oldDst;
3267 HDC hdcSrc, hdcDst, hdcScreen;
3268 UINT32 *dstBuffer;
3269 DWORD colorSrc = 0x11223344;
3271 memset(&biDst, 0, sizeof(BITMAPINFO));
3272 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3273 biDst.bmiHeader.biWidth = 2;
3274 biDst.bmiHeader.biHeight = -2;
3275 biDst.bmiHeader.biPlanes = 1;
3276 biDst.bmiHeader.biBitCount = 32;
3277 biDst.bmiHeader.biCompression = BI_RGB;
3279 hdcScreen = CreateCompatibleDC(0);
3280 if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3282 DeleteDC(hdcScreen);
3283 trace("Skipping 32-bit DDB test\n");
3284 return;
3287 hdcSrc = CreateCompatibleDC(hdcScreen);
3288 bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3289 oldSrc = SelectObject(hdcSrc, bmpSrc);
3291 hdcDst = CreateCompatibleDC(hdcScreen);
3292 bmpDst = CreateDIBSection(hdcDst, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3293 oldDst = SelectObject(hdcDst, bmpDst);
3295 StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3296 ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3298 /* Tidy up */
3299 SelectObject(hdcDst, oldDst);
3300 DeleteObject(bmpDst);
3301 DeleteDC(hdcDst);
3303 SelectObject(hdcSrc, oldSrc);
3304 DeleteObject(bmpSrc);
3305 DeleteDC(hdcSrc);
3307 DeleteDC(hdcScreen);
3311 * Used by test_GetDIBits_top_down to create the bitmap to test against.
3313 static void setup_picture(char *picture, int bpp)
3315 int i;
3317 switch(bpp)
3319 case 16:
3320 case 32:
3321 /*Set the first byte in each pixel to the index of that pixel.*/
3322 for (i = 0; i < 4; i++)
3323 picture[i * (bpp / 8)] = i;
3324 break;
3325 case 24:
3326 picture[0] = 0;
3327 picture[3] = 1;
3328 /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
3329 picture[8] = 2;
3330 picture[11] = 3;
3331 break;
3335 static void test_GetDIBits_top_down(int bpp)
3337 BITMAPINFO bi;
3338 HBITMAP bmptb, bmpbt;
3339 HDC hdc;
3340 int pictureOut[4];
3341 int *picture;
3342 int statusCode;
3344 memset( &bi, 0, sizeof(bi) );
3345 bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
3346 bi.bmiHeader.biWidth=2;
3347 bi.bmiHeader.biHeight=2;
3348 bi.bmiHeader.biPlanes=1;
3349 bi.bmiHeader.biBitCount=bpp;
3350 bi.bmiHeader.biCompression=BI_RGB;
3352 /*Get the device context for the screen.*/
3353 hdc = GetDC(NULL);
3354 ok(hdc != NULL, "Could not get a handle to a device context.\n");
3356 /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
3357 bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3358 ok(bmpbt != NULL, "Could not create a DIB section.\n");
3359 /*Now that we have a pointer to the pixels, we write to them.*/
3360 setup_picture((char*)picture, bpp);
3361 /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
3362 bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
3363 bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3364 ok(bmptb != NULL, "Could not create a DIB section.\n");
3365 /*Write to this top to bottom bitmap.*/
3366 setup_picture((char*)picture, bpp);
3368 bi.bmiHeader.biWidth = 1;
3370 bi.bmiHeader.biHeight = 2;
3371 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3372 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3373 /*Check the first byte of the pixel.*/
3374 ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3375 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3376 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3377 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3378 /*Check second scanline.*/
3379 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3380 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3381 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3382 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3383 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3384 ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3385 /*Check both scanlines.*/
3386 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3387 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3388 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3389 ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3390 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3391 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3392 ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3393 ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3395 /*Make destination bitmap top-down.*/
3396 bi.bmiHeader.biHeight = -2;
3397 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3398 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3399 ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3400 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3401 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3402 ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3403 /*Check second scanline.*/
3404 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3405 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3406 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3407 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3408 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3409 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3410 /*Check both scanlines.*/
3411 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3412 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3413 ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3414 ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3415 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3416 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3417 ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3418 ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3420 DeleteObject(bmpbt);
3421 DeleteObject(bmptb);
3424 static void test_GetSetDIBits_rtl(void)
3426 HDC hdc, hdc_mem;
3427 HBITMAP bitmap, orig_bitmap;
3428 BITMAPINFO info;
3429 int ret;
3430 DWORD bits_1[8 * 8], bits_2[8 * 8];
3432 if(!pSetLayout)
3434 win_skip("Don't have SetLayout\n");
3435 return;
3438 hdc = GetDC( NULL );
3439 hdc_mem = CreateCompatibleDC( hdc );
3440 pSetLayout( hdc_mem, LAYOUT_LTR );
3442 bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
3443 orig_bitmap = SelectObject( hdc_mem, bitmap );
3444 SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
3445 SelectObject( hdc_mem, orig_bitmap );
3447 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3448 info.bmiHeader.biWidth = 8;
3449 info.bmiHeader.biHeight = 8;
3450 info.bmiHeader.biPlanes = 1;
3451 info.bmiHeader.biBitCount = 32;
3452 info.bmiHeader.biCompression = BI_RGB;
3454 /* First show that GetDIBits ignores the layout mode. */
3456 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3457 ok(ret == 8, "got %d\n", ret);
3458 ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
3460 pSetLayout( hdc_mem, LAYOUT_RTL );
3462 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3463 ok(ret == 8, "got %d\n", ret);
3465 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3467 /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
3468 followed by a GetDIBits and show that the bits remain unchanged. */
3470 pSetLayout( hdc_mem, LAYOUT_LTR );
3472 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3473 ok(ret == 8, "got %d\n", ret);
3474 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3475 ok(ret == 8, "got %d\n", ret);
3476 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3478 pSetLayout( hdc_mem, LAYOUT_RTL );
3480 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3481 ok(ret == 8, "got %d\n", ret);
3482 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3483 ok(ret == 8, "got %d\n", ret);
3484 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3486 DeleteObject( bitmap );
3487 DeleteDC( hdc_mem );
3488 ReleaseDC( NULL, hdc );
3491 static void test_GetDIBits_scanlines(void)
3493 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3494 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3495 DWORD *dib_bits;
3496 HDC hdc = GetDC( NULL );
3497 HBITMAP dib;
3498 DWORD data[128], inverted_bits[64];
3499 int i, ret;
3501 memset( info, 0, sizeof(bmi_buf) );
3503 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3504 info->bmiHeader.biWidth = 8;
3505 info->bmiHeader.biHeight = 8;
3506 info->bmiHeader.biPlanes = 1;
3507 info->bmiHeader.biBitCount = 32;
3508 info->bmiHeader.biCompression = BI_RGB;
3510 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3512 for (i = 0; i < 64; i++)
3514 dib_bits[i] = i;
3515 inverted_bits[56 - (i & ~7) + (i & 7)] = i;
3518 /* b-u -> b-u */
3520 memset( data, 0xaa, sizeof(data) );
3522 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3523 ok( ret == 8, "got %d\n", ret );
3524 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3525 memset( data, 0xaa, sizeof(data) );
3527 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3528 ok( ret == 5, "got %d\n", ret );
3529 ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
3530 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3531 memset( data, 0xaa, sizeof(data) );
3533 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3534 ok( ret == 7, "got %d\n", ret );
3535 ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
3536 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3537 memset( data, 0xaa, sizeof(data) );
3539 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3540 ok( ret == 1, "got %d\n", ret );
3541 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3542 memset( data, 0xaa, sizeof(data) );
3544 info->bmiHeader.biHeight = 16;
3545 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3546 ok( ret == 5, "got %d\n", ret );
3547 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3548 ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
3549 for (i = 96; 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, 2, 12, data, info, DIB_RGB_COLORS );
3553 ok( ret == 6, "got %d\n", ret );
3554 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3555 ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
3556 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3557 memset( data, 0xaa, sizeof(data) );
3559 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3560 ok( ret == 0, "got %d\n", ret );
3561 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3562 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3563 memset( data, 0xaa, sizeof(data) );
3565 info->bmiHeader.biHeight = 5;
3566 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3567 ok( ret == 2, "got %d\n", ret );
3568 ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
3569 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3570 memset( data, 0xaa, sizeof(data) );
3572 /* b-u -> t-d */
3574 info->bmiHeader.biHeight = -8;
3575 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3576 ok( ret == 8, "got %d\n", ret );
3577 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3578 memset( data, 0xaa, sizeof(data) );
3580 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3581 ok( ret == 5, "got %d\n", ret );
3582 ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
3583 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3584 memset( data, 0xaa, sizeof(data) );
3586 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3587 ok( ret == 7, "got %d\n", ret );
3588 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3589 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3590 memset( data, 0xaa, sizeof(data) );
3592 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3593 ok( ret == 4, "got %d\n", ret );
3594 ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
3595 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3596 memset( data, 0xaa, sizeof(data) );
3598 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3599 ok( ret == 5, "got %d\n", ret );
3600 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3601 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3602 memset( data, 0xaa, sizeof(data) );
3604 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3605 ok( ret == 5, "got %d\n", ret );
3606 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3607 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3608 memset( data, 0xaa, sizeof(data) );
3610 info->bmiHeader.biHeight = -16;
3611 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3612 ok( ret == 8, "got %d\n", ret );
3613 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3614 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3615 memset( data, 0xaa, sizeof(data) );
3617 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3618 ok( ret == 5, "got %d\n", ret );
3619 ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
3620 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3621 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3622 memset( data, 0xaa, sizeof(data) );
3624 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3625 ok( ret == 8, "got %d\n", ret );
3626 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3627 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3628 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3629 memset( data, 0xaa, sizeof(data) );
3631 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3632 ok( ret == 8, "got %d\n", ret );
3633 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3634 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3635 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3636 memset( data, 0xaa, sizeof(data) );
3638 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3639 ok( ret == 7, "got %d\n", ret );
3640 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3641 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3642 memset( data, 0xaa, sizeof(data) );
3644 ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
3645 ok( ret == 1, "got %d\n", ret );
3646 for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3647 memset( data, 0xaa, sizeof(data) );
3649 info->bmiHeader.biHeight = -5;
3650 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3651 ok( ret == 2, "got %d\n", ret );
3652 ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
3653 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3654 memset( data, 0xaa, sizeof(data) );
3656 DeleteObject( dib );
3658 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3659 info->bmiHeader.biWidth = 8;
3660 info->bmiHeader.biHeight = -8;
3661 info->bmiHeader.biPlanes = 1;
3662 info->bmiHeader.biBitCount = 32;
3663 info->bmiHeader.biCompression = BI_RGB;
3665 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3667 for (i = 0; i < 64; i++) dib_bits[i] = i;
3669 /* t-d -> t-d */
3671 info->bmiHeader.biHeight = -8;
3672 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3673 ok( ret == 8, "got %d\n", ret );
3674 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3675 memset( data, 0xaa, sizeof(data) );
3677 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3678 ok( ret == 5, "got %d\n", ret );
3679 ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
3680 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3681 memset( data, 0xaa, sizeof(data) );
3683 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3684 ok( ret == 7, "got %d\n", ret );
3685 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3686 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3687 memset( data, 0xaa, sizeof(data) );
3689 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3690 ok( ret == 4, "got %d\n", ret );
3691 ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
3692 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3693 memset( data, 0xaa, sizeof(data) );
3695 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3696 ok( ret == 5, "got %d\n", ret );
3697 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3698 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3699 memset( data, 0xaa, sizeof(data) );
3701 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3702 ok( ret == 5, "got %d\n", ret );
3703 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3704 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3705 memset( data, 0xaa, sizeof(data) );
3707 info->bmiHeader.biHeight = -16;
3708 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3709 ok( ret == 8, "got %d\n", ret );
3710 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3711 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3712 memset( data, 0xaa, sizeof(data) );
3714 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3715 ok( ret == 5, "got %d\n", ret );
3716 ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
3717 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3718 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3719 memset( data, 0xaa, sizeof(data) );
3721 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3722 ok( ret == 8, "got %d\n", ret );
3723 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3724 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3725 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3726 memset( data, 0xaa, sizeof(data) );
3728 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3729 ok( ret == 8, "got %d\n", ret );
3730 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3731 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3732 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3733 memset( data, 0xaa, sizeof(data) );
3735 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3736 ok( ret == 7, "got %d\n", ret );
3737 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3738 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3739 memset( data, 0xaa, sizeof(data) );
3741 info->bmiHeader.biHeight = -5;
3742 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3743 ok( ret == 2, "got %d\n", ret );
3744 ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
3745 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3746 memset( data, 0xaa, sizeof(data) );
3749 /* t-d -> b-u */
3751 info->bmiHeader.biHeight = 8;
3753 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3754 ok( ret == 8, "got %d\n", ret );
3755 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3756 memset( data, 0xaa, sizeof(data) );
3758 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3759 ok( ret == 5, "got %d\n", ret );
3760 ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
3761 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3762 memset( data, 0xaa, sizeof(data) );
3764 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3765 ok( ret == 7, "got %d\n", ret );
3766 ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
3767 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3768 memset( data, 0xaa, sizeof(data) );
3770 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3771 ok( ret == 1, "got %d\n", ret );
3772 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3773 memset( data, 0xaa, sizeof(data) );
3775 info->bmiHeader.biHeight = 16;
3776 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3777 ok( ret == 5, "got %d\n", ret );
3778 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3779 ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
3780 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3781 memset( data, 0xaa, sizeof(data) );
3783 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3784 ok( ret == 6, "got %d\n", ret );
3785 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3786 ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
3787 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3788 memset( data, 0xaa, sizeof(data) );
3790 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3791 ok( ret == 0, "got %d\n", ret );
3792 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3793 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3794 memset( data, 0xaa, sizeof(data) );
3796 info->bmiHeader.biHeight = 5;
3797 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3798 ok( ret == 2, "got %d\n", ret );
3799 ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
3800 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3801 memset( data, 0xaa, sizeof(data) );
3803 DeleteObject( dib );
3805 ReleaseDC( NULL, hdc );
3809 static void test_SetDIBits(void)
3811 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3812 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3813 DWORD *dib_bits;
3814 HDC hdc = GetDC( NULL );
3815 DWORD data[128], inverted_data[128];
3816 HBITMAP dib;
3817 int i, ret;
3819 memset( info, 0, sizeof(bmi_buf) );
3821 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3822 info->bmiHeader.biWidth = 8;
3823 info->bmiHeader.biHeight = 8;
3824 info->bmiHeader.biPlanes = 1;
3825 info->bmiHeader.biBitCount = 32;
3826 info->bmiHeader.biCompression = BI_RGB;
3828 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3829 memset( dib_bits, 0xaa, 64 * 4 );
3831 for (i = 0; i < 128; i++)
3833 data[i] = i;
3834 inverted_data[120 - (i & ~7) + (i & 7)] = i;
3837 /* b-u -> b-u */
3839 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3840 ok( ret == 8, "got %d\n", ret );
3841 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
3842 memset( dib_bits, 0xaa, 64 * 4 );
3844 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3845 ok( ret == 5, "got %d\n", ret );
3846 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3847 ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
3848 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3849 memset( dib_bits, 0xaa, 64 * 4 );
3851 /* top of dst is aligned with startscans down for the top of the src.
3852 Then starting from the bottom of src, lines rows are copied across. */
3854 info->bmiHeader.biHeight = 16;
3855 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3856 ok( ret == 12, "got %d\n", ret );
3857 ok( !memcmp( dib_bits, data + 56, 40 * 4 ), "bits differ\n");
3858 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3859 memset( dib_bits, 0xaa, 64 * 4 );
3861 info->bmiHeader.biHeight = 5;
3862 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3863 ok( ret == 2, "got %d\n", ret );
3864 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3865 ok( !memcmp( dib_bits + 32, data, 16 * 4 ), "bits differ\n");
3866 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3867 memset( dib_bits, 0xaa, 64 * 4 );
3869 /* t-d -> b-u */
3870 info->bmiHeader.biHeight = -8;
3871 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3872 ok( ret == 8, "got %d\n", ret );
3873 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3874 memset( dib_bits, 0xaa, 64 * 4 );
3876 /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
3877 we copy lines rows from the top of the src */
3879 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3880 ok( ret == 5, "got %d\n", ret );
3881 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3882 ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
3883 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3884 memset( dib_bits, 0xaa, 64 * 4 );
3886 info->bmiHeader.biHeight = -16;
3887 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3888 ok( ret == 12, "got %d\n", ret );
3889 ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
3890 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3891 memset( dib_bits, 0xaa, 64 * 4 );
3893 ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3894 ok( ret == 12, "got %d\n", ret );
3895 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3896 memset( dib_bits, 0xaa, 64 * 4 );
3898 ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3899 ok( ret == 12, "got %d\n", ret );
3900 ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
3901 memset( dib_bits, 0xaa, 64 * 4 );
3903 info->bmiHeader.biHeight = -5;
3904 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3905 ok( ret == 2, "got %d\n", ret );
3906 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3907 ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
3908 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3909 memset( dib_bits, 0xaa, 64 * 4 );
3911 DeleteObject( dib );
3913 info->bmiHeader.biHeight = -8;
3915 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3916 memset( dib_bits, 0xaa, 16 * 16 * 4 );
3918 /* t-d -> t-d */
3920 /* like the t-d -> b-u case. */
3922 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3923 ok( ret == 8, "got %d\n", ret );
3924 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
3925 memset( dib_bits, 0xaa, 64 * 4 );
3927 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3928 ok( ret == 5, "got %d\n", ret );
3929 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3930 ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
3931 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3932 memset( dib_bits, 0xaa, 64 * 4 );
3934 info->bmiHeader.biHeight = -16;
3935 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3936 ok( ret == 12, "got %d\n", ret );
3937 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3938 ok( !memcmp( dib_bits + 24, data, 40 * 4 ), "bits differ\n");
3939 memset( dib_bits, 0xaa, 64 * 4 );
3941 info->bmiHeader.biHeight = -5;
3942 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3943 ok( ret == 2, "got %d\n", ret );
3944 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3945 ok( !memcmp( dib_bits + 16, data, 16 * 4 ), "bits differ\n");
3946 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3947 memset( dib_bits, 0xaa, 64 * 4 );
3949 /* b-u -> t-d */
3950 /* like the b-u -> b-u case */
3952 info->bmiHeader.biHeight = 8;
3953 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3954 ok( ret == 8, "got %d\n", ret );
3955 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3956 memset( dib_bits, 0xaa, 64 * 4 );
3958 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3959 ok( ret == 5, "got %d\n", ret );
3960 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3961 ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
3962 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3963 memset( dib_bits, 0xaa, 64 * 4 );
3965 info->bmiHeader.biHeight = 16;
3966 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3967 ok( ret == 12, "got %d\n", ret );
3968 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3969 ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
3970 memset( dib_bits, 0xaa, 64 * 4 );
3972 info->bmiHeader.biHeight = 5;
3973 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3974 ok( ret == 2, "got %d\n", ret );
3975 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3976 ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
3977 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3978 memset( dib_bits, 0xaa, 64 * 4 );
3980 DeleteObject( dib );
3981 ReleaseDC( NULL, hdc );
3984 static void test_SetDIBits_RLE4(void)
3986 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3987 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3988 DWORD *dib_bits;
3989 HDC hdc = GetDC( NULL );
3990 BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00, /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
3991 0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
3992 0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00, /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
3993 0x00, 0x02, 0x01, 0x02, 0x05, 0x87, /* dx=1, dy=2, 8, 7, 8, 7, 8 */
3994 0x00, 0x01 }; /* <eod> */
3995 HBITMAP dib;
3996 int i, ret;
3997 DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
3998 0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
3999 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4000 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4001 0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
4002 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4003 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4004 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4006 memset( info, 0, sizeof(bmi_buf) );
4008 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4009 info->bmiHeader.biWidth = 8;
4010 info->bmiHeader.biHeight = 8;
4011 info->bmiHeader.biPlanes = 1;
4012 info->bmiHeader.biBitCount = 32;
4013 info->bmiHeader.biCompression = BI_RGB;
4015 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4016 memset( dib_bits, 0xaa, 64 * 4 );
4018 info->bmiHeader.biBitCount = 4;
4019 info->bmiHeader.biCompression = BI_RLE4;
4020 info->bmiHeader.biSizeImage = sizeof(rle4_data);
4022 for (i = 0; i < 16; i++)
4024 info->bmiColors[i].rgbRed = i;
4025 info->bmiColors[i].rgbGreen = i;
4026 info->bmiColors[i].rgbBlue = i;
4027 info->bmiColors[i].rgbReserved = 0;
4030 ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
4031 ok( ret == 8, "got %d\n", ret );
4032 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
4033 memset( dib_bits, 0xaa, 64 * 4 );
4035 DeleteObject( dib );
4036 ReleaseDC( NULL, hdc );
4039 static void test_SetDIBits_RLE8(void)
4041 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
4042 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
4043 DWORD *dib_bits;
4044 HDC hdc = GetDC( NULL );
4045 BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00, /* 2, 2, 2, f0, f0, f0, f0, <eol> */
4046 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4047 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4048 0x00, 0x01 }; /* <eod> */
4049 HBITMAP dib;
4050 int i, ret;
4051 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4052 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4053 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4054 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4055 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4056 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4057 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4058 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4059 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4060 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4061 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4062 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4063 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4064 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4065 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4066 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4068 memset( info, 0, sizeof(bmi_buf) );
4070 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4071 info->bmiHeader.biWidth = 8;
4072 info->bmiHeader.biHeight = 8;
4073 info->bmiHeader.biPlanes = 1;
4074 info->bmiHeader.biBitCount = 32;
4075 info->bmiHeader.biCompression = BI_RGB;
4077 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4078 memset( dib_bits, 0xaa, 64 * 4 );
4080 info->bmiHeader.biBitCount = 8;
4081 info->bmiHeader.biCompression = BI_RLE8;
4082 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4084 for (i = 0; i < 256; i++)
4086 info->bmiColors[i].rgbRed = i;
4087 info->bmiColors[i].rgbGreen = i;
4088 info->bmiColors[i].rgbBlue = i;
4089 info->bmiColors[i].rgbReserved = 0;
4092 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4093 ok( ret == 8, "got %d\n", ret );
4094 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4095 memset( dib_bits, 0xaa, 64 * 4 );
4097 /* startscan and lines are ignored, unless lines == 0 */
4098 ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4099 ok( ret == 8, "got %d\n", ret );
4100 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4101 memset( dib_bits, 0xaa, 64 * 4 );
4103 ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4104 ok( ret == 8, "got %d\n", ret );
4105 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4106 memset( dib_bits, 0xaa, 64 * 4 );
4108 ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4109 ok( ret == 0, "got %d\n", ret );
4110 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4111 memset( dib_bits, 0xaa, 64 * 4 );
4113 /* reduce width to 4, left-hand side of dst is touched. */
4114 info->bmiHeader.biWidth = 4;
4115 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4116 ok( ret == 8, "got %d\n", ret );
4117 for (i = 0; i < 64; i++)
4119 DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4120 ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4122 memset( dib_bits, 0xaa, 64 * 4 );
4124 /* Show that the top lines are aligned by adjusting the height of the src */
4126 /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4127 info->bmiHeader.biWidth = 8;
4128 info->bmiHeader.biHeight = 4;
4129 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4130 ok( ret == 4, "got %d\n", ret );
4131 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4132 ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4133 memset( dib_bits, 0xaa, 64 * 4 );
4135 /* increase the height to 9 -> everything moves down one row. */
4136 info->bmiHeader.biHeight = 9;
4137 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4138 ok( ret == 9, "got %d\n", ret );
4139 ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4140 for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4141 memset( dib_bits, 0xaa, 64 * 4 );
4143 /* top-down compressed dibs are invalid */
4144 info->bmiHeader.biHeight = -8;
4145 SetLastError( 0xdeadbeef );
4146 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4147 ok( ret == 0, "got %d\n", ret );
4148 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4149 DeleteObject( dib );
4151 /* top-down dst */
4153 info->bmiHeader.biHeight = -8;
4154 info->bmiHeader.biBitCount = 32;
4155 info->bmiHeader.biCompression = BI_RGB;
4156 info->bmiHeader.biSizeImage = 0;
4158 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4159 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4161 info->bmiHeader.biHeight = 8;
4162 info->bmiHeader.biBitCount = 8;
4163 info->bmiHeader.biCompression = BI_RLE8;
4164 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4166 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4167 ok( ret == 8, "got %d\n", ret );
4168 ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4169 memset( dib_bits, 0xaa, 64 * 4 );
4171 info->bmiHeader.biHeight = 4;
4172 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4173 ok( ret == 4, "got %d\n", ret );
4174 ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4175 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4176 memset( dib_bits, 0xaa, 64 * 4 );
4178 info->bmiHeader.biHeight = 9;
4179 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4180 ok( ret == 9, "got %d\n", ret );
4181 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4182 ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4183 memset( dib_bits, 0xaa, 64 * 4 );
4185 DeleteObject( dib );
4187 ReleaseDC( NULL, hdc );
4190 static void test_SetDIBitsToDevice(void)
4192 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
4193 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
4194 DWORD *dib_bits;
4195 HDC hdc = CreateCompatibleDC( 0 );
4196 DWORD data[128], inverted_data[128];
4197 HBITMAP dib;
4198 int i, ret;
4200 memset( info, 0, sizeof(bmi_buf) );
4202 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4203 info->bmiHeader.biWidth = 8;
4204 info->bmiHeader.biHeight = 8;
4205 info->bmiHeader.biPlanes = 1;
4206 info->bmiHeader.biBitCount = 32;
4207 info->bmiHeader.biCompression = BI_RGB;
4209 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4210 memset( dib_bits, 0xaa, 64 * 4 );
4211 SelectObject( hdc, dib );
4213 for (i = 0; i < 128; i++)
4215 data[i] = i;
4216 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4219 /* b-u -> b-u */
4221 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4222 ok( ret == 8, "got %d\n", ret );
4223 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4224 memset( dib_bits, 0xaa, 64 * 4 );
4226 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4227 ok( ret == 5, "got %d\n", ret );
4228 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4229 for (i = 8; i < 48; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4230 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4231 memset( dib_bits, 0xaa, 64 * 4 );
4233 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 3, 1, 5, data, info, DIB_RGB_COLORS );
4234 ok( ret == 5, "got %d\n", ret );
4235 for (i = 0; i < 24; i++) ok( dib_bits[i] == data[i + 16], "%d: got %08x\n", i, dib_bits[i] );
4236 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4237 memset( dib_bits, 0xaa, 64 * 4 );
4239 info->bmiHeader.biHeight = 16;
4240 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4241 ok( ret == 7, "got %d\n", ret );
4242 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4243 for (i = 8; i < 64; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4244 memset( dib_bits, 0xaa, 64 * 4 );
4246 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 8, 0, 6, 1, 12, data, info, DIB_RGB_COLORS );
4247 ok( ret == 12, "got %d\n", ret );
4248 for (i = 0; i < 40; i++) ok( dib_bits[i] == data[i + 56], "%d: got %08x\n", i, dib_bits[i] );
4249 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4250 memset( dib_bits, 0xaa, 64 * 4 );
4252 ret = SetDIBitsToDevice( hdc, 0, -4, 8, 8, 0, 3, 1, 12, data, info, DIB_RGB_COLORS );
4253 ok( ret == 10, "got %d\n", ret );
4254 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4255 for (i = 32; i < 64; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4256 memset( dib_bits, 0xaa, 64 * 4 );
4258 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, -3, 1, 12, data, info, DIB_RGB_COLORS );
4259 ok( ret == 4, "got %d\n", ret );
4260 for (i = 0; i < 32; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4261 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4262 memset( dib_bits, 0xaa, 64 * 4 );
4264 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 5, 0, -2, 1, 12, data, info, DIB_RGB_COLORS );
4265 ok( ret == 2, "got %d\n", ret );
4266 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4267 for (i = 32; i < 48; i++) ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4268 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4269 memset( dib_bits, 0xaa, 64 * 4 );
4271 info->bmiHeader.biHeight = 5;
4272 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 2, 2, data, info, DIB_RGB_COLORS );
4273 ok( ret == 2, "got %d\n", ret );
4274 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4275 for (i = 16; i < 32; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4276 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4277 memset( dib_bits, 0xaa, 64 * 4 );
4279 ret = SetDIBitsToDevice( hdc, 3, 3, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4280 ok( ret == 3, "got %d\n", ret );
4281 for (i = 0; i < 64; i++)
4282 if (i == 27 || i == 28 || i == 35 || i == 36)
4283 ok( dib_bits[i] == data[i - 18], "%d: got %08x\n", i, dib_bits[i] );
4284 else
4285 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4286 memset( dib_bits, 0xaa, 64 * 4 );
4288 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4289 ok( ret == 5, "got %d\n", ret );
4290 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4291 memset( dib_bits, 0xaa, 64 * 4 );
4293 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4294 ok( ret == 0, "got %d\n", ret );
4295 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4296 memset( dib_bits, 0xaa, 64 * 4 );
4298 SetMapMode( hdc, MM_ANISOTROPIC );
4299 SetWindowExtEx( hdc, 3, 3, NULL );
4300 ret = SetDIBitsToDevice( hdc, 2, 2, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4301 ok( ret == 3, "got %d\n", ret );
4302 for (i = 0; i < 64; i++)
4303 if (i == 41 || i == 42 || i == 49 || i == 50)
4304 ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4305 else
4306 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4307 memset( dib_bits, 0xaa, 64 * 4 );
4309 SetWindowExtEx( hdc, -1, -1, NULL );
4310 ret = SetDIBitsToDevice( hdc, 2, 2, 4, 4, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4311 ok( ret == 4, "got %d\n", ret );
4312 for (i = 0; i < 64; i++)
4313 if (i == 48 || i == 49 || i == 56 || i == 57)
4314 ok( dib_bits[i] == data[i - 37], "%d: got %08x\n", i, dib_bits[i] );
4315 else
4316 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4317 memset( dib_bits, 0xaa, 64 * 4 );
4318 SetMapMode( hdc, MM_TEXT );
4320 if (pSetLayout)
4322 pSetLayout( hdc, LAYOUT_RTL );
4323 ret = SetDIBitsToDevice( hdc, 1, 2, 3, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4324 ok( ret == 3, "got %d\n", ret );
4325 for (i = 0; i < 64; i++)
4326 if (i == 36 || i == 37 || i == 38 || i == 44 || i == 45 || i == 46)
4327 ok( dib_bits[i] == data[i - 27], "%d: got %08x\n", i, dib_bits[i] );
4328 else
4329 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4330 memset( dib_bits, 0xaa, 64 * 4 );
4331 pSetLayout( hdc, LAYOUT_LTR );
4334 /* t-d -> b-u */
4335 info->bmiHeader.biHeight = -8;
4336 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4337 ok( ret == 8, "got %d\n", ret );
4338 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4339 memset( dib_bits, 0xaa, 64 * 4 );
4341 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4342 ok( ret == 5, "got %d\n", ret );
4343 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4344 for (i = 8; i < 48; i++) ok( dib_bits[i] == inverted_data[i + 80], "%d: got %08x\n", i, dib_bits[i] );
4345 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4346 memset( dib_bits, 0xaa, 64 * 4 );
4348 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 4, 1, 5, data, info, DIB_RGB_COLORS );
4349 ok( ret == 5, "got %d\n", ret );
4350 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4351 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4352 memset( dib_bits, 0xaa, 64 * 4 );
4354 info->bmiHeader.biHeight = -16;
4355 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4356 ok( ret == 12, "got %d\n", ret );
4357 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4358 for (i = 8; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4359 memset( dib_bits, 0xaa, 64 * 4 );
4361 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, 7, 1, 12, data, info, DIB_RGB_COLORS );
4362 ok( ret == 12, "got %d\n", ret );
4363 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4364 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4365 memset( dib_bits, 0xaa, 64 * 4 );
4367 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 4, 12, data, info, DIB_RGB_COLORS );
4368 ok( ret == 12, "got %d\n", ret );
4369 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4370 for (i = 32; i < 64; i++) ok( dib_bits[i] == inverted_data[i], "%d: got %08x\n", i, dib_bits[i] );
4371 memset( dib_bits, 0xaa, 64 * 4 );
4373 ret = SetDIBitsToDevice( hdc, 0, -3, 8, 8, 0, 2, 4, 12, data, info, DIB_RGB_COLORS );
4374 ok( ret == 12, "got %d\n", ret );
4375 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4376 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4377 memset( dib_bits, 0xaa, 64 * 4 );
4379 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, -2, 4, 12, data, info, DIB_RGB_COLORS );
4380 ok( ret == 12, "got %d\n", ret );
4381 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4382 for (i = 24; i < 40; i++) ok( dib_bits[i] == inverted_data[i + 8], "%d: got %08x\n", i, dib_bits[i] );
4383 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4384 memset( dib_bits, 0xaa, 64 * 4 );
4386 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 5, 12, data, info, DIB_RGB_COLORS );
4387 ok( ret == 12, "got %d\n", ret );
4388 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4389 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4390 memset( dib_bits, 0xaa, 64 * 4 );
4392 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4393 ok( ret == 12, "got %d\n", ret );
4394 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4395 memset( dib_bits, 0xaa, 64 * 4 );
4397 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -2, -4, 0, 12, data, info, DIB_RGB_COLORS );
4398 ok( ret == 12, "got %d\n", ret );
4399 for (i = 0; i < 64; i++)
4400 if (i == 31 || i == 39 || i == 47 || i == 55 || i == 63)
4401 ok( dib_bits[i] == inverted_data[i + 1], "%d: got %08x\n", i, dib_bits[i] );
4402 else
4403 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4404 memset( dib_bits, 0xaa, 64 * 4 );
4406 info->bmiHeader.biHeight = -5;
4407 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4408 ok( ret == 2, "got %d\n", ret );
4409 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4410 for (i = 8; i < 24; i++) ok( dib_bits[i] == inverted_data[i + 104], "%d: got %08x\n", i, dib_bits[i] );
4411 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4412 memset( dib_bits, 0xaa, 64 * 4 );
4414 ret = SetDIBitsToDevice( hdc, 5, 4, 2, 2, 6, 3, 1, 5, data, info, DIB_RGB_COLORS );
4415 ok( ret == 5, "got %d\n", ret );
4416 for (i = 0; i < 64; i++)
4417 if (i == 21 || i == 22 || i == 29 || i == 30)
4418 ok( dib_bits[i] == inverted_data[i + 89], "%d: got %08x\n", i, dib_bits[i] );
4419 else
4420 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4421 memset( dib_bits, 0xaa, 64 * 4 );
4423 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4424 ok( ret == 5, "got %d\n", ret );
4425 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4426 memset( dib_bits, 0xaa, 64 * 4 );
4428 info->bmiHeader.biHeight = -8;
4430 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4431 DeleteObject( SelectObject( hdc, dib ));
4432 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4434 /* t-d -> t-d */
4436 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4437 ok( ret == 8, "got %d\n", ret );
4438 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4439 memset( dib_bits, 0xaa, 64 * 4 );
4441 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4442 ok( ret == 5, "got %d\n", ret );
4443 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4444 for (i = 16; i < 56; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4445 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4446 memset( dib_bits, 0xaa, 64 * 4 );
4448 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 3, 0, 2, 1, 5, data, info, DIB_RGB_COLORS );
4449 ok( ret == 5, "got %d\n", ret );
4450 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4451 for (i = 24; i < 48; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4452 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4453 memset( dib_bits, 0xaa, 64 * 4 );
4455 info->bmiHeader.biHeight = -16;
4456 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4457 ok( ret == 12, "got %d\n", ret );
4458 for (i = 0; i < 56; i++) ok( dib_bits[i] == data[i + 40], "%d: got %08x\n", i, dib_bits[i] );
4459 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4460 memset( dib_bits, 0xaa, 64 * 4 );
4462 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -1, -8, 0, 12, data, info, DIB_RGB_COLORS );
4463 ok( ret == 12, "got %d\n", ret );
4464 for (i = 0; i < 64; i++)
4465 if (i == 6 || i == 7)
4466 ok( dib_bits[i] == data[i + 82], "%d: got %08x\n", i, dib_bits[i] );
4467 else
4468 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4469 memset( dib_bits, 0xaa, 64 * 4 );
4471 info->bmiHeader.biHeight = -5;
4472 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4473 ok( ret == 2, "got %d\n", ret );
4474 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4475 for (i = 40; i < 56; i++) ok( dib_bits[i] == data[i - 40], "%d: got %08x\n", i, dib_bits[i] );
4476 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4477 memset( dib_bits, 0xaa, 64 * 4 );
4479 ret = SetDIBitsToDevice( hdc, 7, 2, 8, 8, 1, 0, 0, 5, data, info, DIB_RGB_COLORS );
4480 ok( ret == 5, "got %d\n", ret );
4481 for (i = 0; i < 64; i++)
4482 if (i == 47 || i == 55 || i == 63)
4483 ok( dib_bits[i] == data[i - 46], "%d: got %08x\n", i, dib_bits[i] );
4484 else
4485 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4486 memset( dib_bits, 0xaa, 64 * 4 );
4488 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4489 ok( ret == 5, "got %d\n", ret );
4490 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4491 memset( dib_bits, 0xaa, 64 * 4 );
4493 /* b-u -> t-d */
4495 info->bmiHeader.biHeight = 8;
4496 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4497 ok( ret == 8, "got %d\n", ret );
4498 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4499 memset( dib_bits, 0xaa, 64 * 4 );
4501 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4502 ok( ret == 5, "got %d\n", ret );
4503 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4504 for (i = 16; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4505 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4506 memset( dib_bits, 0xaa, 64 * 4 );
4508 info->bmiHeader.biHeight = 16;
4509 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4510 ok( ret == 7, "got %d\n", ret );
4511 for (i = 0; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4512 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4513 memset( dib_bits, 0xaa, 64 * 4 );
4515 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, 0, -4, 1, 12, data, info, DIB_RGB_COLORS );
4516 ok( ret == 3, "got %d\n", ret );
4517 for (i = 0; i < 64; i++)
4518 if ((i >= 36 && i <= 39) || (i >= 44 && i <= 47) || (i >= 52 && i <= 55))
4519 ok( dib_bits[i] == inverted_data[i + 68], "%d: got %08x\n", i, dib_bits[i] );
4520 else
4521 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4522 memset( dib_bits, 0xaa, 64 * 4 );
4524 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, -30, -30, 1, 12, data, info, DIB_RGB_COLORS );
4525 ok( ret == 0, "got %d\n", ret );
4526 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4527 memset( dib_bits, 0xaa, 64 * 4 );
4529 ret = SetDIBitsToDevice( hdc, 5, -5, 8, 16, -2, -4, 4, 12, data, info, DIB_RGB_COLORS );
4530 ok( ret == 8, "got %d\n", ret );
4531 for (i = 0; i < 64; i++)
4532 if (i == 7 || i == 15 || i == 23)
4533 ok( dib_bits[i] == inverted_data[i + 97], "%d: got %08x\n", i, dib_bits[i] );
4534 else
4535 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4536 memset( dib_bits, 0xaa, 64 * 4 );
4538 info->bmiHeader.biHeight = 5;
4539 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4540 ok( ret == 2, "got %d\n", ret );
4541 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4542 for (i = 40; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4543 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4544 memset( dib_bits, 0xaa, 64 * 4 );
4546 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4547 ok( ret == 5, "got %d\n", ret );
4548 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4549 memset( dib_bits, 0xaa, 64 * 4 );
4551 DeleteDC( hdc );
4552 DeleteObject( dib );
4555 static void test_SetDIBitsToDevice_RLE8(void)
4557 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
4558 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
4559 DWORD *dib_bits;
4560 HDC hdc = CreateCompatibleDC( 0 );
4561 BYTE rle8_data[20] = { 0x04, 0x02, 0x03, 0xf0, 0x00, 0x00, /* 2, 2, 2, 2, f0, f0, f0, <eol> */
4562 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4563 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4564 0x00, 0x01 }; /* <eod> */
4565 HBITMAP dib;
4566 int i, ret;
4567 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4568 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4569 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4570 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4571 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4572 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4573 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4574 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4575 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4576 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4577 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4578 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4579 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4580 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4581 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4582 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4584 memset( info, 0, sizeof(bmi_buf) );
4586 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4587 info->bmiHeader.biWidth = 8;
4588 info->bmiHeader.biHeight = 8;
4589 info->bmiHeader.biPlanes = 1;
4590 info->bmiHeader.biBitCount = 32;
4591 info->bmiHeader.biCompression = BI_RGB;
4593 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4594 memset( dib_bits, 0xaa, 64 * 4 );
4595 SelectObject( hdc, dib );
4597 info->bmiHeader.biBitCount = 8;
4598 info->bmiHeader.biCompression = BI_RLE8;
4599 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4601 for (i = 0; i < 256; i++)
4603 info->bmiColors[i].rgbRed = i;
4604 info->bmiColors[i].rgbGreen = i;
4605 info->bmiColors[i].rgbBlue = i;
4606 info->bmiColors[i].rgbReserved = 0;
4609 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4610 ok( ret == 8, "got %d\n", ret );
4611 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4612 memset( dib_bits, 0xaa, 64 * 4 );
4614 /* startscan and lines are ignored, unless lines == 0 */
4615 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4616 ok( ret == 8, "got %d\n", ret );
4617 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4618 memset( dib_bits, 0xaa, 64 * 4 );
4620 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4621 ok( ret == 8, "got %d\n", ret );
4622 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4623 memset( dib_bits, 0xaa, 64 * 4 );
4625 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4626 ok( ret == 0, "got %d\n", ret );
4627 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4628 memset( dib_bits, 0xaa, 64 * 4 );
4630 info->bmiHeader.biWidth = 2;
4631 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4632 ok( ret == 8, "got %d\n", ret );
4633 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4634 memset( dib_bits, 0xaa, 64 * 4 );
4636 info->bmiHeader.biWidth = 8;
4637 info->bmiHeader.biHeight = 2;
4638 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4639 ok( ret == 2, "got %d\n", ret );
4640 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4641 memset( dib_bits, 0xaa, 64 * 4 );
4643 info->bmiHeader.biHeight = 9;
4644 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4645 ok( ret == 9, "got %d\n", ret );
4646 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4647 memset( dib_bits, 0xaa, 64 * 4 );
4649 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4650 ok( ret == 9, "got %d\n", ret );
4651 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4652 memset( dib_bits, 0xaa, 64 * 4 );
4654 info->bmiHeader.biHeight = 8;
4655 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 9, rle8_data, info, DIB_RGB_COLORS );
4656 ok( ret == 8, "got %d\n", ret );
4657 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4658 memset( dib_bits, 0xaa, 64 * 4 );
4660 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4661 ok( ret == 8, "got %d\n", ret );
4662 for (i = 0; i < 40; i++) ok( dib_bits[i] == bottom_up[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4663 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4664 memset( dib_bits, 0xaa, 64 * 4 );
4666 ret = SetDIBitsToDevice( hdc, 0, 3, 4, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4667 ok( ret == 8, "got %d\n", ret );
4668 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4669 for (i = 8; i < 40; i++)
4670 if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4671 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4672 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4673 memset( dib_bits, 0xaa, 64 * 4 );
4675 ret = SetDIBitsToDevice( hdc, 3, 3, 8, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4676 ok( ret == 8, "got %d\n", ret );
4677 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4678 for (i = 8; i < 40; i++)
4679 if ((i & 7) < 3) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4680 else ok( dib_bits[i] == bottom_up[i - 11], "%d: got %08x\n", i, dib_bits[i] );
4681 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4682 memset( dib_bits, 0xaa, 64 * 4 );
4684 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 4, 2, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4685 ok( ret == 8, "got %d\n", ret );
4686 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4687 for (i = 8; i < 40; i++)
4688 if ((i & 7) < 2) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4689 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4690 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4691 memset( dib_bits, 0xaa, 64 * 4 );
4693 info->bmiHeader.biWidth = 37;
4694 info->bmiHeader.biHeight = 37;
4695 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
4696 ok( ret == 37, "got %d\n", ret );
4697 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4698 for (i = 24; i < 64; i++)
4699 if (i == 52) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
4700 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4701 else ok( dib_bits[i] == bottom_up[i - 20], "%d: got %08x\n", i, dib_bits[i] );
4702 memset( dib_bits, 0xaa, 64 * 4 );
4704 /* top-down compressed dibs are invalid */
4705 info->bmiHeader.biWidth = 8;
4706 info->bmiHeader.biHeight = -8;
4707 SetLastError( 0xdeadbeef );
4708 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4709 ok( ret == 0, "got %d\n", ret );
4710 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4712 /* top-down dst */
4714 info->bmiHeader.biHeight = -8;
4715 info->bmiHeader.biBitCount = 32;
4716 info->bmiHeader.biCompression = BI_RGB;
4717 info->bmiHeader.biSizeImage = 0;
4719 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4720 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4721 DeleteObject( SelectObject( hdc, dib ));
4723 info->bmiHeader.biHeight = 8;
4724 info->bmiHeader.biBitCount = 8;
4725 info->bmiHeader.biCompression = BI_RLE8;
4726 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4728 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4729 ok( ret == 8, "got %d\n", ret );
4730 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4731 memset( dib_bits, 0xaa, 64 * 4 );
4733 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4734 ok( ret == 8, "got %d\n", ret );
4735 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4736 memset( dib_bits, 0xaa, 64 * 4 );
4738 info->bmiHeader.biHeight = 4;
4739 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4740 ok( ret == 4, "got %d\n", ret );
4741 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4742 memset( dib_bits, 0xaa, 64 * 4 );
4744 info->bmiHeader.biHeight = 9;
4745 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4746 ok( ret == 9, "got %d\n", ret );
4747 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4748 memset( dib_bits, 0xaa, 64 * 4 );
4750 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4751 ok( ret == 9, "got %d\n", ret );
4752 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4753 memset( dib_bits, 0xaa, 64 * 4 );
4755 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 6, 2, 2, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4756 ok( ret == 9, "got %d\n", ret );
4757 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4758 for (i = 24; i < 64; i++) ok( dib_bits[i] == top_down[i - 24], "%d: got %08x\n", i, dib_bits[i] );
4759 memset( dib_bits, 0xaa, 64 * 4 );
4761 info->bmiHeader.biWidth = 37;
4762 info->bmiHeader.biHeight = 37;
4763 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
4764 ok( ret == 37, "got %d\n", ret );
4765 for (i = 0; i < 40; i++)
4766 if (i == 12) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
4767 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4768 else ok( dib_bits[i] == top_down[i + 28], "%d: got %08x\n", i, dib_bits[i] );
4769 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4770 memset( dib_bits, 0xaa, 64 * 4 );
4772 DeleteDC( hdc );
4773 DeleteObject( dib );
4776 START_TEST(bitmap)
4778 HMODULE hdll;
4780 hdll = GetModuleHandle("gdi32.dll");
4781 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
4782 pSetLayout = (void*)GetProcAddress(hdll, "SetLayout");
4784 test_createdibitmap();
4785 test_dibsections();
4786 test_dib_formats();
4787 test_mono_dibsection();
4788 test_bitmap();
4789 test_bmBits();
4790 test_GetDIBits_selected_DIB(1);
4791 test_GetDIBits_selected_DIB(4);
4792 test_GetDIBits_selected_DIB(8);
4793 test_GetDIBits_selected_DDB(TRUE);
4794 test_GetDIBits_selected_DDB(FALSE);
4795 test_GetDIBits();
4796 test_GetDIBits_BI_BITFIELDS();
4797 test_select_object();
4798 test_CreateBitmap();
4799 test_BitBlt();
4800 test_StretchBlt();
4801 test_StretchDIBits();
4802 test_GdiAlphaBlend();
4803 test_32bit_bitmap_blt();
4804 test_bitmapinfoheadersize();
4805 test_get16dibits();
4806 test_clipping();
4807 test_GetDIBits_top_down(16);
4808 test_GetDIBits_top_down(24);
4809 test_GetDIBits_top_down(32);
4810 test_GetSetDIBits_rtl();
4811 test_GetDIBits_scanlines();
4812 test_SetDIBits();
4813 test_SetDIBits_RLE4();
4814 test_SetDIBits_RLE8();
4815 test_SetDIBitsToDevice();
4816 test_SetDIBitsToDevice_RLE8();