gdi32/tests: Add some tests to show the 1 pixel dst sizes are a special case.
[wine/multimedia.git] / dlls / gdi32 / tests / bitmap.c
blob89d2c9c08ed454405ea6adca3a70d59c4f6ae3bf
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 inline int get_bitmap_stride( int width, int bpp )
42 return ((width * bpp + 15) >> 3) & ~1;
45 static inline int get_dib_stride( int width, int bpp )
47 return ((width * bpp + 31) >> 3) & ~3;
50 static inline int get_dib_image_size( const BITMAPINFO *info )
52 return get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount )
53 * abs( info->bmiHeader.biHeight );
56 static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHEADER *bmih)
58 BITMAP bm;
59 BITMAP bma[2];
60 INT ret, width_bytes;
61 BYTE buf[512], buf_cmp[512];
63 ret = GetObject(hbm, sizeof(bm), &bm);
64 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
66 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
67 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
68 ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
69 width_bytes = get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel);
70 ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
71 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
72 ok(bm.bmBitsPixel == expected_depth, "wrong bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, expected_depth);
73 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
75 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
76 assert(sizeof(buf) == sizeof(buf_cmp));
78 SetLastError(0xdeadbeef);
79 ret = GetBitmapBits(hbm, 0, NULL);
80 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
82 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
83 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
85 memset(buf, 0xAA, sizeof(buf));
86 ret = GetBitmapBits(hbm, sizeof(buf), buf);
87 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
88 ok(!memcmp(buf, buf_cmp, sizeof(buf)),
89 "buffers do not match, depth %d\n", bmih->biBitCount);
91 /* test various buffer sizes for GetObject */
92 ret = GetObject(hbm, sizeof(*bma) * 2, bma);
93 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
95 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
96 ok(ret == 0, "%d != 0\n", ret);
98 ret = GetObject(hbm, 0, &bm);
99 ok(ret == 0, "%d != 0\n", ret);
101 ret = GetObject(hbm, 1, &bm);
102 ok(ret == 0, "%d != 0\n", ret);
104 ret = GetObject(hbm, 0, NULL);
105 ok(ret == sizeof(bm), "wrong size %d\n", ret);
108 static void test_createdibitmap(void)
110 HDC hdc, hdcmem;
111 BITMAPINFOHEADER bmih;
112 BITMAPINFO bm;
113 HBITMAP hbm, hbm_colour, hbm_old;
114 INT screen_depth;
115 DWORD pixel;
117 hdc = GetDC(0);
118 screen_depth = GetDeviceCaps(hdc, BITSPIXEL);
119 memset(&bmih, 0, sizeof(bmih));
120 bmih.biSize = sizeof(bmih);
121 bmih.biWidth = 10;
122 bmih.biHeight = 10;
123 bmih.biPlanes = 1;
124 bmih.biBitCount = 32;
125 bmih.biCompression = BI_RGB;
127 hbm = CreateDIBitmap(hdc, NULL, CBM_INIT, NULL, NULL, 0);
128 ok(hbm == NULL, "CreateDIBitmap should fail\n");
129 hbm = CreateDIBitmap(hdc, NULL, 0, NULL, NULL, 0);
130 ok(hbm == NULL, "CreateDIBitmap should fail\n");
132 /* First create an un-initialised bitmap. The depth of the bitmap
133 should match that of the hdc and not that supplied in bmih.
136 /* First try 32 bits */
137 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
138 ok(hbm != NULL, "CreateDIBitmap failed\n");
139 test_bitmap_info(hbm, screen_depth, &bmih);
140 DeleteObject(hbm);
142 /* Then 16 */
143 bmih.biBitCount = 16;
144 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
145 ok(hbm != NULL, "CreateDIBitmap failed\n");
146 test_bitmap_info(hbm, screen_depth, &bmih);
147 DeleteObject(hbm);
149 /* Then 1 */
150 bmih.biBitCount = 1;
151 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
152 ok(hbm != NULL, "CreateDIBitmap failed\n");
153 test_bitmap_info(hbm, screen_depth, &bmih);
154 DeleteObject(hbm);
156 /* Now with a monochrome dc we expect a monochrome bitmap */
157 hdcmem = CreateCompatibleDC(hdc);
159 /* First try 32 bits */
160 bmih.biBitCount = 32;
161 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
162 ok(hbm != NULL, "CreateDIBitmap failed\n");
163 test_bitmap_info(hbm, 1, &bmih);
164 DeleteObject(hbm);
166 /* Then 16 */
167 bmih.biBitCount = 16;
168 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
169 ok(hbm != NULL, "CreateDIBitmap failed\n");
170 test_bitmap_info(hbm, 1, &bmih);
171 DeleteObject(hbm);
173 /* Then 1 */
174 bmih.biBitCount = 1;
175 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
176 ok(hbm != NULL, "CreateDIBitmap failed\n");
177 test_bitmap_info(hbm, 1, &bmih);
178 DeleteObject(hbm);
180 /* Now select a polychrome bitmap into the dc and we expect
181 screen_depth bitmaps again */
182 hbm_colour = CreateCompatibleBitmap(hdc, bmih.biWidth, bmih.biHeight);
183 test_bitmap_info(hbm_colour, screen_depth, &bmih);
184 hbm_old = SelectObject(hdcmem, hbm_colour);
186 /* First try 32 bits */
187 bmih.biBitCount = 32;
188 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
189 ok(hbm != NULL, "CreateDIBitmap failed\n");
190 test_bitmap_info(hbm, screen_depth, &bmih);
191 DeleteObject(hbm);
193 /* Then 16 */
194 bmih.biBitCount = 16;
195 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
196 ok(hbm != NULL, "CreateDIBitmap failed\n");
197 test_bitmap_info(hbm, screen_depth, &bmih);
198 DeleteObject(hbm);
200 /* Then 1 */
201 bmih.biBitCount = 1;
202 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
203 ok(hbm != NULL, "CreateDIBitmap failed\n");
204 test_bitmap_info(hbm, screen_depth, &bmih);
205 DeleteObject(hbm);
207 SelectObject(hdcmem, hbm_old);
208 DeleteObject(hbm_colour);
209 DeleteDC(hdcmem);
211 bmih.biBitCount = 32;
212 hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0);
213 ok(hbm != NULL, "CreateDIBitmap failed\n");
214 test_bitmap_info(hbm, 1, &bmih);
215 DeleteObject(hbm);
217 /* Test how formats are converted */
218 pixel = 0xffffffff;
219 bmih.biBitCount = 1;
220 bmih.biWidth = 1;
221 bmih.biHeight = 1;
223 memset(&bm, 0, sizeof(bm));
224 bm.bmiHeader.biSize = sizeof(bm.bmiHeader);
225 bm.bmiHeader.biWidth = 1;
226 bm.bmiHeader.biHeight = 1;
227 bm.bmiHeader.biPlanes = 1;
228 bm.bmiHeader.biBitCount= 24;
229 bm.bmiHeader.biCompression= BI_RGB;
230 bm.bmiHeader.biSizeImage = 0;
231 hbm = CreateDIBitmap(hdc, &bmih, CBM_INIT, &pixel, &bm, DIB_RGB_COLORS);
232 ok(hbm != NULL, "CreateDIBitmap failed\n");
234 pixel = 0xdeadbeef;
235 bm.bmiHeader.biBitCount= 32;
236 GetDIBits(hdc, hbm, 0, 1, &pixel, &bm, DIB_RGB_COLORS);
237 ok(pixel == 0x00ffffff, "Reading a 32 bit pixel from a DDB returned %08x\n", pixel);
238 DeleteObject(hbm);
240 ReleaseDC(0, hdc);
243 static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
245 BITMAP bm;
246 BITMAP bma[2];
247 DIBSECTION ds;
248 DIBSECTION dsa[2];
249 INT ret, bm_width_bytes, dib_width_bytes;
250 BYTE *buf;
252 ret = GetObject(hbm, sizeof(bm), &bm);
253 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
255 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
256 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
257 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
258 dib_width_bytes = get_dib_stride(bm.bmWidth, bm.bmBitsPixel);
259 bm_width_bytes = get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel);
260 if (bm.bmWidthBytes != dib_width_bytes) /* Win2k bug */
261 ok(bm.bmWidthBytes == bm_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, bm_width_bytes);
262 else
263 ok(bm.bmWidthBytes == dib_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, dib_width_bytes);
264 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
265 ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount);
266 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
268 buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);
270 /* GetBitmapBits returns not 32-bit aligned data */
271 SetLastError(0xdeadbeef);
272 ret = GetBitmapBits(hbm, 0, NULL);
273 ok(ret == bm_width_bytes * bm.bmHeight,
274 "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
276 memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
277 ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
278 ok(ret == bm_width_bytes * bm.bmHeight, "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
280 HeapFree(GetProcessHeap(), 0, buf);
282 /* test various buffer sizes for GetObject */
283 memset(&ds, 0xAA, sizeof(ds));
284 ret = GetObject(hbm, sizeof(*bma) * 2, bma);
285 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
286 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
287 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
288 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
290 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
291 ok(ret == 0, "%d != 0\n", ret);
293 ret = GetObject(hbm, 0, &bm);
294 ok(ret == 0, "%d != 0\n", ret);
296 ret = GetObject(hbm, 1, &bm);
297 ok(ret == 0, "%d != 0\n", ret);
299 /* test various buffer sizes for GetObject */
300 ret = GetObject(hbm, 0, NULL);
301 ok(ret == sizeof(bm), "wrong size %d\n", ret);
303 ret = GetObject(hbm, sizeof(*dsa) * 2, dsa);
304 ok(ret == sizeof(*dsa), "wrong size %d\n", ret);
306 memset(&ds, 0xAA, sizeof(ds));
307 ret = GetObject(hbm, sizeof(ds), &ds);
308 ok(ret == sizeof(ds), "wrong size %d\n", ret);
310 ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
311 if (ds.dsBm.bmWidthBytes != bm_width_bytes) /* Win2k bug */
312 ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%u != %u\n",
313 ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
314 ok(bmih->biSizeImage == 0, "%u != 0\n", bmih->biSizeImage);
315 ds.dsBmih.biSizeImage = 0;
317 ok(ds.dsBmih.biSize == bmih->biSize, "%u != %u\n", ds.dsBmih.biSize, bmih->biSize);
318 ok(ds.dsBmih.biWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
319 ok(ds.dsBmih.biHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
320 ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes);
321 ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount);
322 ok(ds.dsBmih.biCompression == bmih->biCompression ||
323 ((bmih->biBitCount == 32) && broken(ds.dsBmih.biCompression == BI_BITFIELDS)), /* nt4 sp1 and 2 */
324 "%u != %u\n", ds.dsBmih.biCompression, bmih->biCompression);
325 ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%u != %u\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
326 ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%d != %d\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
327 ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%d != %d\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);
329 memset(&ds, 0xAA, sizeof(ds));
330 ret = GetObject(hbm, sizeof(ds) - 4, &ds);
331 ok(ret == sizeof(ds.dsBm), "wrong size %d\n", ret);
332 ok(ds.dsBm.bmWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
333 ok(ds.dsBm.bmHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
334 ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);
336 ret = GetObject(hbm, 0, &ds);
337 ok(ret == 0, "%d != 0\n", ret);
339 ret = GetObject(hbm, 1, &ds);
340 ok(ret == 0, "%d != 0\n", ret);
343 #define test_color_todo(got, exp, txt, todo) \
344 if (!todo && got != exp && screen_depth < 24) { \
345 todo_wine ok(0, #txt " failed at %d-bit screen depth: got 0x%06x expected 0x%06x - skipping DIB tests\n", \
346 screen_depth, (UINT)got, (UINT)exp); \
347 return; \
348 } else if (todo) todo_wine { ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp); } \
349 else ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp) \
351 #define test_color(hdc, color, exp, todo_setp, todo_getp) \
353 COLORREF c; \
354 c = SetPixel(hdc, 0, 0, color); \
355 test_color_todo(c, exp, SetPixel, todo_setp); \
356 c = GetPixel(hdc, 0, 0); \
357 test_color_todo(c, exp, GetPixel, todo_getp); \
360 static void test_dib_bits_access( HBITMAP hdib, void *bits )
362 MEMORY_BASIC_INFORMATION info;
363 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
364 DWORD data[256];
365 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
366 HDC hdc;
367 char filename[MAX_PATH];
368 HANDLE file;
369 DWORD written;
370 INT ret;
372 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
373 "VirtualQuery failed\n");
374 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
375 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
376 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
377 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
378 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
379 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
381 memset( pbmi, 0, sizeof(bmibuf) );
382 memset( data, 0xcc, sizeof(data) );
383 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
384 pbmi->bmiHeader.biHeight = 16;
385 pbmi->bmiHeader.biWidth = 16;
386 pbmi->bmiHeader.biBitCount = 32;
387 pbmi->bmiHeader.biPlanes = 1;
388 pbmi->bmiHeader.biCompression = BI_RGB;
390 hdc = GetDC(0);
392 ret = SetDIBits( hdc, hdib, 0, 16, data, pbmi, DIB_RGB_COLORS );
393 ok(ret == 16, "SetDIBits failed: expected 16 got %d\n", ret);
395 ReleaseDC(0, hdc);
397 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
398 "VirtualQuery failed\n");
399 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
400 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
401 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
402 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
403 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
404 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
406 /* try writing protected bits to a file */
408 GetTempFileNameA( ".", "dib", 0, filename );
409 file = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
410 CREATE_ALWAYS, 0, 0 );
411 ok( file != INVALID_HANDLE_VALUE, "failed to open %s error %u\n", filename, GetLastError() );
412 ret = WriteFile( file, bits, 8192, &written, NULL );
413 ok( ret, "WriteFile failed error %u\n", GetLastError() );
414 if (ret) ok( written == 8192, "only wrote %u bytes\n", written );
415 CloseHandle( file );
416 DeleteFileA( filename );
419 static void test_dibsections(void)
421 HDC hdc, hdcmem, hdcmem2;
422 HBITMAP hdib, oldbm, hdib2, oldbm2;
423 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
424 char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
425 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
426 BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
427 HBITMAP hcoredib;
428 char coreBits[256];
429 BYTE *bits;
430 RGBQUAD rgb[256];
431 int ret;
432 char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
433 LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
434 WORD *index;
435 DWORD *bits32;
436 HPALETTE hpal, oldpal;
437 DIBSECTION dibsec;
438 COLORREF c0, c1;
439 int i;
440 int screen_depth;
441 MEMORY_BASIC_INFORMATION info;
443 hdc = GetDC(0);
444 screen_depth = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
446 memset(pbmi, 0, sizeof(bmibuf));
447 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
448 pbmi->bmiHeader.biHeight = 100;
449 pbmi->bmiHeader.biWidth = 512;
450 pbmi->bmiHeader.biBitCount = 24;
451 pbmi->bmiHeader.biPlanes = 1;
452 pbmi->bmiHeader.biCompression = BI_RGB;
454 SetLastError(0xdeadbeef);
456 /* invalid pointer for BITMAPINFO
457 (*bits should be NULL on error) */
458 bits = (BYTE*)0xdeadbeef;
459 hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
460 ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n");
462 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
463 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
464 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
465 ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
467 /* test the DIB memory */
468 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
469 "VirtualQuery failed\n");
470 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
471 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
472 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
473 ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
474 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
475 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
476 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
478 test_dib_bits_access( hdib, bits );
480 test_dib_info(hdib, bits, &pbmi->bmiHeader);
481 DeleteObject(hdib);
483 /* Test a top-down DIB. */
484 pbmi->bmiHeader.biHeight = -100;
485 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
486 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
487 test_dib_info(hdib, bits, &pbmi->bmiHeader);
488 DeleteObject(hdib);
490 pbmi->bmiHeader.biHeight = 100;
491 pbmi->bmiHeader.biBitCount = 8;
492 pbmi->bmiHeader.biCompression = BI_RLE8;
493 SetLastError(0xdeadbeef);
494 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
495 ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
496 ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
498 pbmi->bmiHeader.biBitCount = 16;
499 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
500 ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
501 ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
502 ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
503 SetLastError(0xdeadbeef);
504 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
505 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
507 /* test the DIB memory */
508 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
509 "VirtualQuery failed\n");
510 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
511 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
512 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
513 ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
514 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
515 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
516 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
518 test_dib_info(hdib, bits, &pbmi->bmiHeader);
519 DeleteObject(hdib);
521 memset(pbmi, 0, sizeof(bmibuf));
522 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
523 pbmi->bmiHeader.biHeight = 16;
524 pbmi->bmiHeader.biWidth = 16;
525 pbmi->bmiHeader.biBitCount = 1;
526 pbmi->bmiHeader.biPlanes = 1;
527 pbmi->bmiHeader.biCompression = BI_RGB;
528 pbmi->bmiColors[0].rgbRed = 0xff;
529 pbmi->bmiColors[0].rgbGreen = 0;
530 pbmi->bmiColors[0].rgbBlue = 0;
531 pbmi->bmiColors[1].rgbRed = 0;
532 pbmi->bmiColors[1].rgbGreen = 0;
533 pbmi->bmiColors[1].rgbBlue = 0xff;
535 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
536 ok(hdib != NULL, "CreateDIBSection failed\n");
537 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
538 ok(dibsec.dsBmih.biClrUsed == 2,
539 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
541 /* Test if the old BITMAPCOREINFO structure is supported */
543 pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
544 pbci->bmciHeader.bcBitCount = 0;
546 ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
547 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
548 ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
549 && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
550 "GetDIBits didn't fill in the BITMAPCOREHEADER structure properly\n");
552 ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
553 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
554 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
555 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
556 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
557 "The color table has not been translated to the old BITMAPCOREINFO format\n");
559 hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
560 ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
562 ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
563 ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
564 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
565 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
566 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
567 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
568 "The color table has not been translated to the old BITMAPCOREINFO format\n");
570 DeleteObject(hcoredib);
572 hdcmem = CreateCompatibleDC(hdc);
573 oldbm = SelectObject(hdcmem, hdib);
575 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
576 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
577 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
578 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
579 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
580 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
582 c0 = RGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen, pbmi->bmiColors[0].rgbBlue);
583 c1 = RGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen, pbmi->bmiColors[1].rgbBlue);
585 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
586 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
587 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
588 test_color(hdcmem, PALETTEINDEX(0), c0, 1, 1);
589 test_color(hdcmem, PALETTEINDEX(1), c0, 1, 1);
590 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
591 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen,
592 pbmi->bmiColors[0].rgbBlue), c0, 1, 1);
593 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen,
594 pbmi->bmiColors[1].rgbBlue), c1, 1, 1);
595 test_color(hdcmem, PALETTERGB(0, 0, 0), c0, 1, 1);
596 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
597 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1, 1, 1);
599 SelectObject(hdcmem, oldbm);
600 DeleteObject(hdib);
602 pbmi->bmiColors[0].rgbRed = 0xff;
603 pbmi->bmiColors[0].rgbGreen = 0xff;
604 pbmi->bmiColors[0].rgbBlue = 0xff;
605 pbmi->bmiColors[1].rgbRed = 0;
606 pbmi->bmiColors[1].rgbGreen = 0;
607 pbmi->bmiColors[1].rgbBlue = 0;
609 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
610 ok(hdib != NULL, "CreateDIBSection failed\n");
612 test_dib_info(hdib, bits, &pbmi->bmiHeader);
614 oldbm = SelectObject(hdcmem, hdib);
616 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
617 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
618 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
619 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
620 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
621 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
623 SelectObject(hdcmem, oldbm);
624 test_dib_info(hdib, bits, &pbmi->bmiHeader);
625 DeleteObject(hdib);
627 pbmi->bmiHeader.biBitCount = 4;
628 for (i = 0; i < 16; i++) {
629 pbmi->bmiColors[i].rgbRed = i;
630 pbmi->bmiColors[i].rgbGreen = 16-i;
631 pbmi->bmiColors[i].rgbBlue = 0;
633 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
634 ok(hdib != NULL, "CreateDIBSection failed\n");
635 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
636 ok(dibsec.dsBmih.biClrUsed == 16,
637 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
638 test_dib_info(hdib, bits, &pbmi->bmiHeader);
639 DeleteObject(hdib);
641 pbmi->bmiHeader.biBitCount = 8;
643 for (i = 0; i < 128; i++) {
644 pbmi->bmiColors[i].rgbRed = 255 - i * 2;
645 pbmi->bmiColors[i].rgbGreen = i * 2;
646 pbmi->bmiColors[i].rgbBlue = 0;
647 pbmi->bmiColors[255 - i].rgbRed = 0;
648 pbmi->bmiColors[255 - i].rgbGreen = i * 2;
649 pbmi->bmiColors[255 - i].rgbBlue = 255 - i * 2;
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 == 256,
655 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
657 oldbm = SelectObject(hdcmem, hdib);
659 for (i = 0; i < 256; i++) {
660 test_color(hdcmem, DIBINDEX(i),
661 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
662 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue),
663 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
666 SelectObject(hdcmem, oldbm);
667 test_dib_info(hdib, bits, &pbmi->bmiHeader);
668 DeleteObject(hdib);
670 pbmi->bmiHeader.biBitCount = 1;
672 /* Now create a palette and a palette indexed dib section */
673 memset(plogpal, 0, sizeof(logpalbuf));
674 plogpal->palVersion = 0x300;
675 plogpal->palNumEntries = 2;
676 plogpal->palPalEntry[0].peRed = 0xff;
677 plogpal->palPalEntry[0].peBlue = 0xff;
678 plogpal->palPalEntry[1].peGreen = 0xff;
680 index = (WORD*)pbmi->bmiColors;
681 *index++ = 0;
682 *index = 1;
683 hpal = CreatePalette(plogpal);
684 ok(hpal != NULL, "CreatePalette failed\n");
685 oldpal = SelectPalette(hdc, hpal, TRUE);
686 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
687 ok(hdib != NULL, "CreateDIBSection failed\n");
688 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
689 ok(dibsec.dsBmih.biClrUsed == 2, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
691 /* The colour table has already been grabbed from the dc, so we select back the
692 old palette */
694 SelectPalette(hdc, oldpal, TRUE);
695 oldbm = SelectObject(hdcmem, hdib);
696 oldpal = SelectPalette(hdcmem, hpal, TRUE);
698 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
699 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
700 ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
701 rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
702 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
703 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
704 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
706 c0 = RGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen, plogpal->palPalEntry[0].peBlue);
707 c1 = RGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen, plogpal->palPalEntry[1].peBlue);
709 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
710 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
711 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
712 test_color(hdcmem, PALETTEINDEX(0), c0, 0, 1);
713 test_color(hdcmem, PALETTEINDEX(1), c1, 0, 1);
714 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
715 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen,
716 plogpal->palPalEntry[0].peBlue), c0, 1, 1);
717 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen,
718 plogpal->palPalEntry[1].peBlue), c1, 1, 1);
719 test_color(hdcmem, PALETTERGB(0, 0, 0), c1, 1, 1);
720 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
721 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0, 1, 1);
722 test_color(hdcmem, PALETTERGB(0, 1, 0), c1, 1, 1);
723 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1, 1, 1);
724 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0, 1, 1);
726 /* Bottom and 2nd row from top green, everything else magenta */
727 bits[0] = bits[1] = 0xff;
728 bits[13 * 4] = bits[13*4 + 1] = 0xff;
730 test_dib_info(hdib, bits, &pbmi->bmiHeader);
732 pbmi->bmiHeader.biBitCount = 32;
734 hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
735 ok(hdib2 != NULL, "CreateDIBSection failed\n");
736 hdcmem2 = CreateCompatibleDC(hdc);
737 oldbm2 = SelectObject(hdcmem2, hdib2);
739 BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
741 ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
742 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
744 SelectObject(hdcmem2, oldbm2);
745 test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
746 DeleteObject(hdib2);
748 SelectObject(hdcmem, oldbm);
749 SelectPalette(hdcmem, oldpal, TRUE);
750 DeleteObject(hdib);
751 DeleteObject(hpal);
754 pbmi->bmiHeader.biBitCount = 8;
756 memset(plogpal, 0, sizeof(logpalbuf));
757 plogpal->palVersion = 0x300;
758 plogpal->palNumEntries = 256;
760 for (i = 0; i < 128; i++) {
761 plogpal->palPalEntry[i].peRed = 255 - i * 2;
762 plogpal->palPalEntry[i].peBlue = i * 2;
763 plogpal->palPalEntry[i].peGreen = 0;
764 plogpal->palPalEntry[255 - i].peRed = 0;
765 plogpal->palPalEntry[255 - i].peGreen = i * 2;
766 plogpal->palPalEntry[255 - i].peBlue = 255 - i * 2;
769 index = (WORD*)pbmi->bmiColors;
770 for (i = 0; i < 256; i++) {
771 *index++ = i;
774 hpal = CreatePalette(plogpal);
775 ok(hpal != NULL, "CreatePalette failed\n");
776 oldpal = SelectPalette(hdc, hpal, TRUE);
777 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
778 ok(hdib != NULL, "CreateDIBSection failed\n");
779 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
780 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
782 test_dib_info(hdib, bits, &pbmi->bmiHeader);
784 SelectPalette(hdc, oldpal, TRUE);
785 oldbm = SelectObject(hdcmem, hdib);
786 oldpal = SelectPalette(hdcmem, hpal, TRUE);
788 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
789 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
790 for (i = 0; i < 256; i++) {
791 ok(rgb[i].rgbRed == plogpal->palPalEntry[i].peRed &&
792 rgb[i].rgbBlue == plogpal->palPalEntry[i].peBlue &&
793 rgb[i].rgbGreen == plogpal->palPalEntry[i].peGreen,
794 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
795 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
798 for (i = 0; i < 256; i++) {
799 test_color(hdcmem, DIBINDEX(i),
800 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
801 test_color(hdcmem, PALETTEINDEX(i),
802 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
803 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue),
804 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
807 SelectPalette(hdcmem, oldpal, TRUE);
808 SelectObject(hdcmem, oldbm);
809 DeleteObject(hdib);
810 DeleteObject(hpal);
812 DeleteDC(hdcmem);
813 DeleteDC(hdcmem2);
814 ReleaseDC(0, hdc);
817 static void test_dib_formats(void)
819 char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256])];
820 BITMAPINFO *bi = (BITMAPINFO *)buffer;
821 char data[256];
822 void *bits;
823 int planes, bpp, compr;
824 HBITMAP hdib, hbmp;
825 HDC hdc, memdc;
826 UINT ret;
827 BOOL expect_ok, todo;
829 hdc = GetDC( 0 );
830 memdc = CreateCompatibleDC( 0 );
831 hbmp = CreateCompatibleBitmap( hdc, 10, 10 );
833 memset( data, 0xaa, sizeof(data) );
835 for (bpp = 0; bpp <= 64; bpp++)
837 for (planes = 0; planes <= 64; planes++)
839 for (compr = 0; compr < 8; compr++)
841 switch (bpp)
843 case 1:
844 case 4:
845 case 8:
846 case 24: expect_ok = (compr == BI_RGB); break;
847 case 16:
848 case 32: expect_ok = (compr == BI_RGB || compr == BI_BITFIELDS); break;
849 default: expect_ok = FALSE; break;
851 todo = (compr == BI_BITFIELDS); /* wine doesn't like strange bitfields */
853 memset( bi, 0, sizeof(bi->bmiHeader) );
854 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
855 bi->bmiHeader.biWidth = 2;
856 bi->bmiHeader.biHeight = 2;
857 bi->bmiHeader.biPlanes = planes;
858 bi->bmiHeader.biBitCount = bpp;
859 bi->bmiHeader.biCompression = compr;
860 bi->bmiHeader.biSizeImage = 0;
861 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
862 ret = GetDIBits(hdc, hbmp, 0, 0, data, bi, DIB_RGB_COLORS);
863 if (expect_ok || (!bpp && compr != BI_JPEG && compr != BI_PNG) ||
864 (bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8))
865 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
866 else
867 ok( !ret || broken(!bpp && (compr == BI_JPEG || compr == BI_PNG)), /* nt4 */
868 "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
870 /* all functions check planes except GetDIBits with 0 lines */
871 if (!planes) expect_ok = FALSE;
872 memset( bi, 0, sizeof(bi->bmiHeader) );
873 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
874 bi->bmiHeader.biWidth = 2;
875 bi->bmiHeader.biHeight = 2;
876 bi->bmiHeader.biPlanes = planes;
877 bi->bmiHeader.biBitCount = bpp;
878 bi->bmiHeader.biCompression = compr;
879 bi->bmiHeader.biSizeImage = 0;
880 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
882 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
883 if (expect_ok && (planes == 1 || planes * bpp <= 16))
884 ok( hdib != NULL, "CreateDIBSection failed for %u/%u/%u\n", bpp, planes, compr );
885 else
886 ok( hdib == NULL, "CreateDIBSection succeeded for %u/%u/%u\n", bpp, planes, compr );
887 if (hdib) DeleteObject( hdib );
889 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, data, bi, DIB_RGB_COLORS );
890 /* no sanity checks in CreateDIBitmap except compression */
891 if (compr == BI_JPEG || compr == BI_PNG)
892 ok( hdib == NULL || broken(hdib != NULL), /* nt4 */
893 "CreateDIBitmap succeeded for %u/%u/%u\n", bpp, planes, compr );
894 else
895 ok( hdib != NULL, "CreateDIBitmap failed for %u/%u/%u\n", bpp, planes, compr );
896 if (hdib) DeleteObject( hdib );
898 /* RLE needs a size */
899 bi->bmiHeader.biSizeImage = 0;
900 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
901 if (expect_ok)
903 if (todo)
904 todo_wine ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
905 else
906 ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
908 else
909 ok( !ret ||
910 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
911 "SetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
912 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
913 if (expect_ok)
915 if (todo)
916 todo_wine ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
917 else
918 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
920 else
921 ok( !ret ||
922 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
923 "SetDIBitsToDevice succeeded for %u/%u/%u\n", bpp, planes, compr );
924 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
925 if (expect_ok)
927 if (todo)
928 todo_wine ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
929 else
930 ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
932 else
933 ok( !ret ||
934 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
935 "StretchDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
937 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
938 if (expect_ok)
939 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
940 else
941 ok( !ret, "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
942 ok( bi->bmiHeader.biBitCount == bpp, "GetDIBits modified bpp %u/%u\n",
943 bpp, bi->bmiHeader.biBitCount );
945 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
946 bi->bmiHeader.biWidth = 2;
947 bi->bmiHeader.biHeight = 2;
948 bi->bmiHeader.biPlanes = planes;
949 bi->bmiHeader.biBitCount = bpp;
950 bi->bmiHeader.biCompression = compr;
951 bi->bmiHeader.biSizeImage = 1;
952 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
953 /* RLE allowed with valid biSizeImage */
954 if ((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)) expect_ok = TRUE;
956 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
957 if (expect_ok)
959 if (todo)
960 todo_wine ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
961 else
962 ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
964 else
965 ok( !ret, "SetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
966 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
967 if (expect_ok)
969 if (todo)
970 todo_wine ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
971 else
972 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
974 else
975 ok( !ret, "SetDIBitsToDevice succeeded for %u/%u/%u\n", bpp, planes, compr );
976 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
977 if (expect_ok)
979 if (todo)
980 todo_wine ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
981 else
982 ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
984 else
985 ok( !ret, "StretchDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
987 bi->bmiHeader.biSizeImage = 0;
988 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
989 if (expect_ok || !bpp)
990 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
991 else
992 ok( !ret, "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
997 memset( bi, 0, sizeof(bi->bmiHeader) );
998 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
999 bi->bmiHeader.biWidth = 2;
1000 bi->bmiHeader.biHeight = 2;
1001 bi->bmiHeader.biPlanes = 1;
1002 bi->bmiHeader.biBitCount = 16;
1003 bi->bmiHeader.biCompression = BI_BITFIELDS;
1004 bi->bmiHeader.biSizeImage = 0;
1005 *(DWORD *)&bi->bmiColors[0] = 0;
1006 *(DWORD *)&bi->bmiColors[1] = 0;
1007 *(DWORD *)&bi->bmiColors[2] = 0;
1009 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1010 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1011 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1012 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1013 /* other functions don't check */
1014 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1015 ok( hdib != NULL, "CreateDIBitmap failed with null bitfields\n" );
1016 DeleteObject( hdib );
1017 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1018 todo_wine ok( ret, "SetDIBitsToDevice failed with null bitfields\n" );
1019 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1020 todo_wine ok( ret, "StretchDIBits failed with null bitfields\n" );
1021 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1022 ok( ret, "GetDIBits failed with null bitfields\n" );
1023 bi->bmiHeader.biPlanes = 1;
1024 bi->bmiHeader.biBitCount = 16;
1025 bi->bmiHeader.biCompression = BI_BITFIELDS;
1026 bi->bmiHeader.biSizeImage = 0;
1027 *(DWORD *)&bi->bmiColors[0] = 0;
1028 *(DWORD *)&bi->bmiColors[1] = 0;
1029 *(DWORD *)&bi->bmiColors[2] = 0;
1030 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1031 ok( ret, "GetDIBits failed with null bitfields\n" );
1033 /* all fields must be non-zero */
1034 *(DWORD *)&bi->bmiColors[0] = 3;
1035 *(DWORD *)&bi->bmiColors[1] = 0;
1036 *(DWORD *)&bi->bmiColors[2] = 7;
1037 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1038 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1039 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1040 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1042 /* garbage is ok though */
1043 *(DWORD *)&bi->bmiColors[0] = 0x55;
1044 *(DWORD *)&bi->bmiColors[1] = 0x44;
1045 *(DWORD *)&bi->bmiColors[2] = 0x33;
1046 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1047 ok( hdib != NULL, "CreateDIBSection failed with bad bitfields\n" );
1048 if (hdib) DeleteObject( hdib );
1049 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1050 todo_wine ok( ret, "SetDIBits failed with bad bitfields\n" );
1052 bi->bmiHeader.biWidth = -2;
1053 bi->bmiHeader.biHeight = 2;
1054 bi->bmiHeader.biBitCount = 32;
1055 bi->bmiHeader.biCompression = BI_RGB;
1056 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1057 ok( hdib == NULL, "CreateDIBSection succeeded with negative width\n" );
1058 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1059 ok( hdib == NULL, "CreateDIBitmap succeeded with negative width\n" );
1060 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1061 ok( !ret, "SetDIBits succeeded with negative width\n" );
1062 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1063 ok( !ret, "SetDIBitsToDevice succeeded with negative width\n" );
1064 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1065 ok( !ret, "StretchDIBits succeeded with negative width\n" );
1066 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1067 ok( !ret, "GetDIBits succeeded with negative width\n" );
1068 bi->bmiHeader.biWidth = -2;
1069 bi->bmiHeader.biHeight = 2;
1070 bi->bmiHeader.biBitCount = 32;
1071 bi->bmiHeader.biCompression = BI_RGB;
1072 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1073 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with negative width\n" );
1075 bi->bmiHeader.biWidth = 0;
1076 bi->bmiHeader.biHeight = 2;
1077 bi->bmiHeader.biBitCount = 32;
1078 bi->bmiHeader.biCompression = BI_RGB;
1079 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1080 ok( hdib == NULL, "CreateDIBSection succeeded with zero width\n" );
1081 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1082 ok( hdib != NULL, "CreateDIBitmap failed with zero width\n" );
1083 DeleteObject( hdib );
1084 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1085 ok( !ret || broken(ret), /* nt4 */ "SetDIBits succeeded with zero width\n" );
1086 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1087 ok( !ret || broken(ret), /* nt4 */ "SetDIBitsToDevice succeeded with zero width\n" );
1088 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1089 ok( !ret || broken(ret), /* nt4 */ "StretchDIBits succeeded with zero width\n" );
1090 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1091 ok( !ret, "GetDIBits succeeded with zero width\n" );
1092 bi->bmiHeader.biWidth = 0;
1093 bi->bmiHeader.biHeight = 2;
1094 bi->bmiHeader.biBitCount = 32;
1095 bi->bmiHeader.biCompression = BI_RGB;
1096 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1097 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero width\n" );
1099 bi->bmiHeader.biWidth = 2;
1100 bi->bmiHeader.biHeight = 0;
1101 bi->bmiHeader.biBitCount = 32;
1102 bi->bmiHeader.biCompression = BI_RGB;
1103 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1104 ok( hdib == NULL, "CreateDIBSection succeeded with zero height\n" );
1105 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1106 ok( hdib != NULL, "CreateDIBitmap failed with zero height\n" );
1107 DeleteObject( hdib );
1108 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1109 ok( !ret, "SetDIBits succeeded with zero height\n" );
1110 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1111 ok( !ret, "SetDIBitsToDevice succeeded with zero height\n" );
1112 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1113 ok( !ret, "StretchDIBits succeeded with zero height\n" );
1114 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1115 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1116 bi->bmiHeader.biWidth = 2;
1117 bi->bmiHeader.biHeight = 0;
1118 bi->bmiHeader.biBitCount = 32;
1119 bi->bmiHeader.biCompression = BI_RGB;
1120 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1121 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1123 DeleteDC( memdc );
1124 DeleteObject( hbmp );
1125 ReleaseDC( 0, hdc );
1128 static void test_mono_dibsection(void)
1130 HDC hdc, memdc;
1131 HBITMAP old_bm, mono_ds;
1132 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
1133 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
1134 BYTE bits[10 * 4];
1135 BYTE *ds_bits;
1136 int num;
1138 hdc = GetDC(0);
1140 memdc = CreateCompatibleDC(hdc);
1142 memset(pbmi, 0, sizeof(bmibuf));
1143 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
1144 pbmi->bmiHeader.biHeight = 10;
1145 pbmi->bmiHeader.biWidth = 10;
1146 pbmi->bmiHeader.biBitCount = 1;
1147 pbmi->bmiHeader.biPlanes = 1;
1148 pbmi->bmiHeader.biCompression = BI_RGB;
1149 pbmi->bmiColors[0].rgbRed = 0xff;
1150 pbmi->bmiColors[0].rgbGreen = 0xff;
1151 pbmi->bmiColors[0].rgbBlue = 0xff;
1152 pbmi->bmiColors[1].rgbRed = 0x0;
1153 pbmi->bmiColors[1].rgbGreen = 0x0;
1154 pbmi->bmiColors[1].rgbBlue = 0x0;
1157 * First dib section is 'inverted' ie color[0] is white, color[1] is black
1160 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1161 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1162 old_bm = SelectObject(memdc, mono_ds);
1164 /* black border, white interior */
1165 Rectangle(memdc, 0, 0, 10, 10);
1166 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1167 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1169 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1171 memset(bits, 0, sizeof(bits));
1172 bits[0] = 0xaa;
1174 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1175 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1177 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1179 pbmi->bmiColors[0].rgbRed = 0x0;
1180 pbmi->bmiColors[0].rgbGreen = 0x0;
1181 pbmi->bmiColors[0].rgbBlue = 0x0;
1182 pbmi->bmiColors[1].rgbRed = 0xff;
1183 pbmi->bmiColors[1].rgbGreen = 0xff;
1184 pbmi->bmiColors[1].rgbBlue = 0xff;
1186 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1187 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1189 SelectObject(memdc, old_bm);
1190 DeleteObject(mono_ds);
1193 * Next dib section is 'normal' ie color[0] is black, color[1] is white
1196 pbmi->bmiColors[0].rgbRed = 0x0;
1197 pbmi->bmiColors[0].rgbGreen = 0x0;
1198 pbmi->bmiColors[0].rgbBlue = 0x0;
1199 pbmi->bmiColors[1].rgbRed = 0xff;
1200 pbmi->bmiColors[1].rgbGreen = 0xff;
1201 pbmi->bmiColors[1].rgbBlue = 0xff;
1203 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1204 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1205 old_bm = SelectObject(memdc, mono_ds);
1207 /* black border, white interior */
1208 Rectangle(memdc, 0, 0, 10, 10);
1209 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
1210 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
1212 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
1214 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1215 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1217 /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
1219 pbmi->bmiColors[0].rgbRed = 0xff;
1220 pbmi->bmiColors[0].rgbGreen = 0xff;
1221 pbmi->bmiColors[0].rgbBlue = 0xff;
1222 pbmi->bmiColors[1].rgbRed = 0x0;
1223 pbmi->bmiColors[1].rgbGreen = 0x0;
1224 pbmi->bmiColors[1].rgbBlue = 0x0;
1226 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1227 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1230 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
1233 pbmi->bmiColors[0].rgbRed = 0xff;
1234 pbmi->bmiColors[0].rgbGreen = 0xff;
1235 pbmi->bmiColors[0].rgbBlue = 0xff;
1236 pbmi->bmiColors[1].rgbRed = 0x0;
1237 pbmi->bmiColors[1].rgbGreen = 0x0;
1238 pbmi->bmiColors[1].rgbBlue = 0x0;
1239 num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors);
1240 ok(num == 2, "num = %d\n", num);
1242 /* black border, white interior */
1243 Rectangle(memdc, 0, 0, 10, 10);
1244 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1245 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1247 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1249 memset(bits, 0, sizeof(bits));
1250 bits[0] = 0xaa;
1252 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1253 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1255 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1257 pbmi->bmiColors[0].rgbRed = 0x0;
1258 pbmi->bmiColors[0].rgbGreen = 0x0;
1259 pbmi->bmiColors[0].rgbBlue = 0x0;
1260 pbmi->bmiColors[1].rgbRed = 0xff;
1261 pbmi->bmiColors[1].rgbGreen = 0xff;
1262 pbmi->bmiColors[1].rgbBlue = 0xff;
1264 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1265 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1267 SelectObject(memdc, old_bm);
1268 DeleteObject(mono_ds);
1271 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
1274 pbmi->bmiColors[0].rgbRed = 0xff;
1275 pbmi->bmiColors[0].rgbGreen = 0x0;
1276 pbmi->bmiColors[0].rgbBlue = 0x0;
1277 pbmi->bmiColors[1].rgbRed = 0xfe;
1278 pbmi->bmiColors[1].rgbGreen = 0x0;
1279 pbmi->bmiColors[1].rgbBlue = 0x0;
1281 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1282 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1283 old_bm = SelectObject(memdc, mono_ds);
1285 /* black border, white interior */
1286 Rectangle(memdc, 0, 0, 10, 10);
1287 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1288 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1290 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1292 pbmi->bmiColors[0].rgbRed = 0x0;
1293 pbmi->bmiColors[0].rgbGreen = 0x0;
1294 pbmi->bmiColors[0].rgbBlue = 0x0;
1295 pbmi->bmiColors[1].rgbRed = 0xff;
1296 pbmi->bmiColors[1].rgbGreen = 0xff;
1297 pbmi->bmiColors[1].rgbBlue = 0xff;
1299 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1300 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1302 /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
1304 pbmi->bmiColors[0].rgbRed = 0xff;
1305 pbmi->bmiColors[0].rgbGreen = 0xff;
1306 pbmi->bmiColors[0].rgbBlue = 0xff;
1307 pbmi->bmiColors[1].rgbRed = 0x0;
1308 pbmi->bmiColors[1].rgbGreen = 0x0;
1309 pbmi->bmiColors[1].rgbBlue = 0x0;
1311 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1312 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1314 SelectObject(memdc, old_bm);
1315 DeleteObject(mono_ds);
1317 DeleteDC(memdc);
1318 ReleaseDC(0, hdc);
1321 static void test_bitmap(void)
1323 char buf[256], buf_cmp[256];
1324 HBITMAP hbmp, hbmp_old;
1325 HDC hdc;
1326 BITMAP bm;
1327 BITMAP bma[2];
1328 INT ret;
1330 hdc = CreateCompatibleDC(0);
1331 assert(hdc != 0);
1333 SetLastError(0xdeadbeef);
1334 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1335 if (!hbmp)
1337 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1338 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1339 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1341 else
1342 DeleteObject(hbmp);
1344 SetLastError(0xdeadbeef);
1345 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1346 if (!hbmp)
1348 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1349 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1350 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1352 else
1353 DeleteObject(hbmp);
1355 SetLastError(0xdeadbeef);
1356 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1357 ok(!hbmp, "CreateBitmap should fail\n");
1358 if (!hbmp)
1359 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1360 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1361 else
1362 DeleteObject(hbmp);
1364 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1365 assert(hbmp != NULL);
1367 ret = GetObject(hbmp, sizeof(bm), &bm);
1368 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1370 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1371 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1372 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1373 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1374 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1375 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1376 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1378 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1379 assert(sizeof(buf) == sizeof(buf_cmp));
1381 ret = GetBitmapBits(hbmp, 0, NULL);
1382 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1384 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1385 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1387 memset(buf, 0xAA, sizeof(buf));
1388 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1389 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1390 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1392 hbmp_old = SelectObject(hdc, hbmp);
1394 ret = GetObject(hbmp, sizeof(bm), &bm);
1395 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1397 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1398 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1399 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1400 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1401 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1402 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1403 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
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_old);
1411 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1413 /* test various buffer sizes for GetObject */
1414 ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
1415 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1417 ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1418 ok(ret == 0, "%d != 0\n", ret);
1420 ret = GetObject(hbmp, 0, &bm);
1421 ok(ret == 0, "%d != 0\n", ret);
1423 ret = GetObject(hbmp, 1, &bm);
1424 ok(ret == 0, "%d != 0\n", ret);
1426 DeleteObject(hbmp);
1427 DeleteDC(hdc);
1430 static void test_bmBits(void)
1432 BYTE bits[4];
1433 HBITMAP hbmp;
1434 BITMAP bmp;
1436 memset(bits, 0, sizeof(bits));
1437 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1438 ok(hbmp != NULL, "CreateBitmap failed\n");
1440 memset(&bmp, 0xFF, sizeof(bmp));
1441 ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1442 "GetObject failed or returned a wrong structure size\n");
1443 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1445 DeleteObject(hbmp);
1448 static void test_GetDIBits_selected_DIB(UINT bpp)
1450 HBITMAP dib;
1451 char bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1452 char bmibuf2[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1453 BITMAPINFO *info = (BITMAPINFO *)bmibuf;
1454 BITMAPINFO *info2 = (BITMAPINFO *)bmibuf2;
1455 void * bits;
1456 void * bits2;
1457 UINT dib_size, dib32_size;
1458 DWORD pixel;
1459 HDC dib_dc, dc;
1460 HBITMAP old_bmp;
1461 UINT i;
1462 int res;
1464 /* Create a DIB section with a color table */
1466 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1467 info->bmiHeader.biWidth = 32;
1468 info->bmiHeader.biHeight = 32;
1469 info->bmiHeader.biPlanes = 1;
1470 info->bmiHeader.biBitCount = bpp;
1471 info->bmiHeader.biCompression = BI_RGB;
1472 info->bmiHeader.biXPelsPerMeter = 0;
1473 info->bmiHeader.biYPelsPerMeter = 0;
1474 info->bmiHeader.biClrUsed = 0;
1475 info->bmiHeader.biClrImportant = 0;
1477 for (i=0; i < (1u << bpp); i++)
1479 BYTE c = i * (1 << (8 - bpp));
1480 info->bmiColors[i].rgbRed = c;
1481 info->bmiColors[i].rgbGreen = c;
1482 info->bmiColors[i].rgbBlue = c;
1483 info->bmiColors[i].rgbReserved = 0;
1486 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1487 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1488 dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1490 /* Set the bits of the DIB section */
1491 for (i=0; i < dib_size; i++)
1493 ((BYTE *)bits)[i] = i % 256;
1496 /* Select the DIB into a DC */
1497 dib_dc = CreateCompatibleDC(NULL);
1498 old_bmp = SelectObject(dib_dc, dib);
1499 dc = CreateCompatibleDC(NULL);
1500 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
1502 /* Copy the DIB attributes but not the color table */
1503 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1505 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1506 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1508 /* Compare the color table and the bits */
1509 for (i=0; i < (1u << bpp); i++)
1510 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1511 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1512 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1513 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1514 "color table entry %d differs (bpp %d)\n", i, bpp );
1516 ok( !memcmp( bits, bits2, dib_size ), "bit mismatch (bpp %d)\n", bpp );
1518 /* Test various combinations of lines = 0 and bits2 = NULL */
1519 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1520 res = GetDIBits( dc, dib, 0, 0, bits2, info2, DIB_RGB_COLORS );
1521 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1522 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1523 "color table mismatch (bpp %d)\n", bpp );
1525 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1526 res = GetDIBits( dc, dib, 0, 0, NULL, info2, DIB_RGB_COLORS );
1527 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1528 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1529 "color table mismatch (bpp %d)\n", bpp );
1531 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1532 res = GetDIBits( dc, dib, 0, info->bmiHeader.biHeight, NULL, info2, DIB_RGB_COLORS );
1533 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1534 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1535 "color table mismatch (bpp %d)\n", bpp );
1537 /* Map into a 32bit-DIB */
1538 info2->bmiHeader.biBitCount = 32;
1539 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1540 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1542 /* Check if last pixel was set */
1543 pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
1544 ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
1546 HeapFree(GetProcessHeap(), 0, bits2);
1547 DeleteDC(dc);
1549 SelectObject(dib_dc, old_bmp);
1550 DeleteDC(dib_dc);
1551 DeleteObject(dib);
1554 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1556 HBITMAP ddb;
1557 char bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1558 char bmibuf2[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1559 BITMAPINFO *info = (BITMAPINFO *)bmibuf;
1560 BITMAPINFO *info2 = (BITMAPINFO *)bmibuf2;
1561 void * bits;
1562 void * bits2;
1563 HDC ddb_dc, dc;
1564 HBITMAP old_bmp;
1565 UINT width, height;
1566 UINT bpp;
1567 UINT i, j;
1568 int res;
1570 width = height = 16;
1572 /* Create a DDB (device-dependent bitmap) */
1573 if (monochrome)
1575 bpp = 1;
1576 ddb = CreateBitmap(width, height, 1, 1, NULL);
1578 else
1580 HDC screen_dc = GetDC(NULL);
1581 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1582 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1583 ReleaseDC(NULL, screen_dc);
1586 /* Set the pixels */
1587 ddb_dc = CreateCompatibleDC(NULL);
1588 old_bmp = SelectObject(ddb_dc, ddb);
1589 for (i = 0; i < width; i++)
1591 for (j=0; j < height; j++)
1593 BYTE c = (i * width + j) % 256;
1594 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1597 SelectObject(ddb_dc, old_bmp);
1599 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1600 info->bmiHeader.biWidth = width;
1601 info->bmiHeader.biHeight = height;
1602 info->bmiHeader.biPlanes = 1;
1603 info->bmiHeader.biBitCount = bpp;
1604 info->bmiHeader.biCompression = BI_RGB;
1606 dc = CreateCompatibleDC(NULL);
1608 /* Fill in biSizeImage */
1609 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1610 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1612 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1613 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1615 /* Get the bits */
1616 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1617 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1619 /* Copy the DIB attributes but not the color table */
1620 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1622 /* Select the DDB into another DC */
1623 old_bmp = SelectObject(ddb_dc, ddb);
1625 /* Get the bits */
1626 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1627 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1629 /* Compare the color table and the bits */
1630 if (bpp <= 8)
1632 for (i=0; i < (1u << bpp); i++)
1633 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1634 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1635 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1636 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1637 "color table entry %d differs (bpp %d)\n", i, bpp );
1640 ok( !memcmp( bits, bits2, info->bmiHeader.biSizeImage ), "bit mismatch (bpp %d)\n", bpp );
1642 /* Test the palette */
1643 if (info2->bmiHeader.biBitCount <= 8)
1645 WORD *colors = (WORD*)info2->bmiColors;
1647 /* Get the palette indices */
1648 res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1649 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1651 for (i = 0; i < (1 << info->bmiHeader.biBitCount); i++)
1652 ok( colors[i] == i, "%d: got %d (bpp %d)\n", i, colors[i], bpp );
1655 HeapFree(GetProcessHeap(), 0, bits2);
1656 HeapFree(GetProcessHeap(), 0, bits);
1657 DeleteDC(dc);
1659 SelectObject(ddb_dc, old_bmp);
1660 DeleteDC(ddb_dc);
1661 DeleteObject(ddb);
1664 static void test_GetDIBits(void)
1666 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1667 static const BYTE bmp_bits_1[16 * 2] =
1669 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1670 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1671 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1672 0xff,0xff, 0,0, 0xff,0xff, 0,0
1674 /* 4-bytes aligned 1-bit DIB data: 16x16 */
1675 static const BYTE dib_bits_1[16 * 4] =
1677 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1678 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1679 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1680 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1682 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1683 static const BYTE bmp_bits_24[16 * 16*3] =
1685 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1686 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1687 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1688 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1689 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1690 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1691 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1692 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1693 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1694 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1695 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1696 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1697 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1698 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1699 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1700 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1701 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1702 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1703 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1704 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1705 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1706 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1707 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1708 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1709 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1710 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1711 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1712 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1713 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1714 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1715 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1716 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 /* 4-bytes aligned 24-bit DIB data: 16x16 */
1719 static const BYTE dib_bits_24[16 * 16*3] =
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,
1735 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1736 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1737 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1738 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1739 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1740 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1741 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1742 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1743 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1744 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1745 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1746 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1747 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1748 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1749 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1750 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1751 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1752 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 HBITMAP hbmp;
1755 BITMAP bm;
1756 HDC hdc;
1757 int i, bytes, lines;
1758 BYTE buf[1024];
1759 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1760 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1761 PALETTEENTRY pal_ents[20];
1763 hdc = GetDC(0);
1765 /* 1-bit source bitmap data */
1766 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1767 ok(hbmp != 0, "CreateBitmap failed\n");
1769 memset(&bm, 0xAA, sizeof(bm));
1770 bytes = GetObject(hbmp, sizeof(bm), &bm);
1771 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1772 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1773 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1774 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1775 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1776 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1777 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1778 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1780 bytes = GetBitmapBits(hbmp, 0, NULL);
1781 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1782 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1783 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1784 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1786 /* retrieve 1-bit DIB data */
1787 memset(bi, 0, sizeof(*bi));
1788 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1789 bi->bmiHeader.biWidth = bm.bmWidth;
1790 bi->bmiHeader.biHeight = bm.bmHeight;
1791 bi->bmiHeader.biPlanes = 1;
1792 bi->bmiHeader.biBitCount = 1;
1793 bi->bmiHeader.biCompression = BI_RGB;
1794 bi->bmiHeader.biSizeImage = 0;
1795 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1796 SetLastError(0xdeadbeef);
1797 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1798 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1799 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1800 broken(GetLastError() == 0xdeadbeef), /* winnt */
1801 "wrong error %u\n", GetLastError());
1802 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1804 memset(buf, 0xAA, sizeof(buf));
1805 SetLastError(0xdeadbeef);
1806 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1807 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1808 lines, bm.bmHeight, GetLastError());
1809 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1811 /* the color table consists of black and white */
1812 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1813 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1814 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1815 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1816 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1817 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1818 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1819 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1820 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1821 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1822 for (i = 2; i < 256; i++)
1824 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1825 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1826 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1827 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1828 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1831 /* returned bits are DWORD aligned and upside down */
1832 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1834 /* Test the palette indices */
1835 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1836 SetLastError(0xdeadbeef);
1837 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1838 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1839 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1840 for (i = 2; i < 256; i++)
1841 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[1]);
1843 /* retrieve 24-bit DIB data */
1844 memset(bi, 0, sizeof(*bi));
1845 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1846 bi->bmiHeader.biWidth = bm.bmWidth;
1847 bi->bmiHeader.biHeight = bm.bmHeight;
1848 bi->bmiHeader.biPlanes = 1;
1849 bi->bmiHeader.biBitCount = 24;
1850 bi->bmiHeader.biCompression = BI_RGB;
1851 bi->bmiHeader.biSizeImage = 0;
1852 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1853 memset(buf, 0xAA, sizeof(buf));
1854 SetLastError(0xdeadbeef);
1855 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1856 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1857 lines, bm.bmHeight, GetLastError());
1858 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1860 /* the color table doesn't exist for 24-bit images */
1861 for (i = 0; i < 256; i++)
1863 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1864 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1865 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1866 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1867 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1870 /* returned bits are DWORD aligned and upside down */
1871 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1872 DeleteObject(hbmp);
1874 /* 24-bit source bitmap data */
1875 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1876 ok(hbmp != 0, "CreateBitmap failed\n");
1877 SetLastError(0xdeadbeef);
1878 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1879 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1880 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1881 lines, bm.bmHeight, GetLastError());
1883 memset(&bm, 0xAA, sizeof(bm));
1884 bytes = GetObject(hbmp, sizeof(bm), &bm);
1885 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1886 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1887 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1888 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1889 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1890 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1891 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1892 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1894 bytes = GetBitmapBits(hbmp, 0, NULL);
1895 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
1896 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1897 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1898 bm.bmWidthBytes * bm.bmHeight, bytes);
1900 /* retrieve 1-bit DIB data */
1901 memset(bi, 0, sizeof(*bi));
1902 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1903 bi->bmiHeader.biWidth = bm.bmWidth;
1904 bi->bmiHeader.biHeight = bm.bmHeight;
1905 bi->bmiHeader.biPlanes = 1;
1906 bi->bmiHeader.biBitCount = 1;
1907 bi->bmiHeader.biCompression = BI_RGB;
1908 bi->bmiHeader.biSizeImage = 0;
1909 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1910 memset(buf, 0xAA, sizeof(buf));
1911 SetLastError(0xdeadbeef);
1912 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1913 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1914 lines, bm.bmHeight, GetLastError());
1915 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1917 /* the color table consists of black and white */
1918 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1919 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1920 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1921 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1922 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1923 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1924 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1925 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1926 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1927 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1928 for (i = 2; i < 256; i++)
1930 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1931 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1932 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1933 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1934 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1937 /* returned bits are DWORD aligned and upside down */
1938 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1940 /* Test the palette indices */
1941 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1942 SetLastError(0xdeadbeef);
1943 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1944 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1945 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1946 for (i = 2; i < 256; i++)
1947 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[i]);
1949 /* retrieve 4-bit DIB data */
1950 memset(bi, 0, sizeof(*bi));
1951 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1952 bi->bmiHeader.biWidth = bm.bmWidth;
1953 bi->bmiHeader.biHeight = bm.bmHeight;
1954 bi->bmiHeader.biPlanes = 1;
1955 bi->bmiHeader.biBitCount = 4;
1956 bi->bmiHeader.biCompression = BI_RGB;
1957 bi->bmiHeader.biSizeImage = 0;
1958 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1959 memset(buf, 0xAA, sizeof(buf));
1960 SetLastError(0xdeadbeef);
1961 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1962 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1963 lines, bm.bmHeight, GetLastError());
1965 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
1967 for (i = 0; i < 16; i++)
1969 RGBQUAD expect;
1970 int entry = i < 8 ? i : i + 4;
1972 if(entry == 7) entry = 12;
1973 else if(entry == 12) entry = 7;
1975 expect.rgbRed = pal_ents[entry].peRed;
1976 expect.rgbGreen = pal_ents[entry].peGreen;
1977 expect.rgbBlue = pal_ents[entry].peBlue;
1978 expect.rgbReserved = 0;
1980 ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
1981 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
1982 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
1983 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1984 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1987 /* retrieve 8-bit DIB data */
1988 memset(bi, 0, sizeof(*bi));
1989 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1990 bi->bmiHeader.biWidth = bm.bmWidth;
1991 bi->bmiHeader.biHeight = bm.bmHeight;
1992 bi->bmiHeader.biPlanes = 1;
1993 bi->bmiHeader.biBitCount = 8;
1994 bi->bmiHeader.biCompression = BI_RGB;
1995 bi->bmiHeader.biSizeImage = 0;
1996 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1997 memset(buf, 0xAA, sizeof(buf));
1998 SetLastError(0xdeadbeef);
1999 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2000 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2001 lines, bm.bmHeight, GetLastError());
2003 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2005 for (i = 0; i < 256; i++)
2007 RGBQUAD expect;
2009 if (i < 10 || i >= 246)
2011 int entry = i < 10 ? i : i - 236;
2012 expect.rgbRed = pal_ents[entry].peRed;
2013 expect.rgbGreen = pal_ents[entry].peGreen;
2014 expect.rgbBlue = pal_ents[entry].peBlue;
2016 else
2018 expect.rgbRed = (i & 0x07) << 5;
2019 expect.rgbGreen = (i & 0x38) << 2;
2020 expect.rgbBlue = i & 0xc0;
2022 expect.rgbReserved = 0;
2024 ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
2025 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2026 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2027 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
2028 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
2031 /* retrieve 24-bit DIB data */
2032 memset(bi, 0, sizeof(*bi));
2033 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2034 bi->bmiHeader.biWidth = bm.bmWidth;
2035 bi->bmiHeader.biHeight = bm.bmHeight;
2036 bi->bmiHeader.biPlanes = 1;
2037 bi->bmiHeader.biBitCount = 24;
2038 bi->bmiHeader.biCompression = BI_RGB;
2039 bi->bmiHeader.biSizeImage = 0;
2040 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
2041 memset(buf, 0xAA, sizeof(buf));
2042 SetLastError(0xdeadbeef);
2043 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2044 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2045 lines, bm.bmHeight, GetLastError());
2046 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2048 /* the color table doesn't exist for 24-bit images */
2049 for (i = 0; i < 256; i++)
2051 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
2052 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
2053 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2054 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
2055 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
2058 /* returned bits are DWORD aligned and upside down */
2059 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2060 DeleteObject(hbmp);
2062 ReleaseDC(0, hdc);
2065 static void test_GetDIBits_BI_BITFIELDS(void)
2067 /* Try a screen resolution detection technique
2068 * from the September 1999 issue of Windows Developer's Journal
2069 * which seems to be in widespread use.
2070 * http://www.lesher.ws/highcolor.html
2071 * http://www.lesher.ws/vidfmt.c
2072 * It hinges on being able to retrieve the bitmaps
2073 * for the three primary colors in non-paletted 16 bit mode.
2075 char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
2076 DWORD bits[32];
2077 LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
2078 DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
2079 HDC hdc;
2080 HBITMAP hbm;
2081 int ret;
2082 void *ptr;
2084 memset(dibinfo, 0, sizeof(dibinfo_buf));
2085 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2087 hdc = GetDC(NULL);
2088 ok(hdc != NULL, "GetDC failed?\n");
2089 hbm = CreateCompatibleBitmap(hdc, 1, 1);
2090 ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
2092 /* Call GetDIBits to fill in bmiHeader. */
2093 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2094 ok(ret == 1, "GetDIBits failed\n");
2095 if (dibinfo->bmiHeader.biBitCount > 8)
2097 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2098 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2099 "compression is %u (%d bpp)\n", dibinfo->bmiHeader.biCompression, dibinfo->bmiHeader.biBitCount );
2101 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2103 ok( !bitmasks[0], "red mask is set\n" );
2104 ok( !bitmasks[1], "green mask is set\n" );
2105 ok( !bitmasks[2], "blue mask is set\n" );
2107 /* test with NULL bits pointer and correct bpp */
2108 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2109 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2110 ok(ret == 1, "GetDIBits failed\n");
2112 ok( bitmasks[0] != 0, "red mask is not set\n" );
2113 ok( bitmasks[1] != 0, "green mask is not set\n" );
2114 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2115 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2117 /* test with valid bits pointer */
2118 memset(dibinfo, 0, sizeof(dibinfo_buf));
2119 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2120 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2121 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2122 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2123 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2124 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2126 ok( bitmasks[0] != 0, "red mask is not set\n" );
2127 ok( bitmasks[1] != 0, "green mask is not set\n" );
2128 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2129 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2131 /* now with bits and 0 lines */
2132 memset(dibinfo, 0, sizeof(dibinfo_buf));
2133 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2134 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2135 SetLastError(0xdeadbeef);
2136 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2137 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2139 ok( !bitmasks[0], "red mask is set\n" );
2140 ok( !bitmasks[1], "green mask is set\n" );
2141 ok( !bitmasks[2], "blue mask is set\n" );
2142 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2144 memset(bitmasks, 0, 3*sizeof(DWORD));
2145 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2146 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2147 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2149 ok( bitmasks[0] != 0, "red mask is not set\n" );
2150 ok( bitmasks[1] != 0, "green mask is not set\n" );
2151 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2152 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2155 else skip("bitmap in colortable mode, skipping BI_BITFIELDS tests\n");
2157 DeleteObject(hbm);
2159 /* same thing now with a 32-bpp DIB section */
2161 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2162 dibinfo->bmiHeader.biWidth = 1;
2163 dibinfo->bmiHeader.biHeight = 1;
2164 dibinfo->bmiHeader.biPlanes = 1;
2165 dibinfo->bmiHeader.biBitCount = 32;
2166 dibinfo->bmiHeader.biCompression = BI_RGB;
2167 dibinfo->bmiHeader.biSizeImage = 0;
2168 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2169 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2170 dibinfo->bmiHeader.biClrUsed = 0;
2171 dibinfo->bmiHeader.biClrImportant = 0;
2172 bitmasks[0] = 0x0000ff;
2173 bitmasks[1] = 0x00ff00;
2174 bitmasks[2] = 0xff0000;
2175 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2176 ok( hbm != 0, "failed to create bitmap\n" );
2178 memset(dibinfo, 0, sizeof(dibinfo_buf));
2179 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2180 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2181 ok(ret == 1, "GetDIBits failed\n");
2182 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2184 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2185 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2186 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2187 ok( !bitmasks[0], "red mask is set\n" );
2188 ok( !bitmasks[1], "green mask is set\n" );
2189 ok( !bitmasks[2], "blue mask is set\n" );
2191 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2192 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2193 ok(ret == 1, "GetDIBits failed\n");
2194 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2195 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2196 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2197 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2198 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2200 ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
2201 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2202 ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
2204 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2206 DeleteObject(hbm);
2208 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2209 dibinfo->bmiHeader.biWidth = 1;
2210 dibinfo->bmiHeader.biHeight = 1;
2211 dibinfo->bmiHeader.biPlanes = 1;
2212 dibinfo->bmiHeader.biBitCount = 32;
2213 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2214 dibinfo->bmiHeader.biSizeImage = 0;
2215 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2216 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2217 dibinfo->bmiHeader.biClrUsed = 0;
2218 dibinfo->bmiHeader.biClrImportant = 0;
2219 bitmasks[0] = 0x0000ff;
2220 bitmasks[1] = 0x00ff00;
2221 bitmasks[2] = 0xff0000;
2222 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2223 ok( hbm != 0, "failed to create bitmap\n" );
2225 if (hbm)
2227 memset(dibinfo, 0, sizeof(dibinfo_buf));
2228 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2229 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2230 ok(ret == 1, "GetDIBits failed\n");
2232 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
2233 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2234 ok( !bitmasks[0], "red mask is set\n" );
2235 ok( !bitmasks[1], "green mask is set\n" );
2236 ok( !bitmasks[2], "blue mask is set\n" );
2238 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2239 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2240 ok(ret == 1, "GetDIBits failed\n");
2241 ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
2242 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2243 ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
2244 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2246 DeleteObject(hbm);
2249 /* 24-bpp DIB sections don't have bitfields */
2251 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2252 dibinfo->bmiHeader.biWidth = 1;
2253 dibinfo->bmiHeader.biHeight = 1;
2254 dibinfo->bmiHeader.biPlanes = 1;
2255 dibinfo->bmiHeader.biBitCount = 24;
2256 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2257 dibinfo->bmiHeader.biSizeImage = 0;
2258 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2259 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2260 dibinfo->bmiHeader.biClrUsed = 0;
2261 dibinfo->bmiHeader.biClrImportant = 0;
2262 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2263 ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
2264 dibinfo->bmiHeader.biCompression = BI_RGB;
2265 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2266 ok( hbm != 0, "failed to create bitmap\n" );
2268 memset(dibinfo, 0, sizeof(dibinfo_buf));
2269 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2270 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2271 ok(ret == 1, "GetDIBits failed\n");
2272 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2274 ok( dibinfo->bmiHeader.biCompression == BI_RGB,
2275 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2276 ok( !bitmasks[0], "red mask is set\n" );
2277 ok( !bitmasks[1], "green mask is set\n" );
2278 ok( !bitmasks[2], "blue mask is set\n" );
2280 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2281 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2282 ok(ret == 1, "GetDIBits failed\n");
2283 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2284 ok( !bitmasks[0], "red mask is set\n" );
2285 ok( !bitmasks[1], "green mask is set\n" );
2286 ok( !bitmasks[2], "blue mask is set\n" );
2287 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2289 DeleteObject(hbm);
2290 ReleaseDC(NULL, hdc);
2293 static void test_select_object(void)
2295 HDC hdc;
2296 HBITMAP hbm, hbm_old;
2297 INT planes, bpp, i;
2298 DWORD depths[] = {8, 15, 16, 24, 32};
2299 BITMAP bm;
2300 DWORD bytes;
2302 hdc = GetDC(0);
2303 ok(hdc != 0, "GetDC(0) failed\n");
2304 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2305 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2307 hbm_old = SelectObject(hdc, hbm);
2308 ok(hbm_old == 0, "SelectObject should fail\n");
2310 DeleteObject(hbm);
2311 ReleaseDC(0, hdc);
2313 hdc = CreateCompatibleDC(0);
2314 ok(hdc != 0, "GetDC(0) failed\n");
2315 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2316 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2318 hbm_old = SelectObject(hdc, hbm);
2319 ok(hbm_old != 0, "SelectObject failed\n");
2320 hbm_old = SelectObject(hdc, hbm_old);
2321 ok(hbm_old == hbm, "SelectObject failed\n");
2323 DeleteObject(hbm);
2325 /* test an 1-bpp bitmap */
2326 planes = GetDeviceCaps(hdc, PLANES);
2327 bpp = 1;
2329 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
2330 ok(hbm != 0, "CreateBitmap failed\n");
2332 hbm_old = SelectObject(hdc, hbm);
2333 ok(hbm_old != 0, "SelectObject failed\n");
2334 hbm_old = SelectObject(hdc, hbm_old);
2335 ok(hbm_old == hbm, "SelectObject failed\n");
2337 DeleteObject(hbm);
2339 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
2340 /* test a color bitmap to dc bpp matching */
2341 planes = GetDeviceCaps(hdc, PLANES);
2342 bpp = GetDeviceCaps(hdc, BITSPIXEL);
2344 hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
2345 ok(hbm != 0, "CreateBitmap failed\n");
2347 hbm_old = SelectObject(hdc, hbm);
2348 if(depths[i] == bpp ||
2349 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
2351 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
2352 SelectObject(hdc, hbm_old);
2353 } else {
2354 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
2357 memset(&bm, 0xAA, sizeof(bm));
2358 bytes = GetObject(hbm, sizeof(bm), &bm);
2359 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2360 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2361 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
2362 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
2363 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2364 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
2365 if(depths[i] == 15) {
2366 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
2367 } else {
2368 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2370 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2372 DeleteObject(hbm);
2375 DeleteDC(hdc);
2378 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
2380 INT ret;
2381 BITMAP bm;
2383 ret = GetObjectType(hbmp);
2384 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
2386 ret = GetObject(hbmp, 0, 0);
2387 ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
2389 memset(&bm, 0xDA, sizeof(bm));
2390 SetLastError(0xdeadbeef);
2391 ret = GetObject(hbmp, sizeof(bm), &bm);
2392 if (!ret) /* XP, only for curObj2 */ return;
2393 ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
2394 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2395 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2396 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2397 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2398 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2399 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2400 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2403 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2405 static void test_CreateBitmap(void)
2407 BITMAP bmp;
2408 HDC screenDC = GetDC(0);
2409 HDC hdc = CreateCompatibleDC(screenDC);
2410 UINT i, expect = 0;
2412 /* all of these are the stock monochrome bitmap */
2413 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2414 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2415 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2416 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2417 HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2418 HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2420 /* these 2 are not the stock monochrome bitmap */
2421 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2422 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2424 HBITMAP old1 = SelectObject(hdc, bm2);
2425 HBITMAP old2 = SelectObject(screenDC, bm3);
2426 SelectObject(hdc, old1);
2427 SelectObject(screenDC, old2);
2429 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2430 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2431 bm, bm1, bm4, bm5, curObj1, old1);
2432 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2433 todo_wine
2434 ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
2435 ok(old2 == 0, "old2 %p\n", old2);
2437 test_mono_1x1_bmp(bm);
2438 test_mono_1x1_bmp(bm1);
2439 test_mono_1x1_bmp(bm2);
2440 test_mono_1x1_bmp(bm3);
2441 test_mono_1x1_bmp(bm4);
2442 test_mono_1x1_bmp(bm5);
2443 test_mono_1x1_bmp(old1);
2444 test_mono_1x1_bmp(curObj1);
2446 DeleteObject(bm);
2447 DeleteObject(bm1);
2448 DeleteObject(bm2);
2449 DeleteObject(bm3);
2450 DeleteObject(bm4);
2451 DeleteObject(bm5);
2453 DeleteDC(hdc);
2454 ReleaseDC(0, screenDC);
2456 /* show that Windows ignores the provided bm.bmWidthBytes */
2457 bmp.bmType = 0;
2458 bmp.bmWidth = 1;
2459 bmp.bmHeight = 1;
2460 bmp.bmWidthBytes = 28;
2461 bmp.bmPlanes = 1;
2462 bmp.bmBitsPixel = 1;
2463 bmp.bmBits = NULL;
2464 bm = CreateBitmapIndirect(&bmp);
2465 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2466 test_mono_1x1_bmp(bm);
2467 DeleteObject(bm);
2469 /* Test how the bmBitsPixel field is treated */
2470 for(i = 1; i <= 33; i++) {
2471 bmp.bmType = 0;
2472 bmp.bmWidth = 1;
2473 bmp.bmHeight = 1;
2474 bmp.bmWidthBytes = 28;
2475 bmp.bmPlanes = 1;
2476 bmp.bmBitsPixel = i;
2477 bmp.bmBits = NULL;
2478 SetLastError(0xdeadbeef);
2479 bm = CreateBitmapIndirect(&bmp);
2480 if(i > 32) {
2481 DWORD error = GetLastError();
2482 ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
2483 ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2484 DeleteObject(bm);
2485 continue;
2487 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2488 GetObject(bm, sizeof(bmp), &bmp);
2489 if(i == 1) {
2490 expect = 1;
2491 } else if(i <= 4) {
2492 expect = 4;
2493 } else if(i <= 8) {
2494 expect = 8;
2495 } else if(i <= 16) {
2496 expect = 16;
2497 } else if(i <= 24) {
2498 expect = 24;
2499 } else if(i <= 32) {
2500 expect = 32;
2502 ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2503 i, bmp.bmBitsPixel, expect);
2504 DeleteObject(bm);
2508 static void test_bitmapinfoheadersize(void)
2510 HBITMAP hdib;
2511 BITMAPINFO bmi;
2512 BITMAPCOREINFO bci;
2513 HDC hdc = GetDC(0);
2515 memset(&bmi, 0, sizeof(BITMAPINFO));
2516 bmi.bmiHeader.biHeight = 100;
2517 bmi.bmiHeader.biWidth = 512;
2518 bmi.bmiHeader.biBitCount = 24;
2519 bmi.bmiHeader.biPlanes = 1;
2521 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2523 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2524 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2526 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2528 SetLastError(0xdeadbeef);
2529 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2530 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2531 DeleteObject(hdib);
2533 bmi.bmiHeader.biSize++;
2535 SetLastError(0xdeadbeef);
2536 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2537 ok(hdib != NULL ||
2538 broken(!hdib), /* Win98, WinMe */
2539 "CreateDIBSection error %d\n", GetLastError());
2540 DeleteObject(hdib);
2542 bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2544 SetLastError(0xdeadbeef);
2545 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2546 ok(hdib != NULL ||
2547 broken(!hdib), /* Win98, WinMe */
2548 "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(BITMAPV4HEADER);
2562 SetLastError(0xdeadbeef);
2563 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2564 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2565 DeleteObject(hdib);
2567 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2569 SetLastError(0xdeadbeef);
2570 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2571 ok(hdib != NULL ||
2572 broken(!hdib), /* Win95 */
2573 "CreateDIBSection error %d\n", GetLastError());
2574 DeleteObject(hdib);
2576 memset(&bci, 0, sizeof(BITMAPCOREINFO));
2577 bci.bmciHeader.bcHeight = 100;
2578 bci.bmciHeader.bcWidth = 512;
2579 bci.bmciHeader.bcBitCount = 24;
2580 bci.bmciHeader.bcPlanes = 1;
2582 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2584 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2585 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2587 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2589 SetLastError(0xdeadbeef);
2590 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2591 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2592 DeleteObject(hdib);
2594 bci.bmciHeader.bcSize++;
2596 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2597 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2599 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2601 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2602 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2604 ReleaseDC(0, hdc);
2607 static void test_get16dibits(void)
2609 BYTE bits[4 * (16 / sizeof(BYTE))];
2610 HBITMAP hbmp;
2611 HDC screen_dc = GetDC(NULL);
2612 int ret;
2613 BITMAPINFO * info;
2614 int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2615 BYTE *p;
2616 int overwritten_bytes = 0;
2618 memset(bits, 0, sizeof(bits));
2619 hbmp = CreateBitmap(2, 2, 1, 16, bits);
2620 ok(hbmp != NULL, "CreateBitmap failed\n");
2622 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2623 assert(info);
2625 memset(info, '!', info_len);
2626 memset(info, 0, sizeof(info->bmiHeader));
2628 info->bmiHeader.biSize = sizeof(info->bmiHeader);
2629 info->bmiHeader.biWidth = 2;
2630 info->bmiHeader.biHeight = 2;
2631 info->bmiHeader.biPlanes = 1;
2632 info->bmiHeader.biCompression = BI_RGB;
2634 ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2635 ok(ret != 0, "GetDIBits failed got %d\n", ret);
2637 for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2638 if (*p != '!')
2639 overwritten_bytes++;
2640 ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2642 HeapFree(GetProcessHeap(), 0, info);
2643 DeleteObject(hbmp);
2644 ReleaseDC(NULL, screen_dc);
2647 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2648 DWORD dwRop, UINT32 expected, int line)
2650 *srcBuffer = 0xFEDCBA98;
2651 *dstBuffer = 0x89ABCDEF;
2652 Rectangle(hdcSrc, 0, 0, 1, 1); /* A null operation to ensure dibs are coerced to X11 */
2653 BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
2654 ok(expected == *dstBuffer,
2655 "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2656 dwRop, expected, *dstBuffer, line);
2659 static void test_BitBlt(void)
2661 HBITMAP bmpDst, bmpSrc;
2662 HBITMAP oldDst, oldSrc;
2663 HDC hdcScreen, hdcDst, hdcSrc;
2664 UINT32 *dstBuffer, *srcBuffer;
2665 HBRUSH hBrush, hOldBrush;
2666 BITMAPINFO bitmapInfo;
2668 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2669 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2670 bitmapInfo.bmiHeader.biWidth = 1;
2671 bitmapInfo.bmiHeader.biHeight = 1;
2672 bitmapInfo.bmiHeader.biPlanes = 1;
2673 bitmapInfo.bmiHeader.biBitCount = 32;
2674 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2675 bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2677 hdcScreen = CreateCompatibleDC(0);
2678 hdcDst = CreateCompatibleDC(hdcScreen);
2679 hdcSrc = CreateCompatibleDC(hdcDst);
2681 /* Setup the destination dib section */
2682 bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
2683 NULL, 0);
2684 oldDst = SelectObject(hdcDst, bmpDst);
2686 hBrush = CreateSolidBrush(0x012345678);
2687 hOldBrush = SelectObject(hdcDst, hBrush);
2689 /* Setup the source dib section */
2690 bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
2691 NULL, 0);
2692 oldSrc = SelectObject(hdcSrc, bmpSrc);
2694 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2695 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2696 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2697 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2698 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2699 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2700 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2701 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2702 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2703 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2704 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2705 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2706 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2707 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2708 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2710 /* Tidy up */
2711 SelectObject(hdcSrc, oldSrc);
2712 DeleteObject(bmpSrc);
2713 DeleteDC(hdcSrc);
2715 SelectObject(hdcDst, hOldBrush);
2716 DeleteObject(hBrush);
2717 SelectObject(hdcDst, oldDst);
2718 DeleteObject(bmpDst);
2719 DeleteDC(hdcDst);
2722 DeleteDC(hdcScreen);
2725 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2726 DWORD dwRop, UINT32 expected, int line)
2728 *srcBuffer = 0xFEDCBA98;
2729 *dstBuffer = 0x89ABCDEF;
2730 StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
2731 ok(expected == *dstBuffer,
2732 "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2733 dwRop, expected, *dstBuffer, line);
2736 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, BITMAPINFO *dst_info, UINT32 *dstBuffer, UINT32 *srcBuffer,
2737 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2738 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2739 UINT32 *expected, int line)
2741 int dst_size = get_dib_image_size( dst_info );
2743 memset(dstBuffer, 0, dst_size);
2744 StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2745 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
2746 ok(memcmp(dstBuffer, expected, dst_size) == 0,
2747 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2748 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2749 expected[0], expected[1], expected[2], expected[3],
2750 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2751 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2752 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2755 static void test_StretchBlt(void)
2757 HBITMAP bmpDst, bmpSrc;
2758 HBITMAP oldDst, oldSrc;
2759 HDC hdcScreen, hdcDst, hdcSrc;
2760 UINT32 *dstBuffer, *srcBuffer;
2761 HBRUSH hBrush, hOldBrush;
2762 BITMAPINFO biDst, biSrc;
2763 UINT32 expected[256];
2765 memset(&biDst, 0, sizeof(BITMAPINFO));
2766 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2767 biDst.bmiHeader.biWidth = 16;
2768 biDst.bmiHeader.biHeight = -16;
2769 biDst.bmiHeader.biPlanes = 1;
2770 biDst.bmiHeader.biBitCount = 32;
2771 biDst.bmiHeader.biCompression = BI_RGB;
2772 memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
2774 hdcScreen = CreateCompatibleDC(0);
2775 hdcDst = CreateCompatibleDC(hdcScreen);
2776 hdcSrc = CreateCompatibleDC(hdcDst);
2778 /* Pixel Tests */
2779 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2780 NULL, 0);
2781 oldDst = SelectObject(hdcDst, bmpDst);
2783 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2784 NULL, 0);
2785 oldSrc = SelectObject(hdcSrc, bmpSrc);
2787 hBrush = CreateSolidBrush(0x012345678);
2788 hOldBrush = SelectObject(hdcDst, hBrush);
2790 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2791 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2792 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2793 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2794 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2795 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2796 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2797 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2798 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2799 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2800 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2801 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2802 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2803 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2804 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2806 SelectObject(hdcDst, hOldBrush);
2807 DeleteObject(hBrush);
2809 /* Top-down to top-down tests */
2810 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2811 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2813 memset( expected, 0, get_dib_image_size( &biDst ) );
2814 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2815 expected[16] = 0xFEDCBA98, expected[17] = 0x76543210;
2816 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2817 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2819 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2820 expected[16] = 0x00000000, expected[17] = 0x00000000;
2821 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2822 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
2824 expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
2825 expected[16] = 0xCAFED00D, expected[17] = 0xCAFED00D;
2826 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2827 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
2829 /* This is an example of the dst width (height) == 1 exception, explored below */
2830 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2831 expected[16] = 0x00000000, expected[17] = 0x00000000;
2832 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2833 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
2835 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2836 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
2837 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2838 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2840 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2841 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
2842 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2843 1, 1, -2, -2, 0, 0, 2, 2, expected, __LINE__);
2845 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2846 expected[16] = 0x00000000, expected[17] = 0x00000000;
2847 todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2848 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
2850 expected[0] = 0x00000000, expected[1] = 0x00000000;
2851 expected[16] = 0x00000000, expected[17] = 0xCAFED00D, expected[18] = 0xFEEDFACE;
2852 expected[32] = 0x00000000, expected[33] = 0xFEDCBA98, expected[34] = 0x76543210;
2854 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2855 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2857 /* when dst width is 1 merge src width - 1 pixels */
2858 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
2859 srcBuffer[0] = 0x0000ff00, srcBuffer[1] = 0x0000f0f0, srcBuffer[2] = 0x0000cccc, srcBuffer[3] = 0x0000aaaa;
2860 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2862 memset( expected, 0, get_dib_image_size( &biDst ) );
2863 expected[0] = srcBuffer[0];
2864 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2865 0, 0, 1, 1, 0, 0, 2, 1, expected, __LINE__);
2867 expected[0] = srcBuffer[0] & srcBuffer[1];
2868 todo_wine
2869 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2870 0, 0, 1, 1, 0, 0, 3, 1, expected, __LINE__);
2872 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
2873 todo_wine
2874 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2875 0, 0, 1, 1, 0, 0, 4, 1, expected, __LINE__);
2877 /* this doesn't happen if the src width is -ve */
2878 expected[0] = srcBuffer[1] & srcBuffer[2];
2879 todo_wine
2880 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2881 0, 0, 1, 1, 2, 0, -2, 1, expected, __LINE__);
2883 /* when dst width > 1 behaviour reverts to what one would expect */
2884 expected[0] = srcBuffer[0] & srcBuffer[1], expected[1] = srcBuffer[2] & srcBuffer[3];
2885 todo_wine
2886 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2887 0, 0, 2, 1, 0, 0, 4, 1, expected, __LINE__);
2889 /* similarly in the vertical direction */
2890 memset( expected, 0, get_dib_image_size( &biDst ) );
2891 expected[0] = srcBuffer[0];
2892 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2893 0, 0, 1, 1, 0, 0, 1, 2, expected, __LINE__);
2895 /* check that it's the dst size in device units that needs to be 1 */
2896 SetMapMode( hdcDst, MM_ISOTROPIC );
2897 SetWindowExtEx( hdcDst, 200, 200, NULL );
2898 SetViewportExtEx( hdcDst, 100, 100, NULL );
2900 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
2901 todo_wine
2902 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2903 0, 0, 2, 2, 0, 0, 4, 1, expected, __LINE__);
2904 SetMapMode( hdcDst, MM_TEXT );
2906 SelectObject(hdcDst, oldDst);
2907 DeleteObject(bmpDst);
2909 /* Top-down to bottom-up tests */
2910 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
2911 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2912 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2914 biDst.bmiHeader.biHeight = 16;
2915 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2916 NULL, 0);
2917 oldDst = SelectObject(hdcDst, bmpDst);
2919 memset( expected, 0, get_dib_image_size( &biDst ) );
2921 expected[224] = 0xFEDCBA98, expected[225] = 0x76543210;
2922 expected[240] = 0xCAFED00D, expected[241] = 0xFEEDFACE;
2923 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2924 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2926 expected[224] = 0xFEEDFACE, expected[225] = 0xCAFED00D;
2927 expected[240] = 0x76543210, expected[241] = 0xFEDCBA98;
2928 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2929 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2931 SelectObject(hdcSrc, oldSrc);
2932 DeleteObject(bmpSrc);
2934 /* Bottom-up to bottom-up tests */
2935 biSrc.bmiHeader.biHeight = 16;
2936 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2937 NULL, 0);
2938 srcBuffer[224] = 0xCAFED00D, srcBuffer[225] = 0xFEEDFACE;
2939 srcBuffer[240] = 0xFEDCBA98, srcBuffer[241] = 0x76543210;
2940 oldSrc = SelectObject(hdcSrc, bmpSrc);
2942 memset( expected, 0, get_dib_image_size( &biDst ) );
2944 expected[224] = 0xCAFED00D, expected[225] = 0xFEEDFACE;
2945 expected[240] = 0xFEDCBA98, expected[241] = 0x76543210;
2946 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2947 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2949 expected[224] = 0x76543210, expected[225] = 0xFEDCBA98;
2950 expected[240] = 0xFEEDFACE, expected[241] = 0xCAFED00D;
2951 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2952 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2954 SelectObject(hdcDst, oldDst);
2955 DeleteObject(bmpDst);
2957 /* Bottom-up to top-down tests */
2958 biDst.bmiHeader.biHeight = -16;
2959 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2960 NULL, 0);
2961 oldDst = SelectObject(hdcDst, bmpDst);
2963 memset( expected, 0, get_dib_image_size( &biDst ) );
2964 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2965 expected[16] = 0xCAFED00D, expected[17] = 0xFEEDFACE;
2966 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2967 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2969 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2970 expected[16] = 0x76543210, expected[17] = 0xFEDCBA98;
2971 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2972 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2974 SelectObject(hdcSrc, oldSrc);
2975 DeleteObject(bmpSrc);
2977 biSrc.bmiHeader.biHeight = -2;
2978 biSrc.bmiHeader.biBitCount = 24;
2979 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
2980 oldSrc = SelectObject(hdcSrc, bmpSrc);
2982 memset( expected, 0, get_dib_image_size( &biDst ) );
2983 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2984 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2985 memcpy(dstBuffer, expected, 4 * sizeof(*dstBuffer));
2986 StretchBlt(hdcSrc, 0, 0, 4, 1, hdcDst, 0, 0, 4, 1, SRCCOPY );
2987 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
2988 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
2989 expected[0] = 0x00EDFACE, expected[1] = 0x00FED00D;
2990 expected[2] = 0x00543210, expected[3] = 0x00DCBA98;
2991 ok(!memcmp(dstBuffer, expected, 16),
2992 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
2993 expected[0], expected[1], expected[2], expected[3],
2994 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
2996 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2997 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2998 memcpy(srcBuffer, expected, 4 * sizeof(*dstBuffer));
2999 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
3000 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3001 expected[0] = 0x00EDFACE, expected[1] = 0x00D00DFE;
3002 expected[2] = 0x0010CAFE, expected[3] = 0x00765432;
3003 ok(!memcmp(dstBuffer, expected, 16),
3004 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3005 expected[0], expected[1], expected[2], expected[3],
3006 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3008 SelectObject(hdcSrc, oldSrc);
3009 DeleteObject(bmpSrc);
3010 DeleteDC(hdcSrc);
3012 SelectObject(hdcDst, oldDst);
3013 DeleteObject(bmpDst);
3014 DeleteDC(hdcDst);
3016 DeleteDC(hdcScreen);
3019 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3020 DWORD dwRop, UINT32 expected, int line)
3022 const UINT32 buffer[2] = { 0xFEDCBA98, 0 };
3023 BITMAPINFO bitmapInfo;
3025 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3026 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3027 bitmapInfo.bmiHeader.biWidth = 2;
3028 bitmapInfo.bmiHeader.biHeight = 1;
3029 bitmapInfo.bmiHeader.biPlanes = 1;
3030 bitmapInfo.bmiHeader.biBitCount = 32;
3031 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3032 bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer);
3034 *dstBuffer = 0x89ABCDEF;
3036 StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop);
3037 ok(expected == *dstBuffer,
3038 "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
3039 dwRop, expected, *dstBuffer, line);
3042 static void check_StretchDIBits_stretch(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3043 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
3044 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
3045 UINT32 expected[4], UINT32 legacy_expected[4], int line)
3047 BITMAPINFO bitmapInfo;
3049 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3050 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3051 bitmapInfo.bmiHeader.biWidth = 2;
3052 bitmapInfo.bmiHeader.biHeight = -2;
3053 bitmapInfo.bmiHeader.biPlanes = 1;
3054 bitmapInfo.bmiHeader.biBitCount = 32;
3055 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3057 memset(dstBuffer, 0, 16);
3058 StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
3059 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3060 srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
3061 ok(memcmp(dstBuffer, expected, 16) == 0,
3062 "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
3063 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
3064 expected[0], expected[1], expected[2], expected[3],
3065 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
3066 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3067 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
3070 static void test_StretchDIBits(void)
3072 HBITMAP bmpDst;
3073 HBITMAP oldDst;
3074 HDC hdcScreen, hdcDst;
3075 UINT32 *dstBuffer, srcBuffer[4];
3076 HBRUSH hBrush, hOldBrush;
3077 BITMAPINFO biDst;
3078 UINT32 expected[4], legacy_expected[4];
3080 memset(&biDst, 0, sizeof(BITMAPINFO));
3081 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3082 biDst.bmiHeader.biWidth = 2;
3083 biDst.bmiHeader.biHeight = -2;
3084 biDst.bmiHeader.biPlanes = 1;
3085 biDst.bmiHeader.biBitCount = 32;
3086 biDst.bmiHeader.biCompression = BI_RGB;
3088 hdcScreen = CreateCompatibleDC(0);
3089 hdcDst = CreateCompatibleDC(hdcScreen);
3091 /* Pixel Tests */
3092 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3093 NULL, 0);
3094 oldDst = SelectObject(hdcDst, bmpDst);
3096 hBrush = CreateSolidBrush(0x012345678);
3097 hOldBrush = SelectObject(hdcDst, hBrush);
3099 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3100 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3101 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3102 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3103 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3104 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3105 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3106 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3107 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3108 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3109 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3110 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3111 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3112 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3113 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3115 SelectObject(hdcDst, hOldBrush);
3116 DeleteObject(hBrush);
3118 /* Top-down destination tests */
3119 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3120 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
3122 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
3123 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
3124 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3125 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
3127 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3128 expected[2] = 0x00000000, expected[3] = 0x00000000;
3129 legacy_expected[0] = 0xFEDCBA98, legacy_expected[1] = 0x00000000;
3130 legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
3131 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3132 0, 0, 1, 1, 0, 0, 1, 1, expected, legacy_expected, __LINE__);
3134 expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
3135 expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
3136 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3137 0, 0, 2, 2, 0, 0, 1, 1, expected, expected, __LINE__);
3139 expected[0] = 0x42441000, expected[1] = 0x00000000;
3140 expected[2] = 0x00000000, expected[3] = 0x00000000;
3141 legacy_expected[0] = 0x00543210, legacy_expected[1] = 0x00000000;
3142 legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
3143 todo_wine check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3144 0, 0, 1, 1, 0, 0, 2, 2, expected, legacy_expected, __LINE__);
3146 expected[0] = 0x00000000, expected[1] = 0x00000000;
3147 expected[2] = 0x00000000, expected[3] = 0x00000000;
3148 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3149 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
3151 expected[0] = 0x00000000, expected[1] = 0x00000000;
3152 expected[2] = 0x00000000, expected[3] = 0x00000000;
3153 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3154 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
3156 expected[0] = 0x00000000, expected[1] = 0x00000000;
3157 expected[2] = 0x00000000, expected[3] = 0x00000000;
3158 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3159 1, 1, -2, -2, 1, 1, -2, -2, expected, expected, __LINE__);
3161 expected[0] = 0x00000000, expected[1] = 0x00000000;
3162 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
3163 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3164 1, 1, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
3166 SelectObject(hdcDst, oldDst);
3167 DeleteObject(bmpDst);
3169 /* Bottom up destination tests */
3170 biDst.bmiHeader.biHeight = 2;
3171 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3172 NULL, 0);
3173 oldDst = SelectObject(hdcDst, bmpDst);
3175 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3176 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
3177 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3178 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
3180 /* Tidy up */
3181 SelectObject(hdcDst, oldDst);
3182 DeleteObject(bmpDst);
3183 DeleteDC(hdcDst);
3185 DeleteDC(hdcScreen);
3188 static void test_GdiAlphaBlend(void)
3190 /* test out-of-bound parameters for GdiAlphaBlend */
3191 HDC hdcNull;
3193 HDC hdcDst;
3194 HBITMAP bmpDst;
3195 HBITMAP oldDst;
3197 BITMAPINFO bmi;
3198 HDC hdcSrc;
3199 HBITMAP bmpSrc;
3200 HBITMAP oldSrc;
3201 LPVOID bits;
3203 BLENDFUNCTION blend;
3205 if (!pGdiAlphaBlend)
3207 win_skip("GdiAlphaBlend() is not implemented\n");
3208 return;
3211 hdcNull = GetDC(NULL);
3212 hdcDst = CreateCompatibleDC(hdcNull);
3213 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
3214 hdcSrc = CreateCompatibleDC(hdcNull);
3216 memset(&bmi, 0, sizeof(bmi)); /* as of Wine 0.9.44 we require the src to be a DIB section */
3217 bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
3218 bmi.bmiHeader.biHeight = 20;
3219 bmi.bmiHeader.biWidth = 20;
3220 bmi.bmiHeader.biBitCount = 32;
3221 bmi.bmiHeader.biPlanes = 1;
3222 bmi.bmiHeader.biCompression = BI_RGB;
3223 bmpSrc = CreateDIBSection(hdcDst, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3224 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3226 oldDst = SelectObject(hdcDst, bmpDst);
3227 oldSrc = SelectObject(hdcSrc, bmpSrc);
3229 blend.BlendOp = AC_SRC_OVER;
3230 blend.BlendFlags = 0;
3231 blend.SourceConstantAlpha = 128;
3232 blend.AlphaFormat = 0;
3234 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend), TRUE, BOOL, "%d");
3235 SetLastError(0xdeadbeef);
3236 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), FALSE, BOOL, "%d");
3237 expect_eq(GetLastError(), ERROR_INVALID_PARAMETER, int, "%d");
3238 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), FALSE, BOOL, "%d");
3239 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend), FALSE, BOOL, "%d");
3240 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
3241 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
3243 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
3244 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), TRUE, BOOL, "%d");
3245 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), TRUE, BOOL, "%d");
3246 SetMapMode(hdcSrc, MM_ANISOTROPIC);
3247 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
3248 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend), TRUE, BOOL, "%d");
3249 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend), TRUE, BOOL, "%d");
3251 SetLastError(0xdeadbeef);
3252 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend), FALSE, BOOL, "%d");
3253 expect_eq(GetLastError(), 0xdeadbeef, int, "%d");
3255 SelectObject(hdcDst, oldDst);
3256 SelectObject(hdcSrc, oldSrc);
3257 DeleteObject(bmpSrc);
3258 DeleteObject(bmpDst);
3259 DeleteDC(hdcDst);
3260 DeleteDC(hdcSrc);
3262 ReleaseDC(NULL, hdcNull);
3266 static void test_clipping(void)
3268 HBITMAP bmpDst;
3269 HBITMAP bmpSrc;
3270 HRGN hRgn;
3271 LPVOID bits;
3272 BOOL result;
3274 HDC hdcDst = CreateCompatibleDC( NULL );
3275 HDC hdcSrc = CreateCompatibleDC( NULL );
3277 BITMAPINFO bmpinfo={{0}};
3278 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3279 bmpinfo.bmiHeader.biWidth = 100;
3280 bmpinfo.bmiHeader.biHeight = 100;
3281 bmpinfo.bmiHeader.biPlanes = 1;
3282 bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3283 bmpinfo.bmiHeader.biCompression = BI_RGB;
3285 bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3286 ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3287 SelectObject( hdcDst, bmpDst );
3289 bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3290 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3291 SelectObject( hdcSrc, bmpSrc );
3293 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3294 ok(result, "BitBlt failed\n");
3296 hRgn = CreateRectRgn( 0,0,0,0 );
3297 SelectClipRgn( hdcDst, hRgn );
3299 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3300 ok(result, "BitBlt failed\n");
3302 DeleteObject( bmpDst );
3303 DeleteObject( bmpSrc );
3304 DeleteObject( hRgn );
3305 DeleteDC( hdcDst );
3306 DeleteDC( hdcSrc );
3309 static void test_32bit_bitmap_blt(void)
3311 BITMAPINFO biDst;
3312 HBITMAP bmpSrc, bmpDst;
3313 HBITMAP oldSrc, oldDst;
3314 HDC hdcSrc, hdcDst, hdcScreen;
3315 UINT32 *dstBuffer;
3316 DWORD colorSrc = 0x11223344;
3318 memset(&biDst, 0, sizeof(BITMAPINFO));
3319 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3320 biDst.bmiHeader.biWidth = 2;
3321 biDst.bmiHeader.biHeight = -2;
3322 biDst.bmiHeader.biPlanes = 1;
3323 biDst.bmiHeader.biBitCount = 32;
3324 biDst.bmiHeader.biCompression = BI_RGB;
3326 hdcScreen = CreateCompatibleDC(0);
3327 if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3329 DeleteDC(hdcScreen);
3330 trace("Skipping 32-bit DDB test\n");
3331 return;
3334 hdcSrc = CreateCompatibleDC(hdcScreen);
3335 bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3336 oldSrc = SelectObject(hdcSrc, bmpSrc);
3338 hdcDst = CreateCompatibleDC(hdcScreen);
3339 bmpDst = CreateDIBSection(hdcDst, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3340 oldDst = SelectObject(hdcDst, bmpDst);
3342 StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3343 ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3345 /* Tidy up */
3346 SelectObject(hdcDst, oldDst);
3347 DeleteObject(bmpDst);
3348 DeleteDC(hdcDst);
3350 SelectObject(hdcSrc, oldSrc);
3351 DeleteObject(bmpSrc);
3352 DeleteDC(hdcSrc);
3354 DeleteDC(hdcScreen);
3358 * Used by test_GetDIBits_top_down to create the bitmap to test against.
3360 static void setup_picture(char *picture, int bpp)
3362 int i;
3364 switch(bpp)
3366 case 16:
3367 case 32:
3368 /*Set the first byte in each pixel to the index of that pixel.*/
3369 for (i = 0; i < 4; i++)
3370 picture[i * (bpp / 8)] = i;
3371 break;
3372 case 24:
3373 picture[0] = 0;
3374 picture[3] = 1;
3375 /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
3376 picture[8] = 2;
3377 picture[11] = 3;
3378 break;
3382 static void test_GetDIBits_top_down(int bpp)
3384 BITMAPINFO bi;
3385 HBITMAP bmptb, bmpbt;
3386 HDC hdc;
3387 int pictureOut[4];
3388 int *picture;
3389 int statusCode;
3391 memset( &bi, 0, sizeof(bi) );
3392 bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
3393 bi.bmiHeader.biWidth=2;
3394 bi.bmiHeader.biHeight=2;
3395 bi.bmiHeader.biPlanes=1;
3396 bi.bmiHeader.biBitCount=bpp;
3397 bi.bmiHeader.biCompression=BI_RGB;
3399 /*Get the device context for the screen.*/
3400 hdc = GetDC(NULL);
3401 ok(hdc != NULL, "Could not get a handle to a device context.\n");
3403 /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
3404 bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3405 ok(bmpbt != NULL, "Could not create a DIB section.\n");
3406 /*Now that we have a pointer to the pixels, we write to them.*/
3407 setup_picture((char*)picture, bpp);
3408 /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
3409 bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
3410 bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3411 ok(bmptb != NULL, "Could not create a DIB section.\n");
3412 /*Write to this top to bottom bitmap.*/
3413 setup_picture((char*)picture, bpp);
3415 bi.bmiHeader.biWidth = 1;
3417 bi.bmiHeader.biHeight = 2;
3418 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3419 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3420 /*Check the first byte of the pixel.*/
3421 ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3422 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3423 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3424 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3425 /*Check second scanline.*/
3426 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3427 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3428 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3429 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3430 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3431 ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3432 /*Check both scanlines.*/
3433 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3434 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3435 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3436 ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3437 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3438 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3439 ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3440 ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3442 /*Make destination bitmap top-down.*/
3443 bi.bmiHeader.biHeight = -2;
3444 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3445 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3446 ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3447 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3448 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3449 ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3450 /*Check second scanline.*/
3451 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3452 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3453 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3454 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3455 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3456 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3457 /*Check both scanlines.*/
3458 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3459 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3460 ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3461 ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3462 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3463 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3464 ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3465 ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3467 DeleteObject(bmpbt);
3468 DeleteObject(bmptb);
3471 static void test_GetSetDIBits_rtl(void)
3473 HDC hdc, hdc_mem;
3474 HBITMAP bitmap, orig_bitmap;
3475 BITMAPINFO info;
3476 int ret;
3477 DWORD bits_1[8 * 8], bits_2[8 * 8];
3479 if(!pSetLayout)
3481 win_skip("Don't have SetLayout\n");
3482 return;
3485 hdc = GetDC( NULL );
3486 hdc_mem = CreateCompatibleDC( hdc );
3487 pSetLayout( hdc_mem, LAYOUT_LTR );
3489 bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
3490 orig_bitmap = SelectObject( hdc_mem, bitmap );
3491 SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
3492 SelectObject( hdc_mem, orig_bitmap );
3494 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3495 info.bmiHeader.biWidth = 8;
3496 info.bmiHeader.biHeight = 8;
3497 info.bmiHeader.biPlanes = 1;
3498 info.bmiHeader.biBitCount = 32;
3499 info.bmiHeader.biCompression = BI_RGB;
3501 /* First show that GetDIBits ignores the layout mode. */
3503 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3504 ok(ret == 8, "got %d\n", ret);
3505 ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
3507 pSetLayout( hdc_mem, LAYOUT_RTL );
3509 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3510 ok(ret == 8, "got %d\n", ret);
3512 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3514 /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
3515 followed by a GetDIBits and show that the bits remain unchanged. */
3517 pSetLayout( hdc_mem, LAYOUT_LTR );
3519 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3520 ok(ret == 8, "got %d\n", ret);
3521 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3522 ok(ret == 8, "got %d\n", ret);
3523 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3525 pSetLayout( hdc_mem, LAYOUT_RTL );
3527 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3528 ok(ret == 8, "got %d\n", ret);
3529 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3530 ok(ret == 8, "got %d\n", ret);
3531 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3533 DeleteObject( bitmap );
3534 DeleteDC( hdc_mem );
3535 ReleaseDC( NULL, hdc );
3538 static void test_GetDIBits_scanlines(void)
3540 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3541 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3542 DWORD *dib_bits;
3543 HDC hdc = GetDC( NULL );
3544 HBITMAP dib;
3545 DWORD data[128], inverted_bits[64];
3546 int i, ret;
3548 memset( info, 0, sizeof(bmi_buf) );
3550 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3551 info->bmiHeader.biWidth = 8;
3552 info->bmiHeader.biHeight = 8;
3553 info->bmiHeader.biPlanes = 1;
3554 info->bmiHeader.biBitCount = 32;
3555 info->bmiHeader.biCompression = BI_RGB;
3557 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3559 for (i = 0; i < 64; i++)
3561 dib_bits[i] = i;
3562 inverted_bits[56 - (i & ~7) + (i & 7)] = i;
3565 /* b-u -> b-u */
3567 memset( data, 0xaa, sizeof(data) );
3569 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3570 ok( ret == 8, "got %d\n", ret );
3571 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3572 memset( data, 0xaa, sizeof(data) );
3574 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3575 ok( ret == 5, "got %d\n", ret );
3576 ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
3577 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3578 memset( data, 0xaa, sizeof(data) );
3580 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3581 ok( ret == 7, "got %d\n", ret );
3582 ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
3583 for (i = 56; 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, 9, 12, data, info, DIB_RGB_COLORS );
3587 ok( ret == 1, "got %d\n", ret );
3588 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3589 memset( data, 0xaa, sizeof(data) );
3591 info->bmiHeader.biHeight = 16;
3592 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3593 ok( ret == 5, "got %d\n", ret );
3594 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3595 ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
3596 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3597 memset( data, 0xaa, sizeof(data) );
3599 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3600 ok( ret == 6, "got %d\n", ret );
3601 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3602 ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
3603 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3604 memset( data, 0xaa, sizeof(data) );
3606 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3607 ok( ret == 0, "got %d\n", ret );
3608 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3609 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3610 memset( data, 0xaa, sizeof(data) );
3612 info->bmiHeader.biHeight = 5;
3613 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3614 ok( ret == 2, "got %d\n", ret );
3615 ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
3616 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3617 memset( data, 0xaa, sizeof(data) );
3619 /* b-u -> t-d */
3621 info->bmiHeader.biHeight = -8;
3622 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3623 ok( ret == 8, "got %d\n", ret );
3624 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3625 memset( data, 0xaa, sizeof(data) );
3627 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3628 ok( ret == 5, "got %d\n", ret );
3629 ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
3630 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3631 memset( data, 0xaa, sizeof(data) );
3633 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3634 ok( ret == 7, "got %d\n", ret );
3635 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3636 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3637 memset( data, 0xaa, sizeof(data) );
3639 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3640 ok( ret == 4, "got %d\n", ret );
3641 ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
3642 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3643 memset( data, 0xaa, sizeof(data) );
3645 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3646 ok( ret == 5, "got %d\n", ret );
3647 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3648 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3649 memset( data, 0xaa, sizeof(data) );
3651 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3652 ok( ret == 5, "got %d\n", ret );
3653 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3654 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3655 memset( data, 0xaa, sizeof(data) );
3657 info->bmiHeader.biHeight = -16;
3658 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3659 ok( ret == 8, "got %d\n", ret );
3660 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3661 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3662 memset( data, 0xaa, sizeof(data) );
3664 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3665 ok( ret == 5, "got %d\n", ret );
3666 ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
3667 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3668 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3669 memset( data, 0xaa, sizeof(data) );
3671 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3672 ok( ret == 8, "got %d\n", ret );
3673 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3674 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3675 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3676 memset( data, 0xaa, sizeof(data) );
3678 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3679 ok( ret == 8, "got %d\n", ret );
3680 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3681 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3682 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3683 memset( data, 0xaa, sizeof(data) );
3685 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3686 ok( ret == 7, "got %d\n", ret );
3687 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3688 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3689 memset( data, 0xaa, sizeof(data) );
3691 ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
3692 ok( ret == 1, "got %d\n", ret );
3693 for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3694 memset( data, 0xaa, sizeof(data) );
3696 info->bmiHeader.biHeight = -5;
3697 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3698 ok( ret == 2, "got %d\n", ret );
3699 ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
3700 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3701 memset( data, 0xaa, sizeof(data) );
3703 DeleteObject( dib );
3705 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3706 info->bmiHeader.biWidth = 8;
3707 info->bmiHeader.biHeight = -8;
3708 info->bmiHeader.biPlanes = 1;
3709 info->bmiHeader.biBitCount = 32;
3710 info->bmiHeader.biCompression = BI_RGB;
3712 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3714 for (i = 0; i < 64; i++) dib_bits[i] = i;
3716 /* t-d -> t-d */
3718 info->bmiHeader.biHeight = -8;
3719 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3720 ok( ret == 8, "got %d\n", ret );
3721 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3722 memset( data, 0xaa, sizeof(data) );
3724 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3725 ok( ret == 5, "got %d\n", ret );
3726 ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
3727 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3728 memset( data, 0xaa, sizeof(data) );
3730 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3731 ok( ret == 7, "got %d\n", ret );
3732 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3733 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3734 memset( data, 0xaa, sizeof(data) );
3736 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3737 ok( ret == 4, "got %d\n", ret );
3738 ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
3739 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3740 memset( data, 0xaa, sizeof(data) );
3742 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3743 ok( ret == 5, "got %d\n", ret );
3744 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3745 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3746 memset( data, 0xaa, sizeof(data) );
3748 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3749 ok( ret == 5, "got %d\n", ret );
3750 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3751 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3752 memset( data, 0xaa, sizeof(data) );
3754 info->bmiHeader.biHeight = -16;
3755 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3756 ok( ret == 8, "got %d\n", ret );
3757 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3758 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3759 memset( data, 0xaa, sizeof(data) );
3761 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3762 ok( ret == 5, "got %d\n", ret );
3763 ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
3764 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3765 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3766 memset( data, 0xaa, sizeof(data) );
3768 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3769 ok( ret == 8, "got %d\n", ret );
3770 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3771 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3772 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3773 memset( data, 0xaa, sizeof(data) );
3775 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3776 ok( ret == 8, "got %d\n", ret );
3777 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3778 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3779 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3780 memset( data, 0xaa, sizeof(data) );
3782 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3783 ok( ret == 7, "got %d\n", ret );
3784 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3785 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3786 memset( data, 0xaa, sizeof(data) );
3788 info->bmiHeader.biHeight = -5;
3789 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3790 ok( ret == 2, "got %d\n", ret );
3791 ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
3792 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3793 memset( data, 0xaa, sizeof(data) );
3796 /* t-d -> b-u */
3798 info->bmiHeader.biHeight = 8;
3800 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3801 ok( ret == 8, "got %d\n", ret );
3802 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3803 memset( data, 0xaa, sizeof(data) );
3805 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3806 ok( ret == 5, "got %d\n", ret );
3807 ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
3808 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3809 memset( data, 0xaa, sizeof(data) );
3811 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3812 ok( ret == 7, "got %d\n", ret );
3813 ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
3814 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3815 memset( data, 0xaa, sizeof(data) );
3817 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3818 ok( ret == 1, "got %d\n", ret );
3819 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3820 memset( data, 0xaa, sizeof(data) );
3822 info->bmiHeader.biHeight = 16;
3823 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3824 ok( ret == 5, "got %d\n", ret );
3825 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3826 ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
3827 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3828 memset( data, 0xaa, sizeof(data) );
3830 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3831 ok( ret == 6, "got %d\n", ret );
3832 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3833 ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
3834 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3835 memset( data, 0xaa, sizeof(data) );
3837 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3838 ok( ret == 0, "got %d\n", ret );
3839 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3840 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3841 memset( data, 0xaa, sizeof(data) );
3843 info->bmiHeader.biHeight = 5;
3844 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3845 ok( ret == 2, "got %d\n", ret );
3846 ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
3847 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3848 memset( data, 0xaa, sizeof(data) );
3850 DeleteObject( dib );
3852 ReleaseDC( NULL, hdc );
3856 static void test_SetDIBits(void)
3858 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3859 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3860 DWORD *dib_bits;
3861 HDC hdc = GetDC( NULL );
3862 DWORD data[128], inverted_data[128];
3863 HBITMAP dib;
3864 int i, ret;
3866 memset( info, 0, sizeof(bmi_buf) );
3868 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3869 info->bmiHeader.biWidth = 8;
3870 info->bmiHeader.biHeight = 8;
3871 info->bmiHeader.biPlanes = 1;
3872 info->bmiHeader.biBitCount = 32;
3873 info->bmiHeader.biCompression = BI_RGB;
3875 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3876 memset( dib_bits, 0xaa, 64 * 4 );
3878 for (i = 0; i < 128; i++)
3880 data[i] = i;
3881 inverted_data[120 - (i & ~7) + (i & 7)] = i;
3884 /* b-u -> b-u */
3886 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3887 ok( ret == 8, "got %d\n", ret );
3888 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
3889 memset( dib_bits, 0xaa, 64 * 4 );
3891 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3892 ok( ret == 5, "got %d\n", ret );
3893 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3894 ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
3895 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3896 memset( dib_bits, 0xaa, 64 * 4 );
3898 /* top of dst is aligned with startscans down for the top of the src.
3899 Then starting from the bottom of src, lines rows are copied across. */
3901 info->bmiHeader.biHeight = 16;
3902 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3903 ok( ret == 12, "got %d\n", ret );
3904 ok( !memcmp( dib_bits, data + 56, 40 * 4 ), "bits differ\n");
3905 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3906 memset( dib_bits, 0xaa, 64 * 4 );
3908 info->bmiHeader.biHeight = 5;
3909 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3910 ok( ret == 2, "got %d\n", ret );
3911 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3912 ok( !memcmp( dib_bits + 32, data, 16 * 4 ), "bits differ\n");
3913 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3914 memset( dib_bits, 0xaa, 64 * 4 );
3916 /* t-d -> b-u */
3917 info->bmiHeader.biHeight = -8;
3918 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3919 ok( ret == 8, "got %d\n", ret );
3920 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3921 memset( dib_bits, 0xaa, 64 * 4 );
3923 /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
3924 we copy lines rows from the top of the src */
3926 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3927 ok( ret == 5, "got %d\n", ret );
3928 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3929 ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
3930 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3931 memset( dib_bits, 0xaa, 64 * 4 );
3933 info->bmiHeader.biHeight = -16;
3934 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3935 ok( ret == 12, "got %d\n", ret );
3936 ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
3937 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3938 memset( dib_bits, 0xaa, 64 * 4 );
3940 ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3941 ok( ret == 12, "got %d\n", ret );
3942 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3943 memset( dib_bits, 0xaa, 64 * 4 );
3945 ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3946 ok( ret == 12, "got %d\n", ret );
3947 ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
3948 memset( dib_bits, 0xaa, 64 * 4 );
3950 info->bmiHeader.biHeight = -5;
3951 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3952 ok( ret == 2, "got %d\n", ret );
3953 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3954 ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
3955 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3956 memset( dib_bits, 0xaa, 64 * 4 );
3958 DeleteObject( dib );
3960 info->bmiHeader.biHeight = -8;
3962 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3963 memset( dib_bits, 0xaa, 16 * 16 * 4 );
3965 /* t-d -> t-d */
3967 /* like the t-d -> b-u case. */
3969 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3970 ok( ret == 8, "got %d\n", ret );
3971 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
3972 memset( dib_bits, 0xaa, 64 * 4 );
3974 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3975 ok( ret == 5, "got %d\n", ret );
3976 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3977 ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
3978 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3979 memset( dib_bits, 0xaa, 64 * 4 );
3981 info->bmiHeader.biHeight = -16;
3982 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3983 ok( ret == 12, "got %d\n", ret );
3984 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3985 ok( !memcmp( dib_bits + 24, data, 40 * 4 ), "bits differ\n");
3986 memset( dib_bits, 0xaa, 64 * 4 );
3988 info->bmiHeader.biHeight = -5;
3989 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3990 ok( ret == 2, "got %d\n", ret );
3991 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3992 ok( !memcmp( dib_bits + 16, data, 16 * 4 ), "bits differ\n");
3993 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3994 memset( dib_bits, 0xaa, 64 * 4 );
3996 /* b-u -> t-d */
3997 /* like the b-u -> b-u case */
3999 info->bmiHeader.biHeight = 8;
4000 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4001 ok( ret == 8, "got %d\n", ret );
4002 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4003 memset( dib_bits, 0xaa, 64 * 4 );
4005 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4006 ok( ret == 5, "got %d\n", ret );
4007 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4008 ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
4009 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4010 memset( dib_bits, 0xaa, 64 * 4 );
4012 info->bmiHeader.biHeight = 16;
4013 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4014 ok( ret == 12, "got %d\n", ret );
4015 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4016 ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
4017 memset( dib_bits, 0xaa, 64 * 4 );
4019 info->bmiHeader.biHeight = 5;
4020 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4021 ok( ret == 2, "got %d\n", ret );
4022 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4023 ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
4024 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4025 memset( dib_bits, 0xaa, 64 * 4 );
4027 DeleteObject( dib );
4028 ReleaseDC( NULL, hdc );
4031 static void test_SetDIBits_RLE4(void)
4033 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
4034 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
4035 DWORD *dib_bits;
4036 HDC hdc = GetDC( NULL );
4037 BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00, /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
4038 0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
4039 0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00, /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
4040 0x00, 0x02, 0x01, 0x02, 0x05, 0x87, /* dx=1, dy=2, 8, 7, 8, 7, 8 */
4041 0x00, 0x01 }; /* <eod> */
4042 HBITMAP dib;
4043 int i, ret;
4044 DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
4045 0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
4046 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4047 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4048 0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
4049 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4050 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4051 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4053 memset( info, 0, sizeof(bmi_buf) );
4055 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4056 info->bmiHeader.biWidth = 8;
4057 info->bmiHeader.biHeight = 8;
4058 info->bmiHeader.biPlanes = 1;
4059 info->bmiHeader.biBitCount = 32;
4060 info->bmiHeader.biCompression = BI_RGB;
4062 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4063 memset( dib_bits, 0xaa, 64 * 4 );
4065 info->bmiHeader.biBitCount = 4;
4066 info->bmiHeader.biCompression = BI_RLE4;
4067 info->bmiHeader.biSizeImage = sizeof(rle4_data);
4069 for (i = 0; i < 16; i++)
4071 info->bmiColors[i].rgbRed = i;
4072 info->bmiColors[i].rgbGreen = i;
4073 info->bmiColors[i].rgbBlue = i;
4074 info->bmiColors[i].rgbReserved = 0;
4077 ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
4078 ok( ret == 8, "got %d\n", ret );
4079 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
4080 memset( dib_bits, 0xaa, 64 * 4 );
4082 DeleteObject( dib );
4083 ReleaseDC( NULL, hdc );
4086 static void test_SetDIBits_RLE8(void)
4088 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
4089 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
4090 DWORD *dib_bits;
4091 HDC hdc = GetDC( NULL );
4092 BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00, /* 2, 2, 2, f0, f0, f0, f0, <eol> */
4093 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4094 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4095 0x00, 0x01 }; /* <eod> */
4096 HBITMAP dib;
4097 int i, ret;
4098 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4099 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4100 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4101 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4102 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4103 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4104 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4105 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4106 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4107 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4108 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4109 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4110 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4111 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4112 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4113 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4115 memset( info, 0, sizeof(bmi_buf) );
4117 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4118 info->bmiHeader.biWidth = 8;
4119 info->bmiHeader.biHeight = 8;
4120 info->bmiHeader.biPlanes = 1;
4121 info->bmiHeader.biBitCount = 32;
4122 info->bmiHeader.biCompression = BI_RGB;
4124 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4125 memset( dib_bits, 0xaa, 64 * 4 );
4127 info->bmiHeader.biBitCount = 8;
4128 info->bmiHeader.biCompression = BI_RLE8;
4129 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4131 for (i = 0; i < 256; i++)
4133 info->bmiColors[i].rgbRed = i;
4134 info->bmiColors[i].rgbGreen = i;
4135 info->bmiColors[i].rgbBlue = i;
4136 info->bmiColors[i].rgbReserved = 0;
4139 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4140 ok( ret == 8, "got %d\n", ret );
4141 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4142 memset( dib_bits, 0xaa, 64 * 4 );
4144 /* startscan and lines are ignored, unless lines == 0 */
4145 ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4146 ok( ret == 8, "got %d\n", ret );
4147 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4148 memset( dib_bits, 0xaa, 64 * 4 );
4150 ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4151 ok( ret == 8, "got %d\n", ret );
4152 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4153 memset( dib_bits, 0xaa, 64 * 4 );
4155 ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4156 ok( ret == 0, "got %d\n", ret );
4157 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4158 memset( dib_bits, 0xaa, 64 * 4 );
4160 /* reduce width to 4, left-hand side of dst is touched. */
4161 info->bmiHeader.biWidth = 4;
4162 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4163 ok( ret == 8, "got %d\n", ret );
4164 for (i = 0; i < 64; i++)
4166 DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4167 ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4169 memset( dib_bits, 0xaa, 64 * 4 );
4171 /* Show that the top lines are aligned by adjusting the height of the src */
4173 /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4174 info->bmiHeader.biWidth = 8;
4175 info->bmiHeader.biHeight = 4;
4176 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4177 ok( ret == 4, "got %d\n", ret );
4178 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4179 ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4180 memset( dib_bits, 0xaa, 64 * 4 );
4182 /* increase the height to 9 -> everything moves down one row. */
4183 info->bmiHeader.biHeight = 9;
4184 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4185 ok( ret == 9, "got %d\n", ret );
4186 ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4187 for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4188 memset( dib_bits, 0xaa, 64 * 4 );
4190 /* top-down compressed dibs are invalid */
4191 info->bmiHeader.biHeight = -8;
4192 SetLastError( 0xdeadbeef );
4193 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4194 ok( ret == 0, "got %d\n", ret );
4195 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4196 DeleteObject( dib );
4198 /* top-down dst */
4200 info->bmiHeader.biHeight = -8;
4201 info->bmiHeader.biBitCount = 32;
4202 info->bmiHeader.biCompression = BI_RGB;
4203 info->bmiHeader.biSizeImage = 0;
4205 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4206 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4208 info->bmiHeader.biHeight = 8;
4209 info->bmiHeader.biBitCount = 8;
4210 info->bmiHeader.biCompression = BI_RLE8;
4211 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4213 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4214 ok( ret == 8, "got %d\n", ret );
4215 ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4216 memset( dib_bits, 0xaa, 64 * 4 );
4218 info->bmiHeader.biHeight = 4;
4219 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4220 ok( ret == 4, "got %d\n", ret );
4221 ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4222 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4223 memset( dib_bits, 0xaa, 64 * 4 );
4225 info->bmiHeader.biHeight = 9;
4226 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4227 ok( ret == 9, "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 ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4230 memset( dib_bits, 0xaa, 64 * 4 );
4232 DeleteObject( dib );
4234 ReleaseDC( NULL, hdc );
4237 static void test_SetDIBitsToDevice(void)
4239 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
4240 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
4241 DWORD *dib_bits;
4242 HDC hdc = CreateCompatibleDC( 0 );
4243 DWORD data[128], inverted_data[128];
4244 HBITMAP dib;
4245 int i, ret;
4247 memset( info, 0, sizeof(bmi_buf) );
4249 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4250 info->bmiHeader.biWidth = 8;
4251 info->bmiHeader.biHeight = 8;
4252 info->bmiHeader.biPlanes = 1;
4253 info->bmiHeader.biBitCount = 32;
4254 info->bmiHeader.biCompression = BI_RGB;
4256 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4257 memset( dib_bits, 0xaa, 64 * 4 );
4258 SelectObject( hdc, dib );
4260 for (i = 0; i < 128; i++)
4262 data[i] = i;
4263 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4266 /* b-u -> b-u */
4268 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4269 ok( ret == 8, "got %d\n", ret );
4270 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4271 memset( dib_bits, 0xaa, 64 * 4 );
4273 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4274 ok( ret == 5, "got %d\n", ret );
4275 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4276 for (i = 8; i < 48; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4277 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4278 memset( dib_bits, 0xaa, 64 * 4 );
4280 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 3, 1, 5, data, info, DIB_RGB_COLORS );
4281 ok( ret == 5, "got %d\n", ret );
4282 for (i = 0; i < 24; i++) ok( dib_bits[i] == data[i + 16], "%d: got %08x\n", i, dib_bits[i] );
4283 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4284 memset( dib_bits, 0xaa, 64 * 4 );
4286 info->bmiHeader.biHeight = 16;
4287 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4288 ok( ret == 7, "got %d\n", ret );
4289 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4290 for (i = 8; i < 64; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4291 memset( dib_bits, 0xaa, 64 * 4 );
4293 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 8, 0, 6, 1, 12, data, info, DIB_RGB_COLORS );
4294 ok( ret == 12, "got %d\n", ret );
4295 for (i = 0; i < 40; i++) ok( dib_bits[i] == data[i + 56], "%d: got %08x\n", i, dib_bits[i] );
4296 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4297 memset( dib_bits, 0xaa, 64 * 4 );
4299 ret = SetDIBitsToDevice( hdc, 0, -4, 8, 8, 0, 3, 1, 12, data, info, DIB_RGB_COLORS );
4300 ok( ret == 10, "got %d\n", ret );
4301 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4302 for (i = 32; i < 64; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4303 memset( dib_bits, 0xaa, 64 * 4 );
4305 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, -3, 1, 12, data, info, DIB_RGB_COLORS );
4306 ok( ret == 4, "got %d\n", ret );
4307 for (i = 0; i < 32; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4308 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4309 memset( dib_bits, 0xaa, 64 * 4 );
4311 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 5, 0, -2, 1, 12, data, info, DIB_RGB_COLORS );
4312 ok( ret == 2, "got %d\n", ret );
4313 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4314 for (i = 32; i < 48; i++) ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4315 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4316 memset( dib_bits, 0xaa, 64 * 4 );
4318 info->bmiHeader.biHeight = 5;
4319 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 2, 2, data, info, DIB_RGB_COLORS );
4320 ok( ret == 2, "got %d\n", ret );
4321 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4322 for (i = 16; i < 32; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4323 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4324 memset( dib_bits, 0xaa, 64 * 4 );
4326 ret = SetDIBitsToDevice( hdc, 3, 3, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4327 ok( ret == 3, "got %d\n", ret );
4328 for (i = 0; i < 64; i++)
4329 if (i == 27 || i == 28 || i == 35 || i == 36)
4330 ok( dib_bits[i] == data[i - 18], "%d: got %08x\n", i, dib_bits[i] );
4331 else
4332 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4333 memset( dib_bits, 0xaa, 64 * 4 );
4335 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4336 ok( ret == 5, "got %d\n", ret );
4337 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4338 memset( dib_bits, 0xaa, 64 * 4 );
4340 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4341 ok( ret == 0, "got %d\n", ret );
4342 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4343 memset( dib_bits, 0xaa, 64 * 4 );
4345 SetMapMode( hdc, MM_ANISOTROPIC );
4346 SetWindowExtEx( hdc, 3, 3, NULL );
4347 ret = SetDIBitsToDevice( hdc, 2, 2, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4348 ok( ret == 3, "got %d\n", ret );
4349 for (i = 0; i < 64; i++)
4350 if (i == 41 || i == 42 || i == 49 || i == 50)
4351 ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4352 else
4353 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4354 memset( dib_bits, 0xaa, 64 * 4 );
4356 SetWindowExtEx( hdc, -1, -1, NULL );
4357 ret = SetDIBitsToDevice( hdc, 2, 2, 4, 4, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4358 ok( ret == 4, "got %d\n", ret );
4359 for (i = 0; i < 64; i++)
4360 if (i == 48 || i == 49 || i == 56 || i == 57)
4361 ok( dib_bits[i] == data[i - 37], "%d: got %08x\n", i, dib_bits[i] );
4362 else
4363 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4364 memset( dib_bits, 0xaa, 64 * 4 );
4365 SetMapMode( hdc, MM_TEXT );
4367 if (pSetLayout)
4369 pSetLayout( hdc, LAYOUT_RTL );
4370 ret = SetDIBitsToDevice( hdc, 1, 2, 3, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4371 ok( ret == 3, "got %d\n", ret );
4372 for (i = 0; i < 64; i++)
4373 if (i == 36 || i == 37 || i == 38 || i == 44 || i == 45 || i == 46)
4374 ok( dib_bits[i] == data[i - 27], "%d: got %08x\n", i, dib_bits[i] );
4375 else
4376 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4377 memset( dib_bits, 0xaa, 64 * 4 );
4378 pSetLayout( hdc, LAYOUT_LTR );
4381 /* t-d -> b-u */
4382 info->bmiHeader.biHeight = -8;
4383 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4384 ok( ret == 8, "got %d\n", ret );
4385 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4386 memset( dib_bits, 0xaa, 64 * 4 );
4388 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4389 ok( ret == 5, "got %d\n", ret );
4390 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4391 for (i = 8; i < 48; i++) ok( dib_bits[i] == inverted_data[i + 80], "%d: got %08x\n", i, dib_bits[i] );
4392 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4393 memset( dib_bits, 0xaa, 64 * 4 );
4395 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 4, 1, 5, data, info, DIB_RGB_COLORS );
4396 ok( ret == 5, "got %d\n", ret );
4397 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4398 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4399 memset( dib_bits, 0xaa, 64 * 4 );
4401 info->bmiHeader.biHeight = -16;
4402 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4403 ok( ret == 12, "got %d\n", ret );
4404 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4405 for (i = 8; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4406 memset( dib_bits, 0xaa, 64 * 4 );
4408 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, 7, 1, 12, data, info, DIB_RGB_COLORS );
4409 ok( ret == 12, "got %d\n", ret );
4410 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4411 for (i = 16; 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, 0, 0, 8, 8, 0, 0, 4, 12, data, info, DIB_RGB_COLORS );
4415 ok( ret == 12, "got %d\n", ret );
4416 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4417 for (i = 32; i < 64; i++) ok( dib_bits[i] == inverted_data[i], "%d: got %08x\n", i, dib_bits[i] );
4418 memset( dib_bits, 0xaa, 64 * 4 );
4420 ret = SetDIBitsToDevice( hdc, 0, -3, 8, 8, 0, 2, 4, 12, data, info, DIB_RGB_COLORS );
4421 ok( ret == 12, "got %d\n", ret );
4422 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4423 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4424 memset( dib_bits, 0xaa, 64 * 4 );
4426 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, -2, 4, 12, data, info, DIB_RGB_COLORS );
4427 ok( ret == 12, "got %d\n", ret );
4428 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4429 for (i = 24; i < 40; i++) ok( dib_bits[i] == inverted_data[i + 8], "%d: got %08x\n", i, dib_bits[i] );
4430 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4431 memset( dib_bits, 0xaa, 64 * 4 );
4433 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 5, 12, data, info, DIB_RGB_COLORS );
4434 ok( ret == 12, "got %d\n", ret );
4435 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4436 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4437 memset( dib_bits, 0xaa, 64 * 4 );
4439 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4440 ok( ret == 12, "got %d\n", ret );
4441 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4442 memset( dib_bits, 0xaa, 64 * 4 );
4444 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -2, -4, 0, 12, data, info, DIB_RGB_COLORS );
4445 ok( ret == 12, "got %d\n", ret );
4446 for (i = 0; i < 64; i++)
4447 if (i == 31 || i == 39 || i == 47 || i == 55 || i == 63)
4448 ok( dib_bits[i] == inverted_data[i + 1], "%d: got %08x\n", i, dib_bits[i] );
4449 else
4450 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4451 memset( dib_bits, 0xaa, 64 * 4 );
4453 info->bmiHeader.biHeight = -5;
4454 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4455 ok( ret == 2, "got %d\n", ret );
4456 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4457 for (i = 8; i < 24; i++) ok( dib_bits[i] == inverted_data[i + 104], "%d: got %08x\n", i, dib_bits[i] );
4458 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4459 memset( dib_bits, 0xaa, 64 * 4 );
4461 ret = SetDIBitsToDevice( hdc, 5, 4, 2, 2, 6, 3, 1, 5, data, info, DIB_RGB_COLORS );
4462 ok( ret == 5, "got %d\n", ret );
4463 for (i = 0; i < 64; i++)
4464 if (i == 21 || i == 22 || i == 29 || i == 30)
4465 ok( dib_bits[i] == inverted_data[i + 89], "%d: got %08x\n", i, dib_bits[i] );
4466 else
4467 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4468 memset( dib_bits, 0xaa, 64 * 4 );
4470 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4471 ok( ret == 5, "got %d\n", ret );
4472 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4473 memset( dib_bits, 0xaa, 64 * 4 );
4475 info->bmiHeader.biHeight = -8;
4477 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4478 DeleteObject( SelectObject( hdc, dib ));
4479 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4481 /* t-d -> t-d */
4483 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4484 ok( ret == 8, "got %d\n", ret );
4485 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4486 memset( dib_bits, 0xaa, 64 * 4 );
4488 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4489 ok( ret == 5, "got %d\n", ret );
4490 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4491 for (i = 16; i < 56; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4492 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4493 memset( dib_bits, 0xaa, 64 * 4 );
4495 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 3, 0, 2, 1, 5, data, info, DIB_RGB_COLORS );
4496 ok( ret == 5, "got %d\n", ret );
4497 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4498 for (i = 24; i < 48; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4499 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4500 memset( dib_bits, 0xaa, 64 * 4 );
4502 info->bmiHeader.biHeight = -16;
4503 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4504 ok( ret == 12, "got %d\n", ret );
4505 for (i = 0; i < 56; i++) ok( dib_bits[i] == data[i + 40], "%d: got %08x\n", i, dib_bits[i] );
4506 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4507 memset( dib_bits, 0xaa, 64 * 4 );
4509 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -1, -8, 0, 12, data, info, DIB_RGB_COLORS );
4510 ok( ret == 12, "got %d\n", ret );
4511 for (i = 0; i < 64; i++)
4512 if (i == 6 || i == 7)
4513 ok( dib_bits[i] == data[i + 82], "%d: got %08x\n", i, dib_bits[i] );
4514 else
4515 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4516 memset( dib_bits, 0xaa, 64 * 4 );
4518 info->bmiHeader.biHeight = -5;
4519 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4520 ok( ret == 2, "got %d\n", ret );
4521 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4522 for (i = 40; i < 56; i++) ok( dib_bits[i] == data[i - 40], "%d: got %08x\n", i, dib_bits[i] );
4523 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4524 memset( dib_bits, 0xaa, 64 * 4 );
4526 ret = SetDIBitsToDevice( hdc, 7, 2, 8, 8, 1, 0, 0, 5, data, info, DIB_RGB_COLORS );
4527 ok( ret == 5, "got %d\n", ret );
4528 for (i = 0; i < 64; i++)
4529 if (i == 47 || i == 55 || i == 63)
4530 ok( dib_bits[i] == data[i - 46], "%d: got %08x\n", i, dib_bits[i] );
4531 else
4532 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4533 memset( dib_bits, 0xaa, 64 * 4 );
4535 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4536 ok( ret == 5, "got %d\n", ret );
4537 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4538 memset( dib_bits, 0xaa, 64 * 4 );
4540 /* b-u -> t-d */
4542 info->bmiHeader.biHeight = 8;
4543 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4544 ok( ret == 8, "got %d\n", ret );
4545 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4546 memset( dib_bits, 0xaa, 64 * 4 );
4548 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4549 ok( ret == 5, "got %d\n", ret );
4550 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4551 for (i = 16; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4552 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4553 memset( dib_bits, 0xaa, 64 * 4 );
4555 info->bmiHeader.biHeight = 16;
4556 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4557 ok( ret == 7, "got %d\n", ret );
4558 for (i = 0; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4559 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4560 memset( dib_bits, 0xaa, 64 * 4 );
4562 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, 0, -4, 1, 12, data, info, DIB_RGB_COLORS );
4563 ok( ret == 3, "got %d\n", ret );
4564 for (i = 0; i < 64; i++)
4565 if ((i >= 36 && i <= 39) || (i >= 44 && i <= 47) || (i >= 52 && i <= 55))
4566 ok( dib_bits[i] == inverted_data[i + 68], "%d: got %08x\n", i, dib_bits[i] );
4567 else
4568 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4569 memset( dib_bits, 0xaa, 64 * 4 );
4571 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, -30, -30, 1, 12, data, info, DIB_RGB_COLORS );
4572 ok( ret == 0, "got %d\n", ret );
4573 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4574 memset( dib_bits, 0xaa, 64 * 4 );
4576 ret = SetDIBitsToDevice( hdc, 5, -5, 8, 16, -2, -4, 4, 12, data, info, DIB_RGB_COLORS );
4577 ok( ret == 8, "got %d\n", ret );
4578 for (i = 0; i < 64; i++)
4579 if (i == 7 || i == 15 || i == 23)
4580 ok( dib_bits[i] == inverted_data[i + 97], "%d: got %08x\n", i, dib_bits[i] );
4581 else
4582 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4583 memset( dib_bits, 0xaa, 64 * 4 );
4585 info->bmiHeader.biHeight = 5;
4586 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4587 ok( ret == 2, "got %d\n", ret );
4588 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4589 for (i = 40; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4590 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4591 memset( dib_bits, 0xaa, 64 * 4 );
4593 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4594 ok( ret == 5, "got %d\n", ret );
4595 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4596 memset( dib_bits, 0xaa, 64 * 4 );
4598 DeleteDC( hdc );
4599 DeleteObject( dib );
4602 static void test_SetDIBitsToDevice_RLE8(void)
4604 char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
4605 BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
4606 DWORD *dib_bits;
4607 HDC hdc = CreateCompatibleDC( 0 );
4608 BYTE rle8_data[20] = { 0x04, 0x02, 0x03, 0xf0, 0x00, 0x00, /* 2, 2, 2, 2, f0, f0, f0, <eol> */
4609 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4610 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4611 0x00, 0x01 }; /* <eod> */
4612 HBITMAP dib;
4613 int i, ret;
4614 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4615 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4616 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4617 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4618 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4619 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4620 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4621 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4622 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4623 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4624 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4625 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4626 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4627 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4628 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4629 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4631 memset( info, 0, sizeof(bmi_buf) );
4633 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4634 info->bmiHeader.biWidth = 8;
4635 info->bmiHeader.biHeight = 8;
4636 info->bmiHeader.biPlanes = 1;
4637 info->bmiHeader.biBitCount = 32;
4638 info->bmiHeader.biCompression = BI_RGB;
4640 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4641 memset( dib_bits, 0xaa, 64 * 4 );
4642 SelectObject( hdc, dib );
4644 info->bmiHeader.biBitCount = 8;
4645 info->bmiHeader.biCompression = BI_RLE8;
4646 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4648 for (i = 0; i < 256; i++)
4650 info->bmiColors[i].rgbRed = i;
4651 info->bmiColors[i].rgbGreen = i;
4652 info->bmiColors[i].rgbBlue = i;
4653 info->bmiColors[i].rgbReserved = 0;
4656 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4657 ok( ret == 8, "got %d\n", ret );
4658 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4659 memset( dib_bits, 0xaa, 64 * 4 );
4661 /* startscan and lines are ignored, unless lines == 0 */
4662 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4663 ok( ret == 8, "got %d\n", ret );
4664 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4665 memset( dib_bits, 0xaa, 64 * 4 );
4667 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4668 ok( ret == 8, "got %d\n", ret );
4669 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4670 memset( dib_bits, 0xaa, 64 * 4 );
4672 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4673 ok( ret == 0, "got %d\n", ret );
4674 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4675 memset( dib_bits, 0xaa, 64 * 4 );
4677 info->bmiHeader.biWidth = 2;
4678 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4679 ok( ret == 8, "got %d\n", ret );
4680 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4681 memset( dib_bits, 0xaa, 64 * 4 );
4683 info->bmiHeader.biWidth = 8;
4684 info->bmiHeader.biHeight = 2;
4685 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4686 ok( ret == 2, "got %d\n", ret );
4687 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4688 memset( dib_bits, 0xaa, 64 * 4 );
4690 info->bmiHeader.biHeight = 9;
4691 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4692 ok( ret == 9, "got %d\n", ret );
4693 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4694 memset( dib_bits, 0xaa, 64 * 4 );
4696 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4697 ok( ret == 9, "got %d\n", ret );
4698 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4699 memset( dib_bits, 0xaa, 64 * 4 );
4701 info->bmiHeader.biHeight = 8;
4702 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 9, rle8_data, info, DIB_RGB_COLORS );
4703 ok( ret == 8, "got %d\n", ret );
4704 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4705 memset( dib_bits, 0xaa, 64 * 4 );
4707 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4708 ok( ret == 8, "got %d\n", ret );
4709 for (i = 0; i < 40; i++) ok( dib_bits[i] == bottom_up[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4710 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4711 memset( dib_bits, 0xaa, 64 * 4 );
4713 ret = SetDIBitsToDevice( hdc, 0, 3, 4, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4714 ok( ret == 8, "got %d\n", ret );
4715 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4716 for (i = 8; i < 40; i++)
4717 if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4718 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4719 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4720 memset( dib_bits, 0xaa, 64 * 4 );
4722 ret = SetDIBitsToDevice( hdc, 3, 3, 8, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4723 ok( ret == 8, "got %d\n", ret );
4724 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4725 for (i = 8; i < 40; i++)
4726 if ((i & 7) < 3) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4727 else ok( dib_bits[i] == bottom_up[i - 11], "%d: got %08x\n", i, dib_bits[i] );
4728 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4729 memset( dib_bits, 0xaa, 64 * 4 );
4731 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 4, 2, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4732 ok( ret == 8, "got %d\n", ret );
4733 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4734 for (i = 8; i < 40; i++)
4735 if ((i & 7) < 2) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4736 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4737 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4738 memset( dib_bits, 0xaa, 64 * 4 );
4740 info->bmiHeader.biWidth = 37;
4741 info->bmiHeader.biHeight = 37;
4742 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
4743 ok( ret == 37, "got %d\n", ret );
4744 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4745 for (i = 24; i < 64; i++)
4746 if (i == 52) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
4747 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4748 else ok( dib_bits[i] == bottom_up[i - 20], "%d: got %08x\n", i, dib_bits[i] );
4749 memset( dib_bits, 0xaa, 64 * 4 );
4751 /* top-down compressed dibs are invalid */
4752 info->bmiHeader.biWidth = 8;
4753 info->bmiHeader.biHeight = -8;
4754 SetLastError( 0xdeadbeef );
4755 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4756 ok( ret == 0, "got %d\n", ret );
4757 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4759 /* top-down dst */
4761 info->bmiHeader.biHeight = -8;
4762 info->bmiHeader.biBitCount = 32;
4763 info->bmiHeader.biCompression = BI_RGB;
4764 info->bmiHeader.biSizeImage = 0;
4766 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4767 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4768 DeleteObject( SelectObject( hdc, dib ));
4770 info->bmiHeader.biHeight = 8;
4771 info->bmiHeader.biBitCount = 8;
4772 info->bmiHeader.biCompression = BI_RLE8;
4773 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4775 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4776 ok( ret == 8, "got %d\n", ret );
4777 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4778 memset( dib_bits, 0xaa, 64 * 4 );
4780 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4781 ok( ret == 8, "got %d\n", ret );
4782 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4783 memset( dib_bits, 0xaa, 64 * 4 );
4785 info->bmiHeader.biHeight = 4;
4786 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4787 ok( ret == 4, "got %d\n", ret );
4788 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4789 memset( dib_bits, 0xaa, 64 * 4 );
4791 info->bmiHeader.biHeight = 9;
4792 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4793 ok( ret == 9, "got %d\n", ret );
4794 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4795 memset( dib_bits, 0xaa, 64 * 4 );
4797 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4798 ok( ret == 9, "got %d\n", ret );
4799 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4800 memset( dib_bits, 0xaa, 64 * 4 );
4802 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 6, 2, 2, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4803 ok( ret == 9, "got %d\n", ret );
4804 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4805 for (i = 24; i < 64; i++) ok( dib_bits[i] == top_down[i - 24], "%d: got %08x\n", i, dib_bits[i] );
4806 memset( dib_bits, 0xaa, 64 * 4 );
4808 info->bmiHeader.biWidth = 37;
4809 info->bmiHeader.biHeight = 37;
4810 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
4811 ok( ret == 37, "got %d\n", ret );
4812 for (i = 0; i < 40; i++)
4813 if (i == 12) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
4814 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4815 else ok( dib_bits[i] == top_down[i + 28], "%d: got %08x\n", i, dib_bits[i] );
4816 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4817 memset( dib_bits, 0xaa, 64 * 4 );
4819 DeleteDC( hdc );
4820 DeleteObject( dib );
4823 START_TEST(bitmap)
4825 HMODULE hdll;
4827 hdll = GetModuleHandle("gdi32.dll");
4828 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
4829 pSetLayout = (void*)GetProcAddress(hdll, "SetLayout");
4831 test_createdibitmap();
4832 test_dibsections();
4833 test_dib_formats();
4834 test_mono_dibsection();
4835 test_bitmap();
4836 test_bmBits();
4837 test_GetDIBits_selected_DIB(1);
4838 test_GetDIBits_selected_DIB(4);
4839 test_GetDIBits_selected_DIB(8);
4840 test_GetDIBits_selected_DDB(TRUE);
4841 test_GetDIBits_selected_DDB(FALSE);
4842 test_GetDIBits();
4843 test_GetDIBits_BI_BITFIELDS();
4844 test_select_object();
4845 test_CreateBitmap();
4846 test_BitBlt();
4847 test_StretchBlt();
4848 test_StretchDIBits();
4849 test_GdiAlphaBlend();
4850 test_32bit_bitmap_blt();
4851 test_bitmapinfoheadersize();
4852 test_get16dibits();
4853 test_clipping();
4854 test_GetDIBits_top_down(16);
4855 test_GetDIBits_top_down(24);
4856 test_GetDIBits_top_down(32);
4857 test_GetSetDIBits_rtl();
4858 test_GetDIBits_scanlines();
4859 test_SetDIBits();
4860 test_SetDIBits_RLE4();
4861 test_SetDIBits_RLE8();
4862 test_SetDIBitsToDevice();
4863 test_SetDIBitsToDevice_RLE8();