gdi32: Add support for DIBINDEX colors in 1-bpp blits.
[wine.git] / dlls / gdi32 / tests / bitmap.c
bloba4002c83b56d80883d4f8ff9d58b4b0a4aa44241
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 "ntstatus.h"
27 #define WIN32_NO_STATUS
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winerror.h"
31 #include "wingdi.h"
32 #include "winuser.h"
33 #include "mmsystem.h"
34 #include "winternl.h"
35 #include "ddk/d3dkmthk.h"
37 #include "wine/test.h"
39 static NTSTATUS (WINAPI *pD3DKMTCreateDCFromMemory)( D3DKMT_CREATEDCFROMMEMORY *desc );
40 static NTSTATUS (WINAPI *pD3DKMTDestroyDCFromMemory)( const D3DKMT_DESTROYDCFROMMEMORY *desc );
41 static BOOL (WINAPI *pGdiAlphaBlend)(HDC,int,int,int,int,HDC,int,int,int,int,BLENDFUNCTION);
42 static BOOL (WINAPI *pGdiGradientFill)(HDC,TRIVERTEX*,ULONG,void*,ULONG,ULONG);
43 static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
45 static inline int get_bitmap_stride( int width, int bpp )
47 return ((width * bpp + 15) >> 3) & ~1;
50 static inline int get_dib_stride( int width, int bpp )
52 return ((width * bpp + 31) >> 3) & ~3;
55 static inline int get_dib_image_size( const BITMAPINFO *info )
57 return get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount )
58 * abs( info->bmiHeader.biHeight );
61 static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHEADER *bmih)
63 BITMAP bm;
64 BITMAP bma[2];
65 INT ret, width_bytes, i;
66 BYTE buf[512], buf_cmp[512];
67 INT test_size[] = {0 /*first value will be changed */, 0, -1, -1000, ~0, sizeof(buf)};
69 ret = GetObjectW(hbm, sizeof(bm), &bm);
70 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
72 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
73 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
74 ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
75 width_bytes = get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel);
76 ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
77 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
78 ok(bm.bmBitsPixel == expected_depth, "wrong bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, expected_depth);
79 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
81 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
82 assert(sizeof(buf) == sizeof(buf_cmp));
84 SetLastError(0xdeadbeef);
85 test_size[0] = bm.bmWidthBytes * bm.bmHeight;
86 /* NULL output buffer with different count values */
87 for (i = 0; i < sizeof(test_size) / sizeof(test_size[0]); i++)
89 ret = GetBitmapBits(hbm, test_size[i], NULL);
90 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
93 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
94 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
96 /* Correct output buffer with different count values */
97 for (i = 0; i < sizeof(test_size) / sizeof(test_size[0]); i++)
99 int expect = i == 1 ? 0 : bm.bmWidthBytes * bm.bmHeight;
100 memset(buf, 0xAA, sizeof(buf));
101 ret = GetBitmapBits(hbm, test_size[i], buf);
102 ok(ret == expect, "Test[%d]: %d != %d\n", i, ret, expect);
103 if (expect)
104 ok(!memcmp(buf, buf_cmp, sizeof(buf)),
105 "Test[%d]: buffers do not match, depth %d\n", i, bmih->biBitCount);
108 /* test various buffer sizes for GetObject */
109 ret = GetObjectW(hbm, sizeof(*bma) * 2, bma);
110 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
112 ret = GetObjectW(hbm, sizeof(bm) / 2, &bm);
113 ok(ret == 0, "%d != 0\n", ret);
115 ret = GetObjectW(hbm, 0, &bm);
116 ok(ret == 0, "%d != 0\n", ret);
118 ret = GetObjectW(hbm, 1, &bm);
119 ok(ret == 0, "%d != 0\n", ret);
121 ret = GetObjectW(hbm, 0, NULL);
122 ok(ret == sizeof(bm), "wrong size %d\n", ret);
125 static void test_createdibitmap(void)
127 HDC hdc, hdcmem;
128 BITMAPINFOHEADER bmih;
129 BITMAPINFO bm;
130 HBITMAP hbm, hbm_colour, hbm_old;
131 INT screen_depth;
132 DWORD pixel;
134 hdc = GetDC(0);
135 screen_depth = GetDeviceCaps(hdc, BITSPIXEL);
136 memset(&bmih, 0, sizeof(bmih));
137 bmih.biSize = sizeof(bmih);
138 bmih.biWidth = 10;
139 bmih.biHeight = 10;
140 bmih.biPlanes = 1;
141 bmih.biBitCount = 32;
142 bmih.biCompression = BI_RGB;
144 hbm = CreateDIBitmap(hdc, NULL, CBM_INIT, NULL, NULL, 0);
145 ok(hbm == NULL, "CreateDIBitmap should fail\n");
146 hbm = CreateDIBitmap(hdc, NULL, 0, NULL, NULL, 0);
147 ok(hbm == NULL, "CreateDIBitmap should fail\n");
149 /* First create an un-initialised bitmap. The depth of the bitmap
150 should match that of the hdc and not that supplied in bmih.
153 /* First try 32 bits */
154 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
155 ok(hbm != NULL, "CreateDIBitmap failed\n");
156 test_bitmap_info(hbm, screen_depth, &bmih);
157 DeleteObject(hbm);
159 /* Then 16 */
160 bmih.biBitCount = 16;
161 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
162 ok(hbm != NULL, "CreateDIBitmap failed\n");
163 test_bitmap_info(hbm, screen_depth, &bmih);
164 DeleteObject(hbm);
166 /* Then 1 */
167 bmih.biBitCount = 1;
168 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
169 ok(hbm != NULL, "CreateDIBitmap failed\n");
170 test_bitmap_info(hbm, screen_depth, &bmih);
171 DeleteObject(hbm);
173 /* Now with a monochrome dc we expect a monochrome bitmap */
174 hdcmem = CreateCompatibleDC(hdc);
176 /* First try 32 bits */
177 bmih.biBitCount = 32;
178 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
179 ok(hbm != NULL, "CreateDIBitmap failed\n");
180 test_bitmap_info(hbm, 1, &bmih);
181 DeleteObject(hbm);
183 /* Then 16 */
184 bmih.biBitCount = 16;
185 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
186 ok(hbm != NULL, "CreateDIBitmap failed\n");
187 test_bitmap_info(hbm, 1, &bmih);
188 DeleteObject(hbm);
190 /* Then 1 */
191 bmih.biBitCount = 1;
192 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
193 ok(hbm != NULL, "CreateDIBitmap failed\n");
194 test_bitmap_info(hbm, 1, &bmih);
195 DeleteObject(hbm);
197 /* Now select a polychrome bitmap into the dc and we expect
198 screen_depth bitmaps again */
199 hbm_colour = CreateCompatibleBitmap(hdc, bmih.biWidth, bmih.biHeight);
200 test_bitmap_info(hbm_colour, screen_depth, &bmih);
201 hbm_old = SelectObject(hdcmem, hbm_colour);
203 /* First try 32 bits */
204 bmih.biBitCount = 32;
205 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
206 ok(hbm != NULL, "CreateDIBitmap failed\n");
207 test_bitmap_info(hbm, screen_depth, &bmih);
208 DeleteObject(hbm);
210 /* Then 16 */
211 bmih.biBitCount = 16;
212 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
213 ok(hbm != NULL, "CreateDIBitmap failed\n");
214 test_bitmap_info(hbm, screen_depth, &bmih);
215 DeleteObject(hbm);
217 /* Then 1 */
218 bmih.biBitCount = 1;
219 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
220 ok(hbm != NULL, "CreateDIBitmap failed\n");
221 test_bitmap_info(hbm, screen_depth, &bmih);
222 DeleteObject(hbm);
224 SelectObject(hdcmem, hbm_old);
225 DeleteObject(hbm_colour);
226 DeleteDC(hdcmem);
228 bmih.biBitCount = 32;
229 hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0);
230 ok(hbm != NULL, "CreateDIBitmap failed\n");
231 test_bitmap_info(hbm, 1, &bmih);
232 DeleteObject(hbm);
234 /* Test how formats are converted */
235 pixel = 0xffffffff;
236 bmih.biBitCount = 1;
237 bmih.biWidth = 1;
238 bmih.biHeight = 1;
240 memset(&bm, 0, sizeof(bm));
241 bm.bmiHeader.biSize = sizeof(bm.bmiHeader);
242 bm.bmiHeader.biWidth = 1;
243 bm.bmiHeader.biHeight = 1;
244 bm.bmiHeader.biPlanes = 1;
245 bm.bmiHeader.biBitCount= 24;
246 bm.bmiHeader.biCompression= BI_RGB;
247 bm.bmiHeader.biSizeImage = 0;
248 hbm = CreateDIBitmap(hdc, &bmih, CBM_INIT, &pixel, &bm, DIB_RGB_COLORS);
249 ok(hbm != NULL, "CreateDIBitmap failed\n");
251 pixel = 0xdeadbeef;
252 bm.bmiHeader.biBitCount= 32;
253 GetDIBits(hdc, hbm, 0, 1, &pixel, &bm, DIB_RGB_COLORS);
254 ok(pixel == 0x00ffffff, "Reading a 32 bit pixel from a DDB returned %08x\n", pixel);
255 DeleteObject(hbm);
257 ReleaseDC(0, hdc);
260 static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
262 BITMAP bm;
263 BITMAP bma[2];
264 DIBSECTION ds;
265 DIBSECTION dsa[2];
266 INT ret, bm_width_bytes, dib_width_bytes;
267 BYTE *buf;
269 ret = GetObjectW(hbm, sizeof(bm), &bm);
270 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
272 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
273 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
274 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
275 dib_width_bytes = get_dib_stride(bm.bmWidth, bm.bmBitsPixel);
276 bm_width_bytes = get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel);
277 if (bm.bmWidthBytes != dib_width_bytes) /* Win2k bug */
278 ok(bm.bmWidthBytes == bm_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, bm_width_bytes);
279 else
280 ok(bm.bmWidthBytes == dib_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, dib_width_bytes);
281 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
282 ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount);
283 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
285 buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);
287 /* GetBitmapBits returns not 32-bit aligned data */
288 SetLastError(0xdeadbeef);
289 ret = GetBitmapBits(hbm, 0, NULL);
290 ok(ret == bm_width_bytes * bm.bmHeight,
291 "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
293 memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
294 ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
295 ok(ret == bm_width_bytes * bm.bmHeight, "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
297 HeapFree(GetProcessHeap(), 0, buf);
299 /* test various buffer sizes for GetObject */
300 memset(&ds, 0xAA, sizeof(ds));
301 ret = GetObjectW(hbm, sizeof(*bma) * 2, bma);
302 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
303 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
304 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
305 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
307 ret = GetObjectW(hbm, sizeof(bm) / 2, &bm);
308 ok(ret == 0, "%d != 0\n", ret);
310 ret = GetObjectW(hbm, 0, &bm);
311 ok(ret == 0, "%d != 0\n", ret);
313 ret = GetObjectW(hbm, 1, &bm);
314 ok(ret == 0, "%d != 0\n", ret);
316 /* test various buffer sizes for GetObject */
317 ret = GetObjectW(hbm, 0, NULL);
318 ok(ret == sizeof(bm), "wrong size %d\n", ret);
320 ret = GetObjectW(hbm, sizeof(*dsa) * 2, dsa);
321 ok(ret == sizeof(*dsa), "wrong size %d\n", ret);
323 memset(&ds, 0xAA, sizeof(ds));
324 ret = GetObjectW(hbm, sizeof(ds), &ds);
325 ok(ret == sizeof(ds), "wrong size %d\n", ret);
327 ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
328 if (ds.dsBm.bmWidthBytes != bm_width_bytes) /* Win2k bug */
329 ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%u != %u\n",
330 ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
331 ok(bmih->biSizeImage == 0, "%u != 0\n", bmih->biSizeImage);
332 ds.dsBmih.biSizeImage = 0;
334 ok(ds.dsBmih.biSize == bmih->biSize, "%u != %u\n", ds.dsBmih.biSize, bmih->biSize);
335 ok(ds.dsBmih.biWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
336 ok(ds.dsBmih.biHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
337 ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes);
338 ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount);
339 ok(ds.dsBmih.biCompression == bmih->biCompression ||
340 ((bmih->biBitCount == 32) && broken(ds.dsBmih.biCompression == BI_BITFIELDS)), /* nt4 sp1 and 2 */
341 "%u != %u\n", ds.dsBmih.biCompression, bmih->biCompression);
342 ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%u != %u\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
343 ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%d != %d\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
344 ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%d != %d\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);
346 memset(&ds, 0xAA, sizeof(ds));
347 ret = GetObjectW(hbm, sizeof(ds) - 4, &ds);
348 ok(ret == sizeof(ds.dsBm), "wrong size %d\n", ret);
349 ok(ds.dsBm.bmWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
350 ok(ds.dsBm.bmHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
351 ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);
353 ret = GetObjectW(hbm, 0, &ds);
354 ok(ret == 0, "%d != 0\n", ret);
356 ret = GetObjectW(hbm, 1, &ds);
357 ok(ret == 0, "%d != 0\n", ret);
360 static void _test_color( int line, HDC hdc, COLORREF color, COLORREF exp )
362 COLORREF c;
363 c = SetPixel(hdc, 0, 0, color);
364 ok_(__FILE__, line)(c == exp, "SetPixel failed: got 0x%06x expected 0x%06x\n", c, exp);
365 c = GetPixel(hdc, 0, 0);
366 ok_(__FILE__, line)(c == exp, "GetPixel failed: got 0x%06x expected 0x%06x\n", c, exp);
367 c = GetNearestColor(hdc, color);
368 ok_(__FILE__, line)(c == exp, "GetNearestColor failed: got 0x%06x expected 0x%06x\n", c, exp);
370 #define test_color(hdc, color, exp) _test_color( __LINE__, hdc, color, exp )
373 static void test_dib_bits_access( HBITMAP hdib, void *bits )
375 MEMORY_BASIC_INFORMATION info;
376 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
377 DWORD data[256];
378 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
379 HDC hdc;
380 char filename[MAX_PATH];
381 HANDLE file;
382 DWORD written;
383 INT ret;
385 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
386 "VirtualQuery failed\n");
387 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
388 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
389 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
390 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
391 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
392 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
394 memset( pbmi, 0, sizeof(bmibuf) );
395 memset( data, 0xcc, sizeof(data) );
396 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
397 pbmi->bmiHeader.biHeight = 16;
398 pbmi->bmiHeader.biWidth = 16;
399 pbmi->bmiHeader.biBitCount = 32;
400 pbmi->bmiHeader.biPlanes = 1;
401 pbmi->bmiHeader.biCompression = BI_RGB;
403 hdc = GetDC(0);
405 ret = SetDIBits( hdc, hdib, 0, 16, data, pbmi, DIB_RGB_COLORS );
406 ok(ret == 16, "SetDIBits failed: expected 16 got %d\n", ret);
408 ReleaseDC(0, hdc);
410 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
411 "VirtualQuery failed\n");
412 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
413 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
414 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
415 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
416 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
417 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
419 /* try writing protected bits to a file */
421 GetTempFileNameA( ".", "dib", 0, filename );
422 file = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
423 CREATE_ALWAYS, 0, 0 );
424 ok( file != INVALID_HANDLE_VALUE, "failed to open %s error %u\n", filename, GetLastError() );
425 ret = WriteFile( file, bits, 8192, &written, NULL );
426 ok( ret, "WriteFile failed error %u\n", GetLastError() );
427 if (ret) ok( written == 8192, "only wrote %u bytes\n", written );
428 CloseHandle( file );
429 DeleteFileA( filename );
432 static void test_dibsections(void)
434 HDC hdc, hdcmem, hdcmem2;
435 HBITMAP hdib, oldbm, hdib2, oldbm2;
436 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
437 char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
438 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
439 BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
440 RGBQUAD *colors = pbmi->bmiColors;
441 RGBTRIPLE *ccolors = pbci->bmciColors;
442 HBITMAP hcoredib;
443 char coreBits[256];
444 BYTE *bits;
445 RGBQUAD rgb[256];
446 int ret;
447 char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
448 LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
449 PALETTEENTRY *palent = plogpal->palPalEntry;
450 WORD *index;
451 DWORD *bits32;
452 HPALETTE hpal, oldpal;
453 DIBSECTION dibsec;
454 COLORREF c0, c1;
455 int i;
456 MEMORY_BASIC_INFORMATION info;
458 hdc = GetDC(0);
460 memset(pbmi, 0, sizeof(bmibuf));
461 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
462 pbmi->bmiHeader.biHeight = 100;
463 pbmi->bmiHeader.biWidth = 512;
464 pbmi->bmiHeader.biBitCount = 24;
465 pbmi->bmiHeader.biPlanes = 1;
466 pbmi->bmiHeader.biCompression = BI_RGB;
468 SetLastError(0xdeadbeef);
470 /* invalid pointer for BITMAPINFO
471 (*bits should be NULL on error) */
472 bits = (BYTE*)0xdeadbeef;
473 hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
474 ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n");
476 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
477 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
478 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
479 ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
481 /* test the DIB memory */
482 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
483 "VirtualQuery failed\n");
484 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
485 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
486 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
487 ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
488 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
489 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
490 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
492 test_dib_bits_access( hdib, bits );
494 test_dib_info(hdib, bits, &pbmi->bmiHeader);
495 DeleteObject(hdib);
497 /* Test a top-down DIB. */
498 pbmi->bmiHeader.biHeight = -100;
499 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
500 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
501 test_dib_info(hdib, bits, &pbmi->bmiHeader);
502 DeleteObject(hdib);
504 pbmi->bmiHeader.biHeight = 100;
505 pbmi->bmiHeader.biBitCount = 8;
506 pbmi->bmiHeader.biCompression = BI_RLE8;
507 SetLastError(0xdeadbeef);
508 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
509 ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
510 ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
512 pbmi->bmiHeader.biBitCount = 16;
513 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
514 ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
515 ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
516 ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
517 SetLastError(0xdeadbeef);
518 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
519 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
521 /* test the DIB memory */
522 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
523 "VirtualQuery failed\n");
524 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
525 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
526 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
527 ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
528 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
529 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
530 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
532 test_dib_info(hdib, bits, &pbmi->bmiHeader);
533 DeleteObject(hdib);
535 memset(pbmi, 0, sizeof(bmibuf));
536 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
537 pbmi->bmiHeader.biHeight = 16;
538 pbmi->bmiHeader.biWidth = 16;
539 pbmi->bmiHeader.biBitCount = 1;
540 pbmi->bmiHeader.biPlanes = 1;
541 pbmi->bmiHeader.biCompression = BI_RGB;
542 colors[0].rgbRed = 0xff;
543 colors[0].rgbGreen = 0;
544 colors[0].rgbBlue = 0;
545 colors[1].rgbRed = 0;
546 colors[1].rgbGreen = 0;
547 colors[1].rgbBlue = 0xff;
549 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
550 ok(hdib != NULL, "CreateDIBSection failed\n");
551 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
552 ok(dibsec.dsBmih.biClrUsed == 2,
553 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
555 /* Test if the old BITMAPCOREINFO structure is supported */
557 pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
558 pbci->bmciHeader.bcBitCount = 0;
560 ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
561 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
562 ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
563 && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
564 "GetDIBits didn't fill in the BITMAPCOREHEADER structure properly\n");
566 ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
567 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
568 ok((ccolors[0].rgbtRed == 0xff) && (ccolors[0].rgbtGreen == 0) &&
569 (ccolors[0].rgbtBlue == 0) && (ccolors[1].rgbtRed == 0) &&
570 (ccolors[1].rgbtGreen == 0) && (ccolors[1].rgbtBlue == 0xff),
571 "The color table has not been translated to the old BITMAPCOREINFO format\n");
573 hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
574 ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
576 ZeroMemory(ccolors, 256 * sizeof(RGBTRIPLE));
577 ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
578 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
579 ok((ccolors[0].rgbtRed == 0xff) && (ccolors[0].rgbtGreen == 0) &&
580 (ccolors[0].rgbtBlue == 0) && (ccolors[1].rgbtRed == 0) &&
581 (ccolors[1].rgbtGreen == 0) && (ccolors[1].rgbtBlue == 0xff),
582 "The color table has not been translated to the old BITMAPCOREINFO format\n");
584 DeleteObject(hcoredib);
586 hdcmem = CreateCompatibleDC(hdc);
587 oldbm = SelectObject(hdcmem, hdib);
589 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
590 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
591 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
592 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
593 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
594 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
596 c0 = RGB(colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue);
597 c1 = RGB(colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue);
599 test_color(hdcmem, DIBINDEX(0), c0);
600 test_color(hdcmem, DIBINDEX(1), c1);
601 test_color(hdcmem, DIBINDEX(2), c0);
602 test_color(hdcmem, PALETTEINDEX(0), c0);
603 test_color(hdcmem, PALETTEINDEX(1), c0);
604 test_color(hdcmem, PALETTEINDEX(2), c0);
605 test_color(hdcmem, PALETTERGB(colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue), c0);
606 test_color(hdcmem, PALETTERGB(colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue), c1);
607 test_color(hdcmem, PALETTERGB(0, 0, 0), c0);
608 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0);
609 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1);
611 SelectObject(hdcmem, oldbm);
612 DeleteObject(hdib);
614 colors[0].rgbRed = 0xff;
615 colors[0].rgbGreen = 0xff;
616 colors[0].rgbBlue = 0xff;
617 colors[1].rgbRed = 0;
618 colors[1].rgbGreen = 0;
619 colors[1].rgbBlue = 0;
621 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
622 ok(hdib != NULL, "CreateDIBSection failed\n");
624 test_dib_info(hdib, bits, &pbmi->bmiHeader);
626 oldbm = SelectObject(hdcmem, hdib);
628 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
629 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
630 ok(!memcmp(rgb, colors, 2 * sizeof(RGBQUAD)),
631 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
632 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
633 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
635 SelectObject(hdcmem, oldbm);
636 test_dib_info(hdib, bits, &pbmi->bmiHeader);
637 DeleteObject(hdib);
639 pbmi->bmiHeader.biBitCount = 4;
640 for (i = 0; i < 16; i++) {
641 colors[i].rgbRed = i;
642 colors[i].rgbGreen = 16-i;
643 colors[i].rgbBlue = 0;
645 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
646 ok(hdib != NULL, "CreateDIBSection failed\n");
647 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
648 ok(dibsec.dsBmih.biClrUsed == 16,
649 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
650 test_dib_info(hdib, bits, &pbmi->bmiHeader);
651 DeleteObject(hdib);
653 pbmi->bmiHeader.biBitCount = 8;
655 for (i = 0; i < 128; i++) {
656 colors[i].rgbRed = 255 - i * 2;
657 colors[i].rgbGreen = i * 2;
658 colors[i].rgbBlue = 0;
659 colors[255 - i].rgbRed = 0;
660 colors[255 - i].rgbGreen = i * 2;
661 colors[255 - i].rgbBlue = 255 - i * 2;
663 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
664 ok(hdib != NULL, "CreateDIBSection failed\n");
665 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
666 ok(dibsec.dsBmih.biClrUsed == 256,
667 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
669 oldbm = SelectObject(hdcmem, hdib);
671 for (i = 0; i < 256; i++) {
672 test_color(hdcmem, DIBINDEX(i), RGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue));
673 test_color(hdcmem, PALETTERGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue),
674 RGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue));
677 SelectObject(hdcmem, oldbm);
678 test_dib_info(hdib, bits, &pbmi->bmiHeader);
679 DeleteObject(hdib);
681 pbmi->bmiHeader.biBitCount = 1;
683 /* Now create a palette and a palette indexed dib section */
684 memset(plogpal, 0, sizeof(logpalbuf));
685 plogpal->palVersion = 0x300;
686 plogpal->palNumEntries = 2;
687 palent[0].peRed = 0xff;
688 palent[0].peBlue = 0xff;
689 palent[1].peGreen = 0xff;
691 index = (WORD*)pbmi->bmiColors;
692 *index++ = 0;
693 *index = 1;
694 hpal = CreatePalette(plogpal);
695 ok(hpal != NULL, "CreatePalette failed\n");
696 oldpal = SelectPalette(hdc, hpal, TRUE);
697 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
698 ok(hdib != NULL, "CreateDIBSection failed\n");
699 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
700 ok(dibsec.dsBmih.biClrUsed == 2, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
702 /* The colour table has already been grabbed from the dc, so we select back the
703 old palette */
705 SelectPalette(hdc, oldpal, TRUE);
706 oldbm = SelectObject(hdcmem, hdib);
707 oldpal = SelectPalette(hdcmem, hpal, TRUE);
709 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
710 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
711 ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
712 rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
713 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
714 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
715 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
717 c0 = RGB(palent[0].peRed, palent[0].peGreen, palent[0].peBlue);
718 c1 = RGB(palent[1].peRed, palent[1].peGreen, palent[1].peBlue);
720 test_color(hdcmem, DIBINDEX(0), c0);
721 test_color(hdcmem, DIBINDEX(1), c1);
722 test_color(hdcmem, DIBINDEX(2), c0);
723 test_color(hdcmem, PALETTEINDEX(0), c0);
724 test_color(hdcmem, PALETTEINDEX(1), c1);
725 test_color(hdcmem, PALETTEINDEX(2), c0);
726 test_color(hdcmem, PALETTERGB(palent[0].peRed, palent[0].peGreen, palent[0].peBlue), c0);
727 test_color(hdcmem, PALETTERGB(palent[1].peRed, palent[1].peGreen, palent[1].peBlue), c1);
728 test_color(hdcmem, PALETTERGB(0, 0, 0), c1);
729 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0);
730 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0);
731 test_color(hdcmem, PALETTERGB(0, 1, 0), c1);
732 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1);
733 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0);
735 /* Bottom and 2nd row from top green, everything else magenta */
736 bits[0] = bits[1] = 0xff;
737 bits[13 * 4] = bits[13*4 + 1] = 0xff;
739 test_dib_info(hdib, bits, &pbmi->bmiHeader);
741 pbmi->bmiHeader.biBitCount = 32;
743 hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
744 ok(hdib2 != NULL, "CreateDIBSection failed\n");
745 hdcmem2 = CreateCompatibleDC(hdc);
746 oldbm2 = SelectObject(hdcmem2, hdib2);
748 BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
750 ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
751 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
753 SelectObject(hdcmem2, oldbm2);
754 test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
755 DeleteObject(hdib2);
757 SelectObject(hdcmem, oldbm);
758 SelectPalette(hdcmem, oldpal, TRUE);
759 DeleteObject(hdib);
760 DeleteObject(hpal);
763 pbmi->bmiHeader.biBitCount = 8;
765 memset(plogpal, 0, sizeof(logpalbuf));
766 plogpal->palVersion = 0x300;
767 plogpal->palNumEntries = 256;
769 for (i = 0; i < 128; i++) {
770 palent[i].peRed = 255 - i * 2;
771 palent[i].peBlue = i * 2;
772 palent[i].peGreen = 0;
773 palent[255 - i].peRed = 0;
774 palent[255 - i].peGreen = i * 2;
775 palent[255 - i].peBlue = 255 - i * 2;
778 index = (WORD*)pbmi->bmiColors;
779 for (i = 0; i < 256; i++) {
780 *index++ = i;
783 hpal = CreatePalette(plogpal);
784 ok(hpal != NULL, "CreatePalette failed\n");
785 oldpal = SelectPalette(hdc, hpal, TRUE);
786 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
787 ok(hdib != NULL, "CreateDIBSection failed\n");
788 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
789 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
791 test_dib_info(hdib, bits, &pbmi->bmiHeader);
793 SelectPalette(hdc, oldpal, TRUE);
794 oldbm = SelectObject(hdcmem, hdib);
795 oldpal = SelectPalette(hdcmem, hpal, TRUE);
797 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
798 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
799 for (i = 0; i < 256; i++) {
800 ok(rgb[i].rgbRed == palent[i].peRed &&
801 rgb[i].rgbBlue == palent[i].peBlue &&
802 rgb[i].rgbGreen == palent[i].peGreen,
803 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
804 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
807 for (i = 0; i < 256; i++) {
808 test_color(hdcmem, DIBINDEX(i), RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
809 test_color(hdcmem, PALETTEINDEX(i), RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
810 test_color(hdcmem, PALETTERGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue),
811 RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
814 SelectPalette(hdcmem, oldpal, TRUE);
815 SelectObject(hdcmem, oldbm);
816 DeleteObject(hdib);
817 DeleteObject(hpal);
819 plogpal->palNumEntries = 37;
820 hpal = CreatePalette(plogpal);
821 ok(hpal != NULL, "CreatePalette failed\n");
822 oldpal = SelectPalette(hdc, hpal, TRUE);
823 pbmi->bmiHeader.biClrUsed = 142;
824 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
825 ok(hdib != NULL, "CreateDIBSection failed\n");
826 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
827 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
829 test_dib_info(hdib, bits, &pbmi->bmiHeader);
831 SelectPalette(hdc, oldpal, TRUE);
832 oldbm = SelectObject(hdcmem, hdib);
834 memset( rgb, 0xcc, sizeof(rgb) );
835 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
836 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
837 for (i = 0; i < 256; i++)
839 if (i < pbmi->bmiHeader.biClrUsed)
841 ok(rgb[i].rgbRed == palent[i % 37].peRed &&
842 rgb[i].rgbBlue == palent[i % 37].peBlue &&
843 rgb[i].rgbGreen == palent[i % 37].peGreen,
844 "GetDIBColorTable returns table %d: r %02x g %02x b %02x res%02x\n",
845 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
846 test_color(hdcmem, DIBINDEX(i),
847 RGB(palent[i % 37].peRed, palent[i % 37].peGreen, palent[i % 37].peBlue));
849 else
851 ok(rgb[i].rgbRed == 0 && rgb[i].rgbBlue == 0 && rgb[i].rgbGreen == 0,
852 "GetDIBColorTable returns table %d: r %02x g %02x b %02x res%02x\n",
853 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
854 test_color(hdcmem, DIBINDEX(i), 0 );
857 pbmi->bmiHeader.biClrUsed = 173;
858 memset( pbmi->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
859 GetDIBits( hdc, hdib, 0, 1, NULL, pbmi, DIB_RGB_COLORS );
860 ok( pbmi->bmiHeader.biClrUsed == 0, "wrong colors %u\n", pbmi->bmiHeader.biClrUsed );
861 for (i = 0; i < 256; i++)
863 if (i < 142)
864 ok(colors[i].rgbRed == palent[i % 37].peRed &&
865 colors[i].rgbBlue == palent[i % 37].peBlue &&
866 colors[i].rgbGreen == palent[i % 37].peGreen,
867 "GetDIBits returns table %d: r %02x g %02x b %02x res%02x\n",
868 i, colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
869 else
870 ok(colors[i].rgbRed == 0 && colors[i].rgbBlue == 0 && colors[i].rgbGreen == 0,
871 "GetDIBits returns table %d: r %02x g %02x b %02x res%02x\n",
872 i, colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
875 rgb[0].rgbRed = 1;
876 rgb[0].rgbGreen = 2;
877 rgb[0].rgbBlue = 3;
878 rgb[0].rgbReserved = 123;
879 ret = SetDIBColorTable( hdcmem, 0, 1, rgb );
880 ok( ret == 1, "SetDIBColorTable returned unexpected result %u\n", ret );
881 ok( rgb[0].rgbReserved == 123, "Expected rgbReserved = 123, got %u\n", rgb[0].rgbReserved );
883 rgb[0].rgbRed = rgb[0].rgbGreen = rgb[0].rgbBlue = rgb[0].rgbReserved = -1;
884 ret = GetDIBColorTable( hdcmem, 0, 1, rgb );
885 ok( ret == 1, "GetDIBColorTable returned unexpected result %u\n", ret );
886 ok( rgb[0].rgbRed == 1, "Expected rgbRed = 1, got %u\n", rgb[0].rgbRed );
887 ok( rgb[0].rgbGreen == 2, "Expected rgbGreen = 2, got %u\n", rgb[0].rgbGreen );
888 ok( rgb[0].rgbBlue == 3, "Expected rgbBlue = 3, got %u\n", rgb[0].rgbBlue );
889 ok( rgb[0].rgbReserved == 0, "Expected rgbReserved = 0, got %u\n", rgb[0].rgbReserved );
891 SelectObject(hdcmem, oldbm);
892 DeleteObject(hdib);
893 DeleteObject(hpal);
895 /* ClrUsed ignored on > 8bpp */
896 pbmi->bmiHeader.biBitCount = 16;
897 pbmi->bmiHeader.biClrUsed = 37;
898 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
899 ok(hdib != NULL, "CreateDIBSection failed\n");
900 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
901 ok(dibsec.dsBmih.biClrUsed == 0, "created DIBSection: wrong biClrUsed field: %u\n", dibsec.dsBmih.biClrUsed);
902 oldbm = SelectObject(hdcmem, hdib);
903 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
904 ok(ret == 0, "GetDIBColorTable returned %d\n", ret);
905 SelectObject(hdcmem, oldbm);
906 DeleteObject(hdib);
908 DeleteDC(hdcmem);
909 DeleteDC(hdcmem2);
910 ReleaseDC(0, hdc);
913 static void test_dib_formats(void)
915 BITMAPINFO *bi;
916 char data[256];
917 void *bits;
918 int planes, bpp, compr, format;
919 HBITMAP hdib, hbmp;
920 HDC hdc, memdc;
921 UINT ret;
922 BOOL format_ok, expect_ok;
924 bi = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
925 hdc = GetDC( 0 );
926 memdc = CreateCompatibleDC( 0 );
927 hbmp = CreateCompatibleBitmap( hdc, 10, 10 );
929 memset( data, 0xaa, sizeof(data) );
931 for (bpp = 0; bpp <= 64; bpp++)
933 for (planes = 0; planes <= 64; planes++)
935 for (compr = 0; compr < 8; compr++)
937 for (format = DIB_RGB_COLORS; format <= DIB_PAL_COLORS; format++)
939 switch (bpp)
941 case 1:
942 case 4:
943 case 8:
944 case 24: expect_ok = (compr == BI_RGB); break;
945 case 16:
946 case 32: expect_ok = (compr == BI_RGB || compr == BI_BITFIELDS); break;
947 default: expect_ok = FALSE; break;
950 memset( bi, 0, sizeof(bi->bmiHeader) );
951 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
952 bi->bmiHeader.biWidth = 2;
953 bi->bmiHeader.biHeight = 2;
954 bi->bmiHeader.biPlanes = planes;
955 bi->bmiHeader.biBitCount = bpp;
956 bi->bmiHeader.biCompression = compr;
957 bi->bmiHeader.biSizeImage = 0;
958 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
959 ret = GetDIBits(hdc, hbmp, 0, 0, data, bi, format);
960 if (expect_ok || (!bpp && compr != BI_JPEG && compr != BI_PNG) ||
961 (bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8))
962 ok( ret, "GetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
963 else
964 ok( !ret || broken(!bpp && (compr == BI_JPEG || compr == BI_PNG)), /* nt4 */
965 "GetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
967 /* all functions check planes except GetDIBits with 0 lines */
968 format_ok = expect_ok;
969 if (!planes) expect_ok = FALSE;
970 memset( bi, 0, sizeof(bi->bmiHeader) );
971 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
972 bi->bmiHeader.biWidth = 2;
973 bi->bmiHeader.biHeight = 2;
974 bi->bmiHeader.biPlanes = planes;
975 bi->bmiHeader.biBitCount = bpp;
976 bi->bmiHeader.biCompression = compr;
977 bi->bmiHeader.biSizeImage = 0;
978 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
980 hdib = CreateDIBSection(hdc, bi, format, &bits, NULL, 0);
981 if (expect_ok && (planes == 1 || planes * bpp <= 16) &&
982 (compr != BI_BITFIELDS || format != DIB_PAL_COLORS))
983 ok( hdib != NULL, "CreateDIBSection failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
984 else
985 ok( hdib == NULL, "CreateDIBSection succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
986 if (hdib) DeleteObject( hdib );
988 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, data, bi, format );
989 /* no sanity checks in CreateDIBitmap except compression */
990 if (compr == BI_JPEG || compr == BI_PNG)
991 ok( hdib == NULL || broken(hdib != NULL), /* nt4 */
992 "CreateDIBitmap succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
993 else
994 ok( hdib != NULL, "CreateDIBitmap failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
995 if (hdib) DeleteObject( hdib );
997 /* RLE needs a size */
998 bi->bmiHeader.biSizeImage = 0;
999 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, format);
1000 if (expect_ok)
1001 ok( ret, "SetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1002 else
1003 ok( !ret ||
1004 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
1005 "SetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1006 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, format );
1007 if (expect_ok)
1008 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1009 else
1010 ok( !ret ||
1011 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
1012 "SetDIBitsToDevice succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1013 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, format, SRCCOPY );
1014 if (expect_ok)
1015 ok( ret, "StretchDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1016 else
1017 ok( !ret ||
1018 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
1019 "StretchDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1021 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, format);
1022 if (expect_ok)
1023 ok( ret, "GetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1024 else
1025 ok( !ret, "GetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1026 ok( bi->bmiHeader.biBitCount == bpp, "GetDIBits modified bpp %u/%u\n",
1027 bpp, bi->bmiHeader.biBitCount );
1029 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1030 bi->bmiHeader.biWidth = 2;
1031 bi->bmiHeader.biHeight = 2;
1032 bi->bmiHeader.biPlanes = planes;
1033 bi->bmiHeader.biBitCount = bpp;
1034 bi->bmiHeader.biCompression = compr;
1035 bi->bmiHeader.biSizeImage = 1;
1036 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
1037 /* RLE allowed with valid biSizeImage */
1038 if ((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)) expect_ok = TRUE;
1040 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, format);
1041 if (expect_ok)
1042 ok( ret, "SetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1043 else
1044 ok( !ret, "SetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1045 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, format );
1046 if (expect_ok)
1047 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1048 else
1049 ok( !ret, "SetDIBitsToDevice succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1050 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, format, SRCCOPY );
1051 if (expect_ok)
1052 ok( ret, "StretchDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1053 else
1054 ok( !ret, "StretchDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1056 bi->bmiHeader.biSizeImage = 0;
1057 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, format);
1058 if (expect_ok || !bpp)
1059 ok( ret, "GetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1060 else
1061 ok( !ret || broken(format_ok && !planes), /* nt4 */
1062 "GetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1068 memset( bi, 0, sizeof(bi->bmiHeader) );
1069 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1070 bi->bmiHeader.biWidth = 2;
1071 bi->bmiHeader.biHeight = 2;
1072 bi->bmiHeader.biPlanes = 1;
1073 bi->bmiHeader.biBitCount = 16;
1074 bi->bmiHeader.biCompression = BI_BITFIELDS;
1075 bi->bmiHeader.biSizeImage = 0;
1076 *(DWORD *)&bi->bmiColors[0] = 0;
1077 *(DWORD *)&bi->bmiColors[1] = 0;
1078 *(DWORD *)&bi->bmiColors[2] = 0;
1080 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1081 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1082 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1083 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1084 /* other functions don't check */
1085 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1086 ok( hdib != NULL, "CreateDIBitmap failed with null bitfields\n" );
1087 DeleteObject( hdib );
1088 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1089 ok( ret, "SetDIBitsToDevice failed with null bitfields\n" );
1090 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1091 ok( ret, "StretchDIBits failed with null bitfields\n" );
1092 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1093 ok( ret, "GetDIBits failed with null bitfields\n" );
1094 bi->bmiHeader.biPlanes = 1;
1095 bi->bmiHeader.biBitCount = 16;
1096 bi->bmiHeader.biCompression = BI_BITFIELDS;
1097 bi->bmiHeader.biSizeImage = 0;
1098 *(DWORD *)&bi->bmiColors[0] = 0;
1099 *(DWORD *)&bi->bmiColors[1] = 0;
1100 *(DWORD *)&bi->bmiColors[2] = 0;
1101 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1102 ok( ret, "GetDIBits failed with null bitfields\n" );
1104 /* all fields must be non-zero */
1105 *(DWORD *)&bi->bmiColors[0] = 3;
1106 *(DWORD *)&bi->bmiColors[1] = 0;
1107 *(DWORD *)&bi->bmiColors[2] = 7;
1108 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1109 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1110 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1111 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1113 /* garbage is ok though */
1114 *(DWORD *)&bi->bmiColors[0] = 0x55;
1115 *(DWORD *)&bi->bmiColors[1] = 0x44;
1116 *(DWORD *)&bi->bmiColors[2] = 0x33;
1117 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1118 ok( hdib != NULL, "CreateDIBSection failed with bad bitfields\n" );
1119 if (hdib) DeleteObject( hdib );
1120 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1121 ok( ret, "SetDIBits failed with bad bitfields\n" );
1123 bi->bmiHeader.biWidth = -2;
1124 bi->bmiHeader.biHeight = 2;
1125 bi->bmiHeader.biBitCount = 32;
1126 bi->bmiHeader.biCompression = BI_RGB;
1127 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1128 ok( hdib == NULL, "CreateDIBSection succeeded with negative width\n" );
1129 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1130 ok( hdib == NULL, "CreateDIBitmap succeeded with negative width\n" );
1131 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1132 ok( !ret, "SetDIBits succeeded with negative width\n" );
1133 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1134 ok( !ret, "SetDIBitsToDevice succeeded with negative width\n" );
1135 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1136 ok( !ret, "StretchDIBits succeeded with negative width\n" );
1137 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1138 ok( !ret, "GetDIBits succeeded with negative width\n" );
1139 bi->bmiHeader.biWidth = -2;
1140 bi->bmiHeader.biHeight = 2;
1141 bi->bmiHeader.biBitCount = 32;
1142 bi->bmiHeader.biCompression = BI_RGB;
1143 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1144 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with negative width\n" );
1146 bi->bmiHeader.biWidth = 0;
1147 bi->bmiHeader.biHeight = 2;
1148 bi->bmiHeader.biBitCount = 32;
1149 bi->bmiHeader.biCompression = BI_RGB;
1150 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1151 ok( hdib == NULL, "CreateDIBSection succeeded with zero width\n" );
1152 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1153 ok( hdib != NULL, "CreateDIBitmap failed with zero width\n" );
1154 DeleteObject( hdib );
1155 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1156 ok( !ret || broken(ret), /* nt4 */ "SetDIBits succeeded with zero width\n" );
1157 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1158 ok( !ret || broken(ret), /* nt4 */ "SetDIBitsToDevice succeeded with zero width\n" );
1159 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1160 ok( !ret || broken(ret), /* nt4 */ "StretchDIBits succeeded with zero width\n" );
1161 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1162 ok( !ret, "GetDIBits succeeded with zero width\n" );
1163 bi->bmiHeader.biWidth = 0;
1164 bi->bmiHeader.biHeight = 2;
1165 bi->bmiHeader.biBitCount = 32;
1166 bi->bmiHeader.biCompression = BI_RGB;
1167 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1168 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero width\n" );
1170 bi->bmiHeader.biWidth = 2;
1171 bi->bmiHeader.biHeight = 0;
1172 bi->bmiHeader.biBitCount = 32;
1173 bi->bmiHeader.biCompression = BI_RGB;
1174 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1175 ok( hdib == NULL, "CreateDIBSection succeeded with zero height\n" );
1176 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1177 ok( hdib != NULL, "CreateDIBitmap failed with zero height\n" );
1178 DeleteObject( hdib );
1179 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1180 ok( !ret, "SetDIBits succeeded with zero height\n" );
1181 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1182 ok( !ret, "SetDIBitsToDevice succeeded with zero height\n" );
1183 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1184 ok( !ret, "StretchDIBits succeeded with zero height\n" );
1185 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1186 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1187 bi->bmiHeader.biWidth = 2;
1188 bi->bmiHeader.biHeight = 0;
1189 bi->bmiHeader.biBitCount = 32;
1190 bi->bmiHeader.biCompression = BI_RGB;
1191 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1192 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1194 /* some functions accept DIB_PAL_COLORS+1, but not beyond */
1196 bi->bmiHeader.biWidth = 2;
1197 bi->bmiHeader.biHeight = 2;
1198 bi->bmiHeader.biBitCount = 1;
1199 bi->bmiHeader.biCompression = BI_RGB;
1200 hdib = CreateDIBSection(hdc, bi, DIB_PAL_COLORS+1, &bits, NULL, 0);
1201 ok( hdib == NULL, "CreateDIBSection succeeded with DIB_PAL_COLORS+1\n" );
1202 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_PAL_COLORS+1 );
1203 ok( hdib != NULL, "CreateDIBitmap failed with DIB_PAL_COLORS+1\n" );
1204 DeleteObject( hdib );
1205 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_PAL_COLORS+1);
1206 ok( !ret, "SetDIBits succeeded with DIB_PAL_COLORS+1\n" );
1207 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_PAL_COLORS+1 );
1208 ok( ret, "SetDIBitsToDevice failed with DIB_PAL_COLORS+1\n" );
1209 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_PAL_COLORS+1, SRCCOPY );
1210 ok( ret, "StretchDIBits failed with DIB_PAL_COLORS+1\n" );
1211 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_PAL_COLORS+1);
1212 ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+1\n" );
1213 bi->bmiHeader.biWidth = 2;
1214 bi->bmiHeader.biHeight = 2;
1215 bi->bmiHeader.biBitCount = 1;
1216 bi->bmiHeader.biCompression = BI_RGB;
1217 ret = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS+1);
1218 ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+1\n" );
1220 bi->bmiHeader.biWidth = 2;
1221 bi->bmiHeader.biHeight = 2;
1222 bi->bmiHeader.biBitCount = 1;
1223 bi->bmiHeader.biCompression = BI_RGB;
1224 hdib = CreateDIBSection(hdc, bi, DIB_PAL_COLORS+2, &bits, NULL, 0);
1225 ok( hdib == NULL, "CreateDIBSection succeeded with DIB_PAL_COLORS+2\n" );
1226 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_PAL_COLORS+2 );
1227 ok( hdib == NULL, "CreateDIBitmap succeeded with DIB_PAL_COLORS+2\n" );
1228 DeleteObject( hdib );
1229 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_PAL_COLORS+2);
1230 ok( !ret, "SetDIBits succeeded with DIB_PAL_COLORS+2\n" );
1231 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_PAL_COLORS+2 );
1232 ok( !ret, "SetDIBitsToDevice succeeded with DIB_PAL_COLORS+2\n" );
1233 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_PAL_COLORS+2, SRCCOPY );
1234 ok( !ret, "StretchDIBits succeeded with DIB_PAL_COLORS+2\n" );
1235 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_PAL_COLORS+2);
1236 ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+2\n" );
1237 bi->bmiHeader.biWidth = 2;
1238 bi->bmiHeader.biHeight = 2;
1239 bi->bmiHeader.biBitCount = 1;
1240 bi->bmiHeader.biCompression = BI_RGB;
1241 ret = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS+2);
1242 ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+2\n" );
1244 bi->bmiHeader.biWidth = 0x4000;
1245 bi->bmiHeader.biHeight = 0x4000;
1246 bi->bmiHeader.biBitCount = 1;
1247 bi->bmiHeader.biCompression = BI_RGB;
1248 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1249 ok( hdib != NULL, "CreateDIBSection failed with large size\n" );
1250 DeleteObject( hdib );
1252 bi->bmiHeader.biWidth = 0x8001;
1253 bi->bmiHeader.biHeight = 0x8001;
1254 bi->bmiHeader.biBitCount = 32;
1255 bi->bmiHeader.biCompression = BI_RGB;
1256 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1257 ok( hdib == NULL, "CreateDIBSection succeeded with size overflow\n" );
1259 bi->bmiHeader.biWidth = 1;
1260 bi->bmiHeader.biHeight = 0x40000001;
1261 bi->bmiHeader.biBitCount = 32;
1262 bi->bmiHeader.biCompression = BI_RGB;
1263 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1264 ok( hdib == NULL, "CreateDIBSection succeeded with size overflow\n" );
1266 bi->bmiHeader.biWidth = 2;
1267 bi->bmiHeader.biHeight = 0x40000001;
1268 bi->bmiHeader.biBitCount = 16;
1269 bi->bmiHeader.biCompression = BI_RGB;
1270 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1271 ok( hdib == NULL, "CreateDIBSection succeeded with size overflow\n" );
1273 bi->bmiHeader.biWidth = 0x40000001;
1274 bi->bmiHeader.biHeight = 1;
1275 bi->bmiHeader.biBitCount = 32;
1276 bi->bmiHeader.biCompression = BI_RGB;
1277 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1278 ok( hdib == NULL, "CreateDIBSection succeeded with size overflow\n" );
1280 bi->bmiHeader.biWidth = 0x40000001;
1281 bi->bmiHeader.biHeight = 4;
1282 bi->bmiHeader.biBitCount = 8;
1283 bi->bmiHeader.biCompression = BI_RGB;
1284 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1285 ok( hdib == NULL, "CreateDIBSection succeeded with size overflow\n" );
1287 DeleteDC( memdc );
1288 DeleteObject( hbmp );
1289 ReleaseDC( 0, hdc );
1290 HeapFree( GetProcessHeap(), 0, bi );
1293 static void test_mono_dibsection(void)
1295 HDC hdc, memdc;
1296 HBITMAP old_bm, mono_ds;
1297 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
1298 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
1299 RGBQUAD *colors = pbmi->bmiColors;
1300 BYTE bits[10 * 4];
1301 BYTE *ds_bits;
1302 int num;
1304 hdc = GetDC(0);
1306 memdc = CreateCompatibleDC(hdc);
1308 memset(pbmi, 0, sizeof(bmibuf));
1309 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
1310 pbmi->bmiHeader.biHeight = 10;
1311 pbmi->bmiHeader.biWidth = 10;
1312 pbmi->bmiHeader.biBitCount = 1;
1313 pbmi->bmiHeader.biPlanes = 1;
1314 pbmi->bmiHeader.biCompression = BI_RGB;
1315 colors[0].rgbRed = 0xff;
1316 colors[0].rgbGreen = 0xff;
1317 colors[0].rgbBlue = 0xff;
1318 colors[1].rgbRed = 0x0;
1319 colors[1].rgbGreen = 0x0;
1320 colors[1].rgbBlue = 0x0;
1323 * First dib section is 'inverted' ie color[0] is white, color[1] is black
1326 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1327 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1328 old_bm = SelectObject(memdc, mono_ds);
1330 /* black border, white interior */
1331 Rectangle(memdc, 0, 0, 10, 10);
1332 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1333 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1335 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1337 memset(bits, 0, sizeof(bits));
1338 bits[0] = 0xaa;
1340 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1341 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1343 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1345 colors[0].rgbRed = 0x0;
1346 colors[0].rgbGreen = 0x0;
1347 colors[0].rgbBlue = 0x0;
1348 colors[1].rgbRed = 0xff;
1349 colors[1].rgbGreen = 0xff;
1350 colors[1].rgbBlue = 0xff;
1352 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1353 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1355 SelectObject(memdc, old_bm);
1356 DeleteObject(mono_ds);
1359 * Next dib section is 'normal' ie color[0] is black, color[1] is white
1362 colors[0].rgbRed = 0x0;
1363 colors[0].rgbGreen = 0x0;
1364 colors[0].rgbBlue = 0x0;
1365 colors[1].rgbRed = 0xff;
1366 colors[1].rgbGreen = 0xff;
1367 colors[1].rgbBlue = 0xff;
1369 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1370 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1371 old_bm = SelectObject(memdc, mono_ds);
1373 /* black border, white interior */
1374 Rectangle(memdc, 0, 0, 10, 10);
1375 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
1376 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
1378 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
1380 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1381 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1383 /* SetDIBitsToDevice with an inverted bmi -> normal dib section */
1385 colors[0].rgbRed = 0xff;
1386 colors[0].rgbGreen = 0xff;
1387 colors[0].rgbBlue = 0xff;
1388 colors[1].rgbRed = 0x0;
1389 colors[1].rgbGreen = 0x0;
1390 colors[1].rgbBlue = 0x0;
1392 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1393 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1396 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
1399 colors[0].rgbRed = 0xff;
1400 colors[0].rgbGreen = 0xff;
1401 colors[0].rgbBlue = 0xff;
1402 colors[1].rgbRed = 0x0;
1403 colors[1].rgbGreen = 0x0;
1404 colors[1].rgbBlue = 0x0;
1405 num = SetDIBColorTable(memdc, 0, 2, colors);
1406 ok(num == 2, "num = %d\n", num);
1408 /* black border, white interior */
1409 Rectangle(memdc, 0, 0, 10, 10);
1410 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1411 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1413 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1415 memset(bits, 0, sizeof(bits));
1416 bits[0] = 0xaa;
1418 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1419 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1421 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1423 colors[0].rgbRed = 0x0;
1424 colors[0].rgbGreen = 0x0;
1425 colors[0].rgbBlue = 0x0;
1426 colors[1].rgbRed = 0xff;
1427 colors[1].rgbGreen = 0xff;
1428 colors[1].rgbBlue = 0xff;
1430 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1431 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1433 SelectObject(memdc, old_bm);
1434 DeleteObject(mono_ds);
1437 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
1440 colors[0].rgbRed = 0xff;
1441 colors[0].rgbGreen = 0x0;
1442 colors[0].rgbBlue = 0x0;
1443 colors[1].rgbRed = 0xfe;
1444 colors[1].rgbGreen = 0x0;
1445 colors[1].rgbBlue = 0x0;
1447 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1448 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1449 old_bm = SelectObject(memdc, mono_ds);
1451 /* black border, white interior */
1452 Rectangle(memdc, 0, 0, 10, 10);
1453 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1454 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1456 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1458 colors[0].rgbRed = 0x0;
1459 colors[0].rgbGreen = 0x0;
1460 colors[0].rgbBlue = 0x0;
1461 colors[1].rgbRed = 0xff;
1462 colors[1].rgbGreen = 0xff;
1463 colors[1].rgbBlue = 0xff;
1465 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1466 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1468 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1470 colors[0].rgbRed = 0xff;
1471 colors[0].rgbGreen = 0xff;
1472 colors[0].rgbBlue = 0xff;
1473 colors[1].rgbRed = 0x0;
1474 colors[1].rgbGreen = 0x0;
1475 colors[1].rgbBlue = 0x0;
1477 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1478 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1480 SelectObject(memdc, old_bm);
1481 DeleteObject(mono_ds);
1483 DeleteDC(memdc);
1484 ReleaseDC(0, hdc);
1487 static void test_bitmap(void)
1489 char buf[256], buf_cmp[256];
1490 HBITMAP hbmp, hbmp_old;
1491 HDC hdc;
1492 BITMAP bm;
1493 BITMAP bma[2];
1494 INT ret;
1496 hdc = CreateCompatibleDC(0);
1497 assert(hdc != 0);
1499 SetLastError(0xdeadbeef);
1500 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1501 if (!hbmp)
1503 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1504 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1505 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1507 else
1508 DeleteObject(hbmp);
1510 SetLastError(0xdeadbeef);
1511 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1512 if (!hbmp)
1514 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1515 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1516 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1518 else
1519 DeleteObject(hbmp);
1521 SetLastError(0xdeadbeef);
1522 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1523 ok(!hbmp, "CreateBitmap should fail\n");
1524 if (!hbmp)
1525 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1526 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1527 else
1528 DeleteObject(hbmp);
1530 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1531 assert(hbmp != NULL);
1533 ret = GetObjectW(hbmp, sizeof(bm), &bm);
1534 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1536 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1537 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1538 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1539 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1540 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1541 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1542 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1544 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1545 assert(sizeof(buf) == sizeof(buf_cmp));
1547 ret = GetBitmapBits(hbmp, 0, NULL);
1548 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1550 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1551 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1553 memset(buf, 0xAA, sizeof(buf));
1554 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1555 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1556 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1558 hbmp_old = SelectObject(hdc, hbmp);
1560 ret = GetObjectW(hbmp, sizeof(bm), &bm);
1561 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1563 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1564 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1565 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1566 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1567 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1568 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1569 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1571 memset(buf, 0xAA, sizeof(buf));
1572 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1573 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1574 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1576 hbmp_old = SelectObject(hdc, hbmp_old);
1577 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1579 /* test various buffer sizes for GetObject */
1580 ret = GetObjectW(hbmp, sizeof(*bma) * 2, bma);
1581 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1583 ret = GetObjectW(hbmp, sizeof(bm) / 2, &bm);
1584 ok(ret == 0, "%d != 0\n", ret);
1586 ret = GetObjectW(hbmp, 0, &bm);
1587 ok(ret == 0, "%d != 0\n", ret);
1589 ret = GetObjectW(hbmp, 1, &bm);
1590 ok(ret == 0, "%d != 0\n", ret);
1592 DeleteObject(hbmp);
1593 DeleteDC(hdc);
1596 static COLORREF get_nearest( int r, int g, int b )
1598 return (r*r + g*g + b*b < (255-r)*(255-r) + (255-g)*(255-g) + (255-b)*(255-b)) ? 0x000000 : 0xffffff;
1601 static BOOL is_black_pen( COLORREF fg, COLORREF bg, int r, int g, int b )
1603 if (fg == 0 || bg == 0xffffff) return RGB(r,g,b) != 0xffffff && RGB(r,g,b) != bg;
1604 return RGB(r,g,b) == 0x000000 || RGB(r,g,b) == bg;
1607 static void test_bitmap_colors( HDC hdc, COLORREF fg, COLORREF bg, int r, int g, int b )
1609 static const WORD pattern_bits[] = { 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa };
1610 char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors ) + 256 * sizeof(RGBQUAD)];
1611 BITMAPINFO *info = (BITMAPINFO *)buffer;
1612 RGBQUAD *colors = info->bmiColors;
1613 WORD bits[16];
1614 void *bits_ptr;
1615 COLORREF res;
1616 HBRUSH old_brush;
1617 HPEN old_pen;
1618 HBITMAP bitmap;
1619 HDC memdc;
1621 res = SetPixel( hdc, 0, 0, RGB(r,g,b) );
1622 ok( res == get_nearest( r, g, b ),
1623 "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg );
1624 res = GetPixel( hdc, 0, 0 );
1625 ok( res == get_nearest( r, g, b ),
1626 "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg );
1627 res = GetNearestColor( hdc, RGB(r,g,b) );
1628 ok( res == get_nearest( r, g, b ),
1629 "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg );
1631 /* solid pen */
1632 old_pen = SelectObject( hdc, CreatePen( PS_SOLID, 1, RGB(r,g,b) ));
1633 MoveToEx( hdc, 0, 0, NULL );
1634 LineTo( hdc, 16, 0 );
1635 res = GetPixel( hdc, 0, 0 );
1636 ok( res == (is_black_pen( fg, bg, r, g, b ) ? 0 : 0xffffff),
1637 "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg );
1638 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1639 ok( bits[0] == (is_black_pen( fg, bg, r, g, b ) ? 0x00 : 0xffff),
1640 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1641 DeleteObject( SelectObject( hdc, old_pen ));
1643 /* mono DDB pattern brush */
1644 bitmap = CreateBitmap( 16, 8, 1, 1, pattern_bits );
1645 old_brush = SelectObject( hdc, CreatePatternBrush( bitmap ));
1646 PatBlt( hdc, 0, 0, 16, 16, PATCOPY );
1647 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1648 ok( bits[0] == 0x5555 || broken(bits[0] == 0xaada) /* XP SP1 & 2003 SP0 */,
1649 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1650 DeleteObject( SelectObject( hdc, old_brush ));
1652 /* mono DDB bitmap */
1653 memdc = CreateCompatibleDC( hdc );
1654 SelectObject( memdc, bitmap );
1655 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1656 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1657 ok( bits[0] == 0x5555,
1658 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1659 SetTextColor( memdc, RGB(255,255,255) );
1660 SetBkColor( memdc, RGB(0,0,0) );
1661 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1662 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1663 ok( bits[0] == 0x5555,
1664 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1666 /* mono DIB section */
1667 memset( buffer, 0, sizeof(buffer) );
1668 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1669 info->bmiHeader.biHeight = -16;
1670 info->bmiHeader.biWidth = 16;
1671 info->bmiHeader.biBitCount = 1;
1672 info->bmiHeader.biPlanes = 1;
1673 info->bmiHeader.biCompression = BI_RGB;
1674 colors[0].rgbRed = 0xff;
1675 colors[0].rgbGreen = 0xff;
1676 colors[0].rgbBlue = 0xf0;
1677 colors[1].rgbRed = 0x20;
1678 colors[1].rgbGreen = 0x0;
1679 colors[1].rgbBlue = 0x0;
1680 bitmap = CreateDIBSection( 0, info, DIB_RGB_COLORS, &bits_ptr, NULL, 0 );
1681 memset( bits_ptr, 0x55, 64 );
1682 DeleteObject( SelectObject( memdc, bitmap ));
1683 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1684 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1685 ok( bits[0] == 0x5555,
1686 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1688 colors[0].rgbRed = 0x0;
1689 colors[0].rgbGreen = 0x0;
1690 colors[0].rgbBlue = 0x10;
1691 colors[1].rgbRed = 0xff;
1692 colors[1].rgbGreen = 0xf0;
1693 colors[1].rgbBlue = 0xff;
1694 bitmap = CreateDIBSection( 0, info, DIB_RGB_COLORS, &bits_ptr, NULL, 0 );
1695 memset( bits_ptr, 0x55, 64 );
1696 DeleteObject( SelectObject( memdc, bitmap ));
1697 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1698 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1699 ok( bits[0] == 0xaaaa,
1700 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1702 SetTextColor( memdc, RGB(0,20,0) );
1703 SetBkColor( memdc, RGB(240,240,240) );
1704 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1705 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1706 ok( bits[0] == 0x5555,
1707 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1709 SetTextColor( memdc, RGB(250,250,250) );
1710 SetBkColor( memdc, RGB(10,10,10) );
1711 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1712 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1713 ok( bits[0] == 0xaaaa,
1714 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1715 DeleteDC( memdc );
1716 DeleteObject( bitmap );
1719 static void test_mono_bitmap(void)
1721 static const COLORREF colors[][2] =
1723 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff) },
1724 { RGB(0xff,0xff,0xff), RGB(0x00,0x00,0x00) },
1725 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xfe) },
1726 { RGB(0x00,0x01,0x00), RGB(0xff,0xff,0xff) },
1727 { RGB(0x00,0x00,0x00), RGB(0x80,0x80,0x80) },
1728 { RGB(0x80,0x80,0x80), RGB(0xff,0xff,0xff) },
1729 { RGB(0x30,0x40,0x50), RGB(0x60,0x70,0x80) },
1730 { RGB(0xa0,0xa0,0xa0), RGB(0x20,0x30,0x10) },
1731 { PALETTEINDEX(0), PALETTEINDEX(255) },
1732 { PALETTEINDEX(1), PALETTEINDEX(2) },
1735 HBITMAP hbmp;
1736 HDC hdc;
1737 DWORD col;
1738 int i, r, g, b;
1740 hdc = CreateCompatibleDC(0);
1741 assert(hdc != 0);
1743 hbmp = CreateBitmap(16, 16, 1, 1, NULL);
1744 assert(hbmp != NULL);
1746 SelectObject( hdc, hbmp );
1748 for (col = 0; col < sizeof(colors) / sizeof(colors[0]); col++)
1750 SetTextColor( hdc, colors[col][0] );
1751 SetBkColor( hdc, colors[col][1] );
1753 for (i = 0; i < 256; i++)
1755 HPALETTE pal = GetCurrentObject( hdc, OBJ_PAL );
1756 PALETTEENTRY ent;
1758 if (!GetPaletteEntries( pal, i, 1, &ent )) GetPaletteEntries( pal, 0, 1, &ent );
1759 test_color( hdc, PALETTEINDEX(i), get_nearest( ent.peRed, ent.peGreen, ent.peBlue ));
1760 test_color( hdc, DIBINDEX(i), (i == 1) ? 0xffffff : 0x000000 );
1763 for (r = 0; r < 256; r += 15)
1764 for (g = 0; g < 256; g += 15)
1765 for (b = 0; b < 256; b += 15)
1766 test_bitmap_colors( hdc, colors[col][0], colors[col][1], r, g, b );
1769 DeleteDC(hdc);
1770 DeleteObject(hbmp);
1773 static void test_bmBits(void)
1775 BYTE bits[4];
1776 HBITMAP hbmp;
1777 BITMAP bmp;
1779 memset(bits, 0, sizeof(bits));
1780 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1781 ok(hbmp != NULL, "CreateBitmap failed\n");
1783 memset(&bmp, 0xFF, sizeof(bmp));
1784 ok(GetObjectW(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1785 "GetObject failed or returned a wrong structure size\n");
1786 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1788 DeleteObject(hbmp);
1791 static void test_GetDIBits_selected_DIB(UINT bpp)
1793 HBITMAP dib;
1794 BITMAPINFO *info;
1795 BITMAPINFO *info2;
1796 void * bits;
1797 void * bits2;
1798 UINT dib_size, dib32_size;
1799 DWORD pixel;
1800 HDC dib_dc, dc;
1801 HBITMAP old_bmp;
1802 UINT i;
1803 int res;
1805 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1806 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1808 /* Create a DIB section with a color table */
1810 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1811 info->bmiHeader.biWidth = 32;
1812 info->bmiHeader.biHeight = 32;
1813 info->bmiHeader.biPlanes = 1;
1814 info->bmiHeader.biBitCount = bpp;
1815 info->bmiHeader.biCompression = BI_RGB;
1816 info->bmiHeader.biXPelsPerMeter = 0;
1817 info->bmiHeader.biYPelsPerMeter = 0;
1818 info->bmiHeader.biClrUsed = 0;
1819 info->bmiHeader.biClrImportant = 0;
1821 for (i=0; i < (1u << bpp); i++)
1823 BYTE c = i * (1 << (8 - bpp));
1824 info->bmiColors[i].rgbRed = c;
1825 info->bmiColors[i].rgbGreen = c;
1826 info->bmiColors[i].rgbBlue = c;
1827 info->bmiColors[i].rgbReserved = 0;
1830 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1831 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1832 dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1834 /* Set the bits of the DIB section */
1835 for (i=0; i < dib_size; i++)
1837 ((BYTE *)bits)[i] = i % 256;
1840 /* Select the DIB into a DC */
1841 dib_dc = CreateCompatibleDC(NULL);
1842 old_bmp = SelectObject(dib_dc, dib);
1843 dc = CreateCompatibleDC(NULL);
1844 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
1846 /* Copy the DIB attributes but not the color table */
1847 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1849 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1850 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1852 /* Compare the color table and the bits */
1853 for (i=0; i < (1u << bpp); i++)
1854 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1855 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1856 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1857 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1858 "color table entry %d differs (bpp %d)\n", i, bpp );
1860 ok( !memcmp( bits, bits2, dib_size ), "bit mismatch (bpp %d)\n", bpp );
1862 /* Test various combinations of lines = 0 and bits2 = NULL */
1863 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1864 res = GetDIBits( dc, dib, 0, 0, bits2, info2, DIB_RGB_COLORS );
1865 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1866 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1867 "color table mismatch (bpp %d)\n", bpp );
1869 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1870 res = GetDIBits( dc, dib, 0, 0, NULL, info2, DIB_RGB_COLORS );
1871 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1872 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1873 "color table mismatch (bpp %d)\n", bpp );
1875 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1876 res = GetDIBits( dc, dib, 0, info->bmiHeader.biHeight, NULL, info2, DIB_RGB_COLORS );
1877 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1878 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1879 "color table mismatch (bpp %d)\n", bpp );
1881 /* Map into a 32bit-DIB */
1882 info2->bmiHeader.biBitCount = 32;
1883 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1884 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1886 /* Check if last pixel was set */
1887 pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
1888 ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
1890 HeapFree(GetProcessHeap(), 0, bits2);
1891 DeleteDC(dc);
1893 SelectObject(dib_dc, old_bmp);
1894 DeleteDC(dib_dc);
1895 DeleteObject(dib);
1896 HeapFree(GetProcessHeap(), 0, info2);
1897 HeapFree(GetProcessHeap(), 0, info);
1900 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1902 HBITMAP ddb;
1903 BITMAPINFO *info;
1904 BITMAPINFO *info2;
1905 void * bits;
1906 void * bits2;
1907 HDC ddb_dc, dc;
1908 HBITMAP old_bmp;
1909 UINT width, height;
1910 UINT bpp;
1911 UINT i, j;
1912 int res;
1914 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1915 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1917 width = height = 16;
1919 /* Create a DDB (device-dependent bitmap) */
1920 if (monochrome)
1922 bpp = 1;
1923 ddb = CreateBitmap(width, height, 1, 1, NULL);
1925 else
1927 HDC screen_dc = GetDC(NULL);
1928 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1929 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1930 ReleaseDC(NULL, screen_dc);
1933 /* Set the pixels */
1934 ddb_dc = CreateCompatibleDC(NULL);
1935 old_bmp = SelectObject(ddb_dc, ddb);
1936 for (i = 0; i < width; i++)
1938 for (j=0; j < height; j++)
1940 BYTE c = (i * width + j) % 256;
1941 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1944 SelectObject(ddb_dc, old_bmp);
1946 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1947 info->bmiHeader.biWidth = width;
1948 info->bmiHeader.biHeight = height;
1949 info->bmiHeader.biPlanes = 1;
1950 info->bmiHeader.biBitCount = bpp;
1951 info->bmiHeader.biCompression = BI_RGB;
1953 dc = CreateCompatibleDC(NULL);
1955 /* Fill in biSizeImage */
1956 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1957 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1959 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1960 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1962 /* Get the bits */
1963 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1964 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1966 /* Copy the DIB attributes but not the color table */
1967 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1969 /* Select the DDB into another DC */
1970 old_bmp = SelectObject(ddb_dc, ddb);
1972 /* Get the bits */
1973 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1974 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1976 /* Compare the color table and the bits */
1977 if (bpp <= 8)
1979 for (i=0; i < (1u << bpp); i++)
1980 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1981 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1982 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1983 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1984 "color table entry %d differs (bpp %d)\n", i, bpp );
1987 ok( !memcmp( bits, bits2, info->bmiHeader.biSizeImage ), "bit mismatch (bpp %d)\n", bpp );
1989 /* Test the palette */
1990 if (info2->bmiHeader.biBitCount <= 8)
1992 WORD *colors = (WORD*)info2->bmiColors;
1994 /* Get the palette indices */
1995 res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1996 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1998 for (i = 0; i < (1 << info->bmiHeader.biBitCount); i++)
1999 ok( colors[i] == i, "%d: got %d (bpp %d)\n", i, colors[i], bpp );
2002 HeapFree(GetProcessHeap(), 0, bits2);
2003 HeapFree(GetProcessHeap(), 0, bits);
2004 DeleteDC(dc);
2006 SelectObject(ddb_dc, old_bmp);
2007 DeleteDC(ddb_dc);
2008 DeleteObject(ddb);
2009 HeapFree(GetProcessHeap(), 0, info2);
2010 HeapFree(GetProcessHeap(), 0, info);
2013 static void test_GetDIBits(void)
2015 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
2016 static const BYTE bmp_bits_1[16 * 2] =
2018 0xff,0xff, 0,0, 0xff,0xff, 0,0,
2019 0xff,0xff, 0,0, 0xff,0xff, 0,0,
2020 0xff,0xff, 0,0, 0xff,0xff, 0,0,
2021 0xff,0xff, 0,0, 0xff,0xff, 0,0
2023 /* 4-bytes aligned 1-bit DIB data: 16x16 */
2024 static const BYTE dib_bits_1[16 * 4] =
2026 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
2027 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
2028 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
2029 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
2031 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
2032 static const BYTE bmp_bits_24[16 * 16*3] =
2034 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2035 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2036 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2037 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2038 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2039 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2040 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2041 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2042 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2043 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2044 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2045 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2046 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2047 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2048 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2049 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2050 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2051 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2052 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2053 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2054 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2055 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2056 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2057 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2058 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2059 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2060 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2061 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2062 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2063 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2064 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2065 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
2067 /* 4-bytes aligned 24-bit DIB data: 16x16 */
2068 static const BYTE dib_bits_24[16 * 16*3] =
2070 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2071 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2072 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2073 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2074 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2075 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2076 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2077 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2078 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2079 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2080 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2081 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2082 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2083 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2084 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2085 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2086 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2087 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2088 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2089 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2090 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2091 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2092 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2093 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2094 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2095 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2096 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2097 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2098 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2099 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2100 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2101 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
2103 HBITMAP hbmp;
2104 BITMAP bm;
2105 HDC hdc;
2106 int i, bytes, lines;
2107 BYTE buf[1024];
2108 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
2109 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
2110 RGBQUAD *colors = bi->bmiColors;
2111 PALETTEENTRY pal_ents[20];
2113 hdc = GetDC(0);
2115 /* 1-bit source bitmap data */
2116 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
2117 ok(hbmp != 0, "CreateBitmap failed\n");
2119 memset(&bm, 0xAA, sizeof(bm));
2120 bytes = GetObjectW(hbmp, sizeof(bm), &bm);
2121 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2122 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2123 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
2124 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
2125 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2126 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
2127 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2128 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2130 bytes = GetBitmapBits(hbmp, 0, NULL);
2131 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
2132 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
2133 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
2134 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
2136 /* retrieve 1-bit DIB data */
2137 memset(bi, 0, sizeof(*bi));
2138 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2139 bi->bmiHeader.biWidth = bm.bmWidth;
2140 bi->bmiHeader.biHeight = bm.bmHeight;
2141 bi->bmiHeader.biPlanes = 1;
2142 bi->bmiHeader.biBitCount = 1;
2143 bi->bmiHeader.biCompression = BI_RGB;
2144 bi->bmiHeader.biClrUsed = 37;
2145 bi->bmiHeader.biSizeImage = 0;
2146 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2147 SetLastError(0xdeadbeef);
2148 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2149 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
2150 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
2151 broken(GetLastError() == 0xdeadbeef), /* winnt */
2152 "wrong error %u\n", GetLastError());
2153 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
2154 ok(bi->bmiHeader.biClrUsed == 37 || broken(bi->bmiHeader.biClrUsed == 0),
2155 "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2157 memset(buf, 0xAA, sizeof(buf));
2158 SetLastError(0xdeadbeef);
2159 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2160 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2161 lines, bm.bmHeight, GetLastError());
2162 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
2163 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2165 /* the color table consists of black and white */
2166 ok(colors[0].rgbRed == 0 && colors[0].rgbGreen == 0 &&
2167 colors[0].rgbBlue == 0 && colors[0].rgbReserved == 0,
2168 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
2169 colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue, colors[0].rgbReserved);
2170 ok(colors[1].rgbRed == 0xff && colors[1].rgbGreen == 0xff &&
2171 colors[1].rgbBlue == 0xff && colors[1].rgbReserved == 0,
2172 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
2173 colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue, colors[1].rgbReserved);
2174 for (i = 2; i < 256; i++)
2176 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2177 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2178 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2179 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2182 /* returned bits are DWORD aligned and upside down */
2183 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
2185 /* Test the palette indices */
2186 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2187 SetLastError(0xdeadbeef);
2188 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
2189 ok(((WORD*)colors)[0] == 0, "Color 0 is %d\n", ((WORD*)colors)[0]);
2190 ok(((WORD*)colors)[1] == 1, "Color 1 is %d\n", ((WORD*)colors)[1]);
2191 for (i = 2; i < 256; i++)
2192 ok(((WORD*)colors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)colors)[1]);
2194 /* retrieve 24-bit DIB data */
2195 memset(bi, 0, sizeof(*bi));
2196 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2197 bi->bmiHeader.biWidth = bm.bmWidth;
2198 bi->bmiHeader.biHeight = bm.bmHeight;
2199 bi->bmiHeader.biPlanes = 1;
2200 bi->bmiHeader.biBitCount = 24;
2201 bi->bmiHeader.biCompression = BI_RGB;
2202 bi->bmiHeader.biClrUsed = 37;
2203 bi->bmiHeader.biSizeImage = 0;
2204 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2205 memset(buf, 0xAA, sizeof(buf));
2206 SetLastError(0xdeadbeef);
2207 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2208 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2209 lines, bm.bmHeight, GetLastError());
2210 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2211 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2213 /* the color table doesn't exist for 24-bit images */
2214 for (i = 0; i < 256; i++)
2216 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2217 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2218 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2219 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2222 /* returned bits are DWORD aligned and upside down */
2223 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2224 DeleteObject(hbmp);
2226 /* 24-bit source bitmap data */
2227 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
2228 ok(hbmp != 0, "CreateBitmap failed\n");
2229 SetLastError(0xdeadbeef);
2230 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
2231 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
2232 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
2233 lines, bm.bmHeight, GetLastError());
2235 memset(&bm, 0xAA, sizeof(bm));
2236 bytes = GetObjectW(hbmp, sizeof(bm), &bm);
2237 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2238 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2239 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
2240 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
2241 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2242 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
2243 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2244 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2246 bytes = GetBitmapBits(hbmp, 0, NULL);
2247 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
2248 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
2249 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
2250 bm.bmWidthBytes * bm.bmHeight, bytes);
2252 /* retrieve 1-bit DIB data */
2253 memset(bi, 0, sizeof(*bi));
2254 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2255 bi->bmiHeader.biWidth = bm.bmWidth;
2256 bi->bmiHeader.biHeight = bm.bmHeight;
2257 bi->bmiHeader.biPlanes = 1;
2258 bi->bmiHeader.biBitCount = 1;
2259 bi->bmiHeader.biCompression = BI_RGB;
2260 bi->bmiHeader.biClrUsed = 37;
2261 bi->bmiHeader.biSizeImage = 0;
2262 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2263 memset(buf, 0xAA, sizeof(buf));
2264 SetLastError(0xdeadbeef);
2265 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2266 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2267 lines, bm.bmHeight, GetLastError());
2268 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
2269 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2271 /* the color table consists of black and white */
2272 ok(colors[0].rgbRed == 0 && colors[0].rgbGreen == 0 &&
2273 colors[0].rgbBlue == 0 && colors[0].rgbReserved == 0,
2274 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
2275 colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue, colors[0].rgbReserved);
2276 ok(colors[1].rgbRed == 0xff && colors[1].rgbGreen == 0xff &&
2277 colors[1].rgbBlue == 0xff && colors[1].rgbReserved == 0,
2278 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
2279 colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue, colors[1].rgbReserved);
2280 for (i = 2; i < 256; i++)
2282 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2283 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2284 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2285 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2288 /* returned bits are DWORD aligned and upside down */
2289 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
2291 /* Test the palette indices */
2292 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2293 SetLastError(0xdeadbeef);
2294 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
2295 ok(((WORD*)colors)[0] == 0, "Color 0 is %d\n", ((WORD*)colors)[0]);
2296 ok(((WORD*)colors)[1] == 1, "Color 1 is %d\n", ((WORD*)colors)[1]);
2297 for (i = 2; i < 256; i++)
2298 ok(((WORD*)colors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)colors)[i]);
2300 /* retrieve 4-bit DIB data */
2301 memset(bi, 0, sizeof(*bi));
2302 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2303 bi->bmiHeader.biWidth = bm.bmWidth;
2304 bi->bmiHeader.biHeight = bm.bmHeight;
2305 bi->bmiHeader.biPlanes = 1;
2306 bi->bmiHeader.biBitCount = 4;
2307 bi->bmiHeader.biCompression = BI_RGB;
2308 bi->bmiHeader.biClrUsed = 37;
2309 bi->bmiHeader.biSizeImage = 0;
2310 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2311 memset(buf, 0xAA, sizeof(buf));
2312 SetLastError(0xdeadbeef);
2313 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2314 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2315 lines, bm.bmHeight, GetLastError());
2316 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2318 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2320 for (i = 0; i < 16; i++)
2322 RGBQUAD expect;
2323 int entry = i < 8 ? i : i + 4;
2325 if(entry == 7) entry = 12;
2326 else if(entry == 12) entry = 7;
2328 expect.rgbRed = pal_ents[entry].peRed;
2329 expect.rgbGreen = pal_ents[entry].peGreen;
2330 expect.rgbBlue = pal_ents[entry].peBlue;
2331 expect.rgbReserved = 0;
2333 ok(!memcmp(colors + i, &expect, sizeof(expect)),
2334 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2335 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2336 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2339 /* retrieve 8-bit DIB data */
2340 memset(bi, 0, sizeof(*bi));
2341 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2342 bi->bmiHeader.biWidth = bm.bmWidth;
2343 bi->bmiHeader.biHeight = bm.bmHeight;
2344 bi->bmiHeader.biPlanes = 1;
2345 bi->bmiHeader.biBitCount = 8;
2346 bi->bmiHeader.biCompression = BI_RGB;
2347 bi->bmiHeader.biClrUsed = 37;
2348 bi->bmiHeader.biSizeImage = 0;
2349 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2350 memset(buf, 0xAA, sizeof(buf));
2351 SetLastError(0xdeadbeef);
2352 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2353 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2354 lines, bm.bmHeight, GetLastError());
2355 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2357 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2359 for (i = 0; i < 256; i++)
2361 RGBQUAD expect;
2363 if (i < 10 || i >= 246)
2365 int entry = i < 10 ? i : i - 236;
2366 expect.rgbRed = pal_ents[entry].peRed;
2367 expect.rgbGreen = pal_ents[entry].peGreen;
2368 expect.rgbBlue = pal_ents[entry].peBlue;
2370 else
2372 expect.rgbRed = (i & 0x07) << 5;
2373 expect.rgbGreen = (i & 0x38) << 2;
2374 expect.rgbBlue = i & 0xc0;
2376 expect.rgbReserved = 0;
2378 ok(!memcmp(colors + i, &expect, sizeof(expect)),
2379 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2380 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2381 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2384 /* retrieve 24-bit DIB data */
2385 memset(bi, 0, sizeof(*bi));
2386 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2387 bi->bmiHeader.biWidth = bm.bmWidth;
2388 bi->bmiHeader.biHeight = bm.bmHeight;
2389 bi->bmiHeader.biPlanes = 1;
2390 bi->bmiHeader.biBitCount = 24;
2391 bi->bmiHeader.biCompression = BI_RGB;
2392 bi->bmiHeader.biClrUsed = 37;
2393 bi->bmiHeader.biSizeImage = 0;
2394 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2395 memset(buf, 0xAA, sizeof(buf));
2396 SetLastError(0xdeadbeef);
2397 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2398 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2399 lines, bm.bmHeight, GetLastError());
2400 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2401 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2403 /* the color table doesn't exist for 24-bit images */
2404 for (i = 0; i < 256; i++)
2406 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2407 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2408 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2409 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2412 /* returned bits are DWORD aligned and upside down */
2413 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2414 DeleteObject(hbmp);
2416 ReleaseDC(0, hdc);
2419 static void test_GetDIBits_BI_BITFIELDS(void)
2421 /* Try a screen resolution detection technique
2422 * from the September 1999 issue of Windows Developer's Journal
2423 * which seems to be in widespread use.
2424 * http://www.lesher.ws/highcolor.html
2425 * http://www.lesher.ws/vidfmt.c
2426 * It hinges on being able to retrieve the bitmaps
2427 * for the three primary colors in non-paletted 16 bit mode.
2429 char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
2430 DWORD bits[32];
2431 LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
2432 DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
2433 HDC hdc;
2434 HBITMAP hbm;
2435 int ret;
2436 void *ptr;
2438 memset(dibinfo, 0, sizeof(dibinfo_buf));
2439 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2441 hdc = GetDC(NULL);
2442 ok(hdc != NULL, "GetDC failed?\n");
2443 hbm = CreateCompatibleBitmap(hdc, 1, 1);
2444 ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
2446 /* Call GetDIBits to fill in bmiHeader. */
2447 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2448 ok(ret == 1, "GetDIBits failed\n");
2449 if (dibinfo->bmiHeader.biBitCount > 8)
2451 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2452 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2453 "compression is %u (%d bpp)\n", dibinfo->bmiHeader.biCompression, dibinfo->bmiHeader.biBitCount );
2455 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2457 ok( !bitmasks[0], "red mask is set\n" );
2458 ok( !bitmasks[1], "green mask is set\n" );
2459 ok( !bitmasks[2], "blue mask is set\n" );
2461 /* test with NULL bits pointer and correct bpp */
2462 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2463 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2464 ok(ret == 1, "GetDIBits failed\n");
2466 ok( bitmasks[0] != 0, "red mask is not set\n" );
2467 ok( bitmasks[1] != 0, "green mask is not set\n" );
2468 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2469 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2471 /* test with valid bits pointer */
2472 memset(dibinfo, 0, sizeof(dibinfo_buf));
2473 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2474 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2475 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2476 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2477 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2478 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2480 ok( bitmasks[0] != 0, "red mask is not set\n" );
2481 ok( bitmasks[1] != 0, "green mask is not set\n" );
2482 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2483 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2485 /* now with bits and 0 lines */
2486 memset(dibinfo, 0, sizeof(dibinfo_buf));
2487 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2488 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2489 SetLastError(0xdeadbeef);
2490 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2491 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2493 ok( !bitmasks[0], "red mask is set\n" );
2494 ok( !bitmasks[1], "green mask is set\n" );
2495 ok( !bitmasks[2], "blue mask is set\n" );
2496 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2498 memset(bitmasks, 0, 3*sizeof(DWORD));
2499 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2500 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2501 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2503 ok( bitmasks[0] != 0, "red mask is not set\n" );
2504 ok( bitmasks[1] != 0, "green mask is not set\n" );
2505 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2506 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2509 else skip("bitmap in colortable mode, skipping BI_BITFIELDS tests\n");
2511 DeleteObject(hbm);
2513 /* same thing now with a 32-bpp DIB section */
2515 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2516 dibinfo->bmiHeader.biWidth = 1;
2517 dibinfo->bmiHeader.biHeight = 1;
2518 dibinfo->bmiHeader.biPlanes = 1;
2519 dibinfo->bmiHeader.biBitCount = 32;
2520 dibinfo->bmiHeader.biCompression = BI_RGB;
2521 dibinfo->bmiHeader.biSizeImage = 0;
2522 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2523 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2524 dibinfo->bmiHeader.biClrUsed = 0;
2525 dibinfo->bmiHeader.biClrImportant = 0;
2526 bitmasks[0] = 0x0000ff;
2527 bitmasks[1] = 0x00ff00;
2528 bitmasks[2] = 0xff0000;
2529 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2530 ok( hbm != 0, "failed to create bitmap\n" );
2532 memset(dibinfo, 0, sizeof(dibinfo_buf));
2533 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2534 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2535 ok(ret == 1, "GetDIBits failed\n");
2536 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2538 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2539 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2540 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2541 ok( !bitmasks[0], "red mask is set\n" );
2542 ok( !bitmasks[1], "green mask is set\n" );
2543 ok( !bitmasks[2], "blue mask is set\n" );
2545 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2546 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2547 ok(ret == 1, "GetDIBits failed\n");
2548 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2549 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2550 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2551 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2552 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2554 ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
2555 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2556 ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
2558 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2560 DeleteObject(hbm);
2562 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2563 dibinfo->bmiHeader.biWidth = 1;
2564 dibinfo->bmiHeader.biHeight = 1;
2565 dibinfo->bmiHeader.biPlanes = 1;
2566 dibinfo->bmiHeader.biBitCount = 32;
2567 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2568 dibinfo->bmiHeader.biSizeImage = 0;
2569 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2570 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2571 dibinfo->bmiHeader.biClrUsed = 0;
2572 dibinfo->bmiHeader.biClrImportant = 0;
2573 bitmasks[0] = 0x0000ff;
2574 bitmasks[1] = 0x00ff00;
2575 bitmasks[2] = 0xff0000;
2576 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2577 ok( hbm != 0, "failed to create bitmap\n" );
2579 if (hbm)
2581 memset(dibinfo, 0, sizeof(dibinfo_buf));
2582 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2583 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2584 ok(ret == 1, "GetDIBits failed\n");
2586 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
2587 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2588 ok( !bitmasks[0], "red mask is set\n" );
2589 ok( !bitmasks[1], "green mask is set\n" );
2590 ok( !bitmasks[2], "blue mask is set\n" );
2592 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2593 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2594 ok(ret == 1, "GetDIBits failed\n");
2595 ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
2596 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2597 ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
2598 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2600 DeleteObject(hbm);
2603 /* 24-bpp DIB sections don't have bitfields */
2605 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2606 dibinfo->bmiHeader.biWidth = 1;
2607 dibinfo->bmiHeader.biHeight = 1;
2608 dibinfo->bmiHeader.biPlanes = 1;
2609 dibinfo->bmiHeader.biBitCount = 24;
2610 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2611 dibinfo->bmiHeader.biSizeImage = 0;
2612 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2613 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2614 dibinfo->bmiHeader.biClrUsed = 0;
2615 dibinfo->bmiHeader.biClrImportant = 0;
2616 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2617 ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
2618 dibinfo->bmiHeader.biCompression = BI_RGB;
2619 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2620 ok( hbm != 0, "failed to create bitmap\n" );
2622 memset(dibinfo, 0, sizeof(dibinfo_buf));
2623 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2624 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2625 ok(ret == 1, "GetDIBits failed\n");
2626 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2628 ok( dibinfo->bmiHeader.biCompression == BI_RGB,
2629 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2630 ok( !bitmasks[0], "red mask is set\n" );
2631 ok( !bitmasks[1], "green mask is set\n" );
2632 ok( !bitmasks[2], "blue mask is set\n" );
2634 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2635 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2636 ok(ret == 1, "GetDIBits failed\n");
2637 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2638 ok( !bitmasks[0], "red mask is set\n" );
2639 ok( !bitmasks[1], "green mask is set\n" );
2640 ok( !bitmasks[2], "blue mask is set\n" );
2641 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2643 DeleteObject(hbm);
2644 ReleaseDC(NULL, hdc);
2647 static void test_select_object(void)
2649 HDC hdc;
2650 HBITMAP hbm, hbm_old;
2651 INT planes, bpp, i;
2652 DWORD depths[] = {8, 15, 16, 24, 32};
2653 BITMAP bm;
2654 DWORD bytes;
2656 hdc = GetDC(0);
2657 ok(hdc != 0, "GetDC(0) failed\n");
2658 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2659 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2661 hbm_old = SelectObject(hdc, hbm);
2662 ok(hbm_old == 0, "SelectObject should fail\n");
2664 DeleteObject(hbm);
2665 ReleaseDC(0, hdc);
2667 hdc = CreateCompatibleDC(0);
2668 ok(hdc != 0, "GetDC(0) failed\n");
2669 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2670 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2672 hbm_old = SelectObject(hdc, hbm);
2673 ok(hbm_old != 0, "SelectObject failed\n");
2674 hbm_old = SelectObject(hdc, hbm_old);
2675 ok(hbm_old == hbm, "SelectObject failed\n");
2677 DeleteObject(hbm);
2679 /* test an 1-bpp bitmap */
2680 planes = GetDeviceCaps(hdc, PLANES);
2681 bpp = 1;
2683 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
2684 ok(hbm != 0, "CreateBitmap failed\n");
2686 hbm_old = SelectObject(hdc, hbm);
2687 ok(hbm_old != 0, "SelectObject failed\n");
2688 hbm_old = SelectObject(hdc, hbm_old);
2689 ok(hbm_old == hbm, "SelectObject failed\n");
2691 DeleteObject(hbm);
2693 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
2694 /* test a color bitmap to dc bpp matching */
2695 planes = GetDeviceCaps(hdc, PLANES);
2696 bpp = GetDeviceCaps(hdc, BITSPIXEL);
2698 hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
2699 ok(hbm != 0, "CreateBitmap failed\n");
2701 hbm_old = SelectObject(hdc, hbm);
2702 if(depths[i] == bpp ||
2703 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
2705 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
2706 SelectObject(hdc, hbm_old);
2707 } else {
2708 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
2711 memset(&bm, 0xAA, sizeof(bm));
2712 bytes = GetObjectW(hbm, sizeof(bm), &bm);
2713 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2714 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2715 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
2716 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
2717 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2718 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
2719 if(depths[i] == 15) {
2720 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
2721 } else {
2722 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2724 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2726 DeleteObject(hbm);
2729 DeleteDC(hdc);
2732 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
2734 INT ret;
2735 BITMAP bm;
2737 ret = GetObjectType(hbmp);
2738 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
2740 ret = GetObjectW(hbmp, 0, 0);
2741 ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
2743 memset(&bm, 0xDA, sizeof(bm));
2744 SetLastError(0xdeadbeef);
2745 ret = GetObjectW(hbmp, sizeof(bm), &bm);
2746 if (!ret) /* XP, only for curObj2 */ return;
2747 ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
2748 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2749 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2750 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2751 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2752 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2753 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2754 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2757 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2759 static void test_CreateBitmap(void)
2761 BITMAP bmp;
2762 HDC screenDC = GetDC(0);
2763 HDC hdc = CreateCompatibleDC(screenDC);
2764 UINT i, expect = 0;
2766 /* all of these are the stock monochrome bitmap */
2767 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2768 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2769 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2770 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2771 HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2772 HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2774 /* these 2 are not the stock monochrome bitmap */
2775 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2776 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2778 HBITMAP old1 = SelectObject(hdc, bm2);
2779 HBITMAP old2 = SelectObject(screenDC, bm3);
2780 SelectObject(hdc, old1);
2781 SelectObject(screenDC, old2);
2783 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2784 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2785 bm, bm1, bm4, bm5, curObj1, old1);
2786 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2787 todo_wine
2788 ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
2789 ok(old2 == 0, "old2 %p\n", old2);
2791 test_mono_1x1_bmp(bm);
2792 test_mono_1x1_bmp(bm1);
2793 test_mono_1x1_bmp(bm2);
2794 test_mono_1x1_bmp(bm3);
2795 test_mono_1x1_bmp(bm4);
2796 test_mono_1x1_bmp(bm5);
2797 test_mono_1x1_bmp(old1);
2798 test_mono_1x1_bmp(curObj1);
2800 DeleteObject(bm);
2801 DeleteObject(bm1);
2802 DeleteObject(bm2);
2803 DeleteObject(bm3);
2804 DeleteObject(bm4);
2805 DeleteObject(bm5);
2807 DeleteDC(hdc);
2808 ReleaseDC(0, screenDC);
2810 /* show that Windows ignores the provided bm.bmWidthBytes */
2811 bmp.bmType = 0;
2812 bmp.bmWidth = 1;
2813 bmp.bmHeight = 1;
2814 bmp.bmWidthBytes = 28;
2815 bmp.bmPlanes = 1;
2816 bmp.bmBitsPixel = 1;
2817 bmp.bmBits = NULL;
2818 bm = CreateBitmapIndirect(&bmp);
2819 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2820 test_mono_1x1_bmp(bm);
2821 DeleteObject(bm);
2823 /* Test how the bmBitsPixel field is treated */
2824 for(i = 1; i <= 33; i++) {
2825 bmp.bmType = 0;
2826 bmp.bmWidth = 1;
2827 bmp.bmHeight = 1;
2828 bmp.bmWidthBytes = 28;
2829 bmp.bmPlanes = 1;
2830 bmp.bmBitsPixel = i;
2831 bmp.bmBits = NULL;
2832 SetLastError(0xdeadbeef);
2833 bm = CreateBitmapIndirect(&bmp);
2834 if(i > 32) {
2835 DWORD error = GetLastError();
2836 ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
2837 ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2838 DeleteObject(bm);
2839 continue;
2841 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2842 GetObjectW(bm, sizeof(bmp), &bmp);
2843 if(i == 1) {
2844 expect = 1;
2845 } else if(i <= 4) {
2846 expect = 4;
2847 } else if(i <= 8) {
2848 expect = 8;
2849 } else if(i <= 16) {
2850 expect = 16;
2851 } else if(i <= 24) {
2852 expect = 24;
2853 } else if(i <= 32) {
2854 expect = 32;
2856 ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2857 i, bmp.bmBitsPixel, expect);
2858 DeleteObject(bm);
2862 static void test_bitmapinfoheadersize(void)
2864 HBITMAP hdib;
2865 BITMAPINFO bmi;
2866 BITMAPCOREINFO bci;
2867 HDC hdc = GetDC(0);
2869 memset(&bmi, 0, sizeof(BITMAPINFO));
2870 bmi.bmiHeader.biHeight = 100;
2871 bmi.bmiHeader.biWidth = 512;
2872 bmi.bmiHeader.biBitCount = 24;
2873 bmi.bmiHeader.biPlanes = 1;
2875 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2877 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2878 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2880 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2882 SetLastError(0xdeadbeef);
2883 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2884 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2885 DeleteObject(hdib);
2887 bmi.bmiHeader.biSize++;
2889 SetLastError(0xdeadbeef);
2890 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2891 ok(hdib != NULL ||
2892 broken(!hdib), /* Win98, WinMe */
2893 "CreateDIBSection error %d\n", GetLastError());
2894 DeleteObject(hdib);
2896 bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2898 SetLastError(0xdeadbeef);
2899 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2900 ok(hdib != NULL ||
2901 broken(!hdib), /* Win98, WinMe */
2902 "CreateDIBSection error %d\n", GetLastError());
2903 DeleteObject(hdib);
2905 bmi.bmiHeader.biSize++;
2907 SetLastError(0xdeadbeef);
2908 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2909 ok(hdib != NULL ||
2910 broken(!hdib), /* Win98, WinMe */
2911 "CreateDIBSection error %d\n", GetLastError());
2912 DeleteObject(hdib);
2914 bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2916 SetLastError(0xdeadbeef);
2917 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2918 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2919 DeleteObject(hdib);
2921 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2923 SetLastError(0xdeadbeef);
2924 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2925 ok(hdib != NULL ||
2926 broken(!hdib), /* Win95 */
2927 "CreateDIBSection error %d\n", GetLastError());
2928 DeleteObject(hdib);
2930 memset(&bci, 0, sizeof(BITMAPCOREINFO));
2931 bci.bmciHeader.bcHeight = 100;
2932 bci.bmciHeader.bcWidth = 512;
2933 bci.bmciHeader.bcBitCount = 24;
2934 bci.bmciHeader.bcPlanes = 1;
2936 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2938 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2939 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2941 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2943 SetLastError(0xdeadbeef);
2944 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2945 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2946 DeleteObject(hdib);
2948 bci.bmciHeader.bcSize++;
2950 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2951 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2953 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2955 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2956 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2958 ReleaseDC(0, hdc);
2961 static void test_get16dibits(void)
2963 BYTE bits[4 * (16 / sizeof(BYTE))];
2964 HBITMAP hbmp;
2965 HDC screen_dc = GetDC(NULL);
2966 int ret;
2967 BITMAPINFO * info;
2968 int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2969 BYTE *p;
2970 int overwritten_bytes = 0;
2972 memset(bits, 0, sizeof(bits));
2973 hbmp = CreateBitmap(2, 2, 1, 16, bits);
2974 ok(hbmp != NULL, "CreateBitmap failed\n");
2976 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2977 assert(info);
2979 memset(info, '!', info_len);
2980 memset(info, 0, sizeof(info->bmiHeader));
2982 info->bmiHeader.biSize = sizeof(info->bmiHeader);
2983 info->bmiHeader.biWidth = 2;
2984 info->bmiHeader.biHeight = 2;
2985 info->bmiHeader.biPlanes = 1;
2986 info->bmiHeader.biCompression = BI_RGB;
2988 ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2989 ok(ret != 0, "GetDIBits failed got %d\n", ret);
2991 for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2992 if (*p != '!')
2993 overwritten_bytes++;
2994 ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2996 HeapFree(GetProcessHeap(), 0, info);
2997 DeleteObject(hbmp);
2998 ReleaseDC(NULL, screen_dc);
3001 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
3002 DWORD dwRop, UINT32 expected, int line)
3004 *srcBuffer = 0xFEDCBA98;
3005 *dstBuffer = 0x89ABCDEF;
3006 BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
3007 ok(expected == *dstBuffer,
3008 "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
3009 dwRop, expected, *dstBuffer, line);
3012 static void test_BitBlt(void)
3014 HBITMAP bmpDst, bmpSrc;
3015 HBITMAP oldDst, oldSrc;
3016 HDC hdcScreen, hdcDst, hdcSrc;
3017 UINT32 *dstBuffer, *srcBuffer;
3018 HBRUSH hBrush, hOldBrush;
3019 BITMAPINFO bitmapInfo;
3021 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3022 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3023 bitmapInfo.bmiHeader.biWidth = 1;
3024 bitmapInfo.bmiHeader.biHeight = 1;
3025 bitmapInfo.bmiHeader.biPlanes = 1;
3026 bitmapInfo.bmiHeader.biBitCount = 32;
3027 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3028 bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
3030 hdcScreen = CreateCompatibleDC(0);
3031 hdcDst = CreateCompatibleDC(hdcScreen);
3032 hdcSrc = CreateCompatibleDC(hdcDst);
3034 /* Setup the destination dib section */
3035 bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
3036 NULL, 0);
3037 oldDst = SelectObject(hdcDst, bmpDst);
3039 hBrush = CreateSolidBrush(0x12345678);
3040 hOldBrush = SelectObject(hdcDst, hBrush);
3042 /* Setup the source dib section */
3043 bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
3044 NULL, 0);
3045 oldSrc = SelectObject(hdcSrc, bmpSrc);
3047 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3048 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3049 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3050 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3051 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3052 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3053 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3054 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3055 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3056 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3057 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3058 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3059 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3060 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3061 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3063 /* Tidy up */
3064 SelectObject(hdcSrc, oldSrc);
3065 DeleteObject(bmpSrc);
3066 DeleteDC(hdcSrc);
3068 SelectObject(hdcDst, hOldBrush);
3069 DeleteObject(hBrush);
3070 SelectObject(hdcDst, oldDst);
3071 DeleteObject(bmpDst);
3072 DeleteDC(hdcDst);
3075 DeleteDC(hdcScreen);
3078 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
3079 DWORD dwRop, UINT32 expected, int line)
3081 *srcBuffer = 0xFEDCBA98;
3082 *dstBuffer = 0x89ABCDEF;
3083 StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
3084 ok(expected == *dstBuffer,
3085 "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
3086 dwRop, expected, *dstBuffer, line);
3089 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, BITMAPINFO *dst_info, UINT32 *dstBuffer, UINT32 *srcBuffer,
3090 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
3091 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
3092 UINT32 *expected, int line)
3094 int dst_size = get_dib_image_size( dst_info );
3096 memset(dstBuffer, 0, dst_size);
3097 StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
3098 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
3099 ok(memcmp(dstBuffer, expected, dst_size) == 0,
3100 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
3101 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
3102 expected[0], expected[1], expected[2], expected[3],
3103 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
3104 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3105 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
3108 static void test_StretchBlt(void)
3110 HBITMAP bmpDst, bmpSrc;
3111 HBITMAP oldDst, oldSrc;
3112 HDC hdcScreen, hdcDst, hdcSrc;
3113 UINT32 *dstBuffer, *srcBuffer;
3114 HBRUSH hBrush, hOldBrush;
3115 BITMAPINFO biDst, biSrc;
3116 UINT32 expected[256];
3117 RGBQUAD colors[2];
3119 memset(&biDst, 0, sizeof(BITMAPINFO));
3120 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3121 biDst.bmiHeader.biWidth = 16;
3122 biDst.bmiHeader.biHeight = -16;
3123 biDst.bmiHeader.biPlanes = 1;
3124 biDst.bmiHeader.biBitCount = 32;
3125 biDst.bmiHeader.biCompression = BI_RGB;
3126 memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
3128 hdcScreen = CreateCompatibleDC(0);
3129 hdcDst = CreateCompatibleDC(hdcScreen);
3130 hdcSrc = CreateCompatibleDC(hdcDst);
3132 /* Pixel Tests */
3133 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3134 NULL, 0);
3135 oldDst = SelectObject(hdcDst, bmpDst);
3137 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
3138 NULL, 0);
3139 oldSrc = SelectObject(hdcSrc, bmpSrc);
3141 hBrush = CreateSolidBrush(0x012345678);
3142 hOldBrush = SelectObject(hdcDst, hBrush);
3144 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3145 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3146 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3147 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3148 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3149 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3150 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3151 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3152 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3153 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3154 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3155 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3156 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3157 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3158 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3160 SelectObject(hdcDst, hOldBrush);
3161 DeleteObject(hBrush);
3163 /* Top-down to top-down tests */
3164 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3165 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
3167 memset( expected, 0, get_dib_image_size( &biDst ) );
3168 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
3169 expected[16] = 0xFEDCBA98, expected[17] = 0x76543210;
3170 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3171 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3173 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3174 expected[16] = 0x00000000, expected[17] = 0x00000000;
3175 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3176 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
3178 expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
3179 expected[16] = 0xCAFED00D, expected[17] = 0xCAFED00D;
3180 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3181 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
3183 /* This is an example of the dst width (height) == 1 exception, explored below */
3184 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3185 expected[16] = 0x00000000, expected[17] = 0x00000000;
3186 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3187 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
3189 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
3190 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
3191 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3192 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3194 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
3195 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
3196 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3197 1, 1, -2, -2, 0, 0, 2, 2, expected, __LINE__);
3199 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3200 expected[16] = 0x00000000, expected[17] = 0x00000000;
3201 todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3202 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
3204 expected[0] = 0x00000000, expected[1] = 0x00000000;
3205 expected[16] = 0x00000000, expected[17] = 0xCAFED00D, expected[18] = 0xFEEDFACE;
3206 expected[32] = 0x00000000, expected[33] = 0xFEDCBA98, expected[34] = 0x76543210;
3208 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3209 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3211 /* when dst width is 1 merge src width - 1 pixels */
3212 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
3213 srcBuffer[0] = 0x0000ff00, srcBuffer[1] = 0x0000f0f0, srcBuffer[2] = 0x0000cccc, srcBuffer[3] = 0x0000aaaa;
3214 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
3216 memset( expected, 0, get_dib_image_size( &biDst ) );
3217 expected[0] = srcBuffer[0];
3218 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3219 0, 0, 1, 1, 0, 0, 2, 1, expected, __LINE__);
3221 expected[0] = srcBuffer[0] & srcBuffer[1];
3222 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3223 0, 0, 1, 1, 0, 0, 3, 1, expected, __LINE__);
3225 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
3226 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3227 0, 0, 1, 1, 0, 0, 4, 1, expected, __LINE__);
3229 /* this doesn't happen if the src width is -ve */
3230 expected[0] = srcBuffer[1] & srcBuffer[2];
3231 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3232 0, 0, 1, 1, 2, 0, -2, 1, expected, __LINE__);
3234 /* when dst width > 1 behaviour reverts to what one would expect */
3235 expected[0] = srcBuffer[0] & srcBuffer[1], expected[1] = srcBuffer[2] & srcBuffer[3];
3236 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3237 0, 0, 2, 1, 0, 0, 4, 1, expected, __LINE__);
3239 /* similarly in the vertical direction */
3240 memset( expected, 0, get_dib_image_size( &biDst ) );
3241 expected[0] = srcBuffer[0];
3242 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3243 0, 0, 1, 1, 0, 0, 1, 2, expected, __LINE__);
3245 /* check that it's the dst size in device units that needs to be 1 */
3246 SetMapMode( hdcDst, MM_ISOTROPIC );
3247 SetWindowExtEx( hdcDst, 200, 200, NULL );
3248 SetViewportExtEx( hdcDst, 100, 100, NULL );
3250 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
3251 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3252 0, 0, 2, 2, 0, 0, 4, 1, expected, __LINE__);
3253 SetMapMode( hdcDst, MM_TEXT );
3255 SelectObject(hdcDst, oldDst);
3256 DeleteObject(bmpDst);
3258 /* Top-down to bottom-up tests */
3259 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
3260 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3261 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
3263 biDst.bmiHeader.biHeight = 16;
3264 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3265 NULL, 0);
3266 oldDst = SelectObject(hdcDst, bmpDst);
3268 memset( expected, 0, get_dib_image_size( &biDst ) );
3270 expected[224] = 0xFEDCBA98, expected[225] = 0x76543210;
3271 expected[240] = 0xCAFED00D, expected[241] = 0xFEEDFACE;
3272 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3273 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3275 expected[224] = 0xFEEDFACE, expected[225] = 0xCAFED00D;
3276 expected[240] = 0x76543210, expected[241] = 0xFEDCBA98;
3277 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3278 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3280 SelectObject(hdcSrc, oldSrc);
3281 DeleteObject(bmpSrc);
3283 /* Bottom-up to bottom-up tests */
3284 biSrc.bmiHeader.biHeight = 16;
3285 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
3286 NULL, 0);
3287 srcBuffer[224] = 0xCAFED00D, srcBuffer[225] = 0xFEEDFACE;
3288 srcBuffer[240] = 0xFEDCBA98, srcBuffer[241] = 0x76543210;
3289 oldSrc = SelectObject(hdcSrc, bmpSrc);
3291 memset( expected, 0, get_dib_image_size( &biDst ) );
3293 expected[224] = 0xCAFED00D, expected[225] = 0xFEEDFACE;
3294 expected[240] = 0xFEDCBA98, expected[241] = 0x76543210;
3295 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3296 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3298 expected[224] = 0x76543210, expected[225] = 0xFEDCBA98;
3299 expected[240] = 0xFEEDFACE, expected[241] = 0xCAFED00D;
3300 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3301 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3303 SelectObject(hdcDst, oldDst);
3304 DeleteObject(bmpDst);
3306 /* Bottom-up to top-down tests */
3307 biDst.bmiHeader.biHeight = -16;
3308 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3309 NULL, 0);
3310 oldDst = SelectObject(hdcDst, bmpDst);
3312 memset( expected, 0, get_dib_image_size( &biDst ) );
3313 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3314 expected[16] = 0xCAFED00D, expected[17] = 0xFEEDFACE;
3315 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3316 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3318 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3319 expected[16] = 0x76543210, expected[17] = 0xFEDCBA98;
3320 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3321 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3323 SelectObject(hdcSrc, oldSrc);
3324 DeleteObject(bmpSrc);
3326 biSrc.bmiHeader.biHeight = -2;
3327 biSrc.bmiHeader.biBitCount = 24;
3328 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
3329 oldSrc = SelectObject(hdcSrc, bmpSrc);
3331 memset( expected, 0, get_dib_image_size( &biDst ) );
3332 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3333 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
3334 memcpy(dstBuffer, expected, 4 * sizeof(*dstBuffer));
3335 StretchBlt(hdcSrc, 0, 0, 4, 1, hdcDst, 0, 0, 4, 1, SRCCOPY );
3336 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
3337 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3338 expected[0] = 0x00EDFACE, expected[1] = 0x00FED00D;
3339 expected[2] = 0x00543210, expected[3] = 0x00DCBA98;
3340 ok(!memcmp(dstBuffer, expected, 16),
3341 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3342 expected[0], expected[1], expected[2], expected[3],
3343 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3345 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3346 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
3347 memcpy(srcBuffer, expected, 4 * sizeof(*dstBuffer));
3348 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
3349 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3350 expected[0] = 0x00EDFACE, expected[1] = 0x00D00DFE;
3351 expected[2] = 0x0010CAFE, expected[3] = 0x00765432;
3352 ok(!memcmp(dstBuffer, expected, 16),
3353 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3354 expected[0], expected[1], expected[2], expected[3],
3355 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3357 SelectObject(hdcSrc, oldSrc);
3358 DeleteObject(bmpSrc);
3360 biSrc.bmiHeader.biBitCount = 1;
3361 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
3362 oldSrc = SelectObject(hdcSrc, bmpSrc);
3363 *((DWORD *)colors + 0) = 0x123456;
3364 *((DWORD *)colors + 1) = 0x335577;
3365 SetDIBColorTable( hdcSrc, 0, 2, colors );
3366 srcBuffer[0] = 0x55555555;
3367 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
3368 SetTextColor( hdcDst, 0 );
3369 SetBkColor( hdcDst, 0 );
3370 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3371 expected[0] = expected[2] = 0x00123456;
3372 expected[1] = expected[3] = 0x00335577;
3373 ok(!memcmp(dstBuffer, expected, 16),
3374 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3375 expected[0], expected[1], expected[2], expected[3],
3376 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3378 SelectObject(hdcSrc, oldSrc);
3379 DeleteObject(bmpSrc);
3381 bmpSrc = CreateBitmap( 16, 16, 1, 1, 0 );
3382 oldSrc = SelectObject(hdcSrc, bmpSrc);
3383 SetPixel( hdcSrc, 0, 0, 0 );
3384 SetPixel( hdcSrc, 1, 0, 0xffffff );
3385 SetPixel( hdcSrc, 2, 0, 0xffffff );
3386 SetPixel( hdcSrc, 3, 0, 0 );
3387 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
3388 SetTextColor( hdcDst, RGB(0x22,0x44,0x66) );
3389 SetBkColor( hdcDst, RGB(0x65,0x43,0x21) );
3390 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3391 expected[0] = expected[3] = 0x00224466;
3392 expected[1] = expected[2] = 0x00654321;
3393 ok(!memcmp(dstBuffer, expected, 16),
3394 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3395 expected[0], expected[1], expected[2], expected[3],
3396 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3398 SelectObject(hdcSrc, oldSrc);
3399 DeleteObject(bmpSrc);
3401 DeleteDC(hdcSrc);
3403 SelectObject(hdcDst, oldDst);
3404 DeleteObject(bmpDst);
3405 DeleteDC(hdcDst);
3407 DeleteDC(hdcScreen);
3410 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3411 DWORD dwRop, UINT32 expected, int line)
3413 const UINT32 buffer[2] = { 0xFEDCBA98, 0 };
3414 BITMAPINFO bitmapInfo;
3416 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3417 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3418 bitmapInfo.bmiHeader.biWidth = 2;
3419 bitmapInfo.bmiHeader.biHeight = 1;
3420 bitmapInfo.bmiHeader.biPlanes = 1;
3421 bitmapInfo.bmiHeader.biBitCount = 32;
3422 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3423 bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer);
3425 *dstBuffer = 0x89ABCDEF;
3427 StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop);
3428 ok(expected == *dstBuffer,
3429 "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
3430 dwRop, expected, *dstBuffer, line);
3433 static INT check_StretchDIBits_stretch( HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3434 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
3435 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
3436 UINT32 expected[4], int line)
3438 BITMAPINFO bitmapInfo;
3439 INT ret;
3441 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3442 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3443 bitmapInfo.bmiHeader.biWidth = 2;
3444 bitmapInfo.bmiHeader.biHeight = -2;
3445 bitmapInfo.bmiHeader.biPlanes = 1;
3446 bitmapInfo.bmiHeader.biBitCount = 32;
3447 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3449 memset(dstBuffer, 0, 16);
3450 ret = StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
3451 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3452 srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
3453 ok(memcmp(dstBuffer, expected, 16) == 0,
3454 "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
3455 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
3456 expected[0], expected[1], expected[2], expected[3],
3457 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
3458 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3459 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
3460 return ret;
3463 static void test_StretchDIBits(void)
3465 HBITMAP bmpDst;
3466 HBITMAP oldDst;
3467 HDC hdcScreen, hdcDst;
3468 UINT32 *dstBuffer, srcBuffer[4];
3469 HBRUSH hBrush, hOldBrush;
3470 BITMAPINFO biDst;
3471 UINT32 expected[4];
3472 INT ret;
3474 memset(&biDst, 0, sizeof(BITMAPINFO));
3475 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3476 biDst.bmiHeader.biWidth = 2;
3477 biDst.bmiHeader.biHeight = -2;
3478 biDst.bmiHeader.biPlanes = 1;
3479 biDst.bmiHeader.biBitCount = 32;
3480 biDst.bmiHeader.biCompression = BI_RGB;
3482 hdcScreen = CreateCompatibleDC(0);
3483 hdcDst = CreateCompatibleDC(hdcScreen);
3485 /* Pixel Tests */
3486 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3487 NULL, 0);
3488 oldDst = SelectObject(hdcDst, bmpDst);
3490 hBrush = CreateSolidBrush(0x012345678);
3491 hOldBrush = SelectObject(hdcDst, hBrush);
3493 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3494 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3495 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3496 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3497 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3498 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3499 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3500 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3501 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3502 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3503 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3504 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3505 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3506 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3507 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3509 SelectObject(hdcDst, hOldBrush);
3510 DeleteObject(hBrush);
3512 /* Top-down destination tests */
3513 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3514 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
3516 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
3517 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
3518 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3519 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3520 ok( ret == 2, "got ret %d\n", ret );
3522 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3523 expected[2] = 0x00000000, expected[3] = 0x00000000;
3524 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3525 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
3526 todo_wine ok( ret == 1, "got ret %d\n", ret );
3528 expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
3529 expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
3530 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3531 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
3532 ok( ret == 2, "got ret %d\n", ret );
3534 expected[0] = 0x42441000, expected[1] = 0x00000000;
3535 expected[2] = 0x00000000, expected[3] = 0x00000000;
3536 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3537 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
3538 ok( ret == 2, "got ret %d\n", ret );
3540 expected[0] = 0x00000000, expected[1] = 0x00000000;
3541 expected[2] = 0x00000000, expected[3] = 0x00000000;
3542 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3543 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3544 ok( ret == 0, "got ret %d\n", ret );
3546 expected[0] = 0x00000000, expected[1] = 0x00000000;
3547 expected[2] = 0x00000000, expected[3] = 0x00000000;
3548 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3549 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3550 ok( ret == 0, "got ret %d\n", ret );
3552 expected[0] = 0x00000000, expected[1] = 0x00000000;
3553 expected[2] = 0x00000000, expected[3] = 0x00000000;
3554 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3555 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
3556 ok( ret == 0, "got ret %d\n", ret );
3558 expected[0] = 0x00000000, expected[1] = 0x00000000;
3559 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
3560 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3561 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3562 ok( ret == 2, "got ret %d\n", ret );
3564 expected[0] = 0x00000000, expected[1] = 0x00000000;
3565 expected[2] = 0x00000000, expected[3] = 0x00000000;
3566 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3567 2, 2, 4, 4, 0, 0, 2, 2, expected, __LINE__);
3568 ok( ret == 2, "got ret %d\n", ret );
3570 expected[0] = 0x00000000, expected[1] = 0x00000000;
3571 expected[2] = 0x00000000, expected[3] = 0x00000000;
3572 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3573 -4, -4, 4, 4, 0, 0, 4, 4, expected, __LINE__);
3574 ok( ret == 2, "got ret %d\n", ret );
3576 SelectObject(hdcDst, oldDst);
3577 DeleteObject(bmpDst);
3579 /* Bottom up destination tests */
3580 biDst.bmiHeader.biHeight = 2;
3581 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3582 NULL, 0);
3583 oldDst = SelectObject(hdcDst, bmpDst);
3585 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3586 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
3587 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3588 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3590 /* Tidy up */
3591 SelectObject(hdcDst, oldDst);
3592 DeleteObject(bmpDst);
3593 DeleteDC(hdcDst);
3595 DeleteDC(hdcScreen);
3598 static void test_GdiAlphaBlend(void)
3600 HDC hdcNull;
3601 HDC hdcDst;
3602 HBITMAP bmpDst;
3603 BITMAPINFO *bmi;
3604 HDC hdcSrc;
3605 HBITMAP bmpSrc;
3606 HBITMAP oldSrc;
3607 LPVOID bits;
3608 BOOL ret;
3609 BLENDFUNCTION blend;
3611 if (!pGdiAlphaBlend)
3613 win_skip("GdiAlphaBlend() is not implemented\n");
3614 return;
3617 hdcNull = GetDC(NULL);
3618 hdcDst = CreateCompatibleDC(hdcNull);
3619 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
3620 hdcSrc = CreateCompatibleDC(hdcNull);
3622 bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3623 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3624 bmi->bmiHeader.biHeight = 20;
3625 bmi->bmiHeader.biWidth = 20;
3626 bmi->bmiHeader.biBitCount = 32;
3627 bmi->bmiHeader.biPlanes = 1;
3628 bmi->bmiHeader.biCompression = BI_RGB;
3629 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3630 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3632 SelectObject(hdcDst, bmpDst);
3633 oldSrc = SelectObject(hdcSrc, bmpSrc);
3635 blend.BlendOp = AC_SRC_OVER;
3636 blend.BlendFlags = 0;
3637 blend.SourceConstantAlpha = 128;
3638 blend.AlphaFormat = 0;
3640 SetLastError(0xdeadbeef);
3641 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3642 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3644 SetLastError(0xdeadbeef);
3645 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3646 ok( !ret, "GdiAlphaBlend succeeded\n" );
3647 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3649 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3650 ok( !ret, "GdiAlphaBlend succeeded\n" );
3651 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend);
3652 ok( !ret, "GdiAlphaBlend succeeded\n" );
3653 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3654 ok( !ret, "GdiAlphaBlend succeeded\n" );
3655 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3656 ok( !ret, "GdiAlphaBlend succeeded\n" );
3658 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
3659 SetLastError(0xdeadbeef);
3660 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3661 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3662 SetLastError(0xdeadbeef);
3663 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3664 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3665 SetMapMode(hdcSrc, MM_ANISOTROPIC);
3666 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
3667 SetLastError(0xdeadbeef);
3668 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend);
3669 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3670 SetLastError(0xdeadbeef);
3671 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend);
3672 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3674 SetMapMode(hdcDst, MM_ANISOTROPIC);
3675 SetViewportExtEx(hdcDst, -1, -1, NULL);
3676 SetLastError(0xdeadbeef);
3677 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 50, 50, blend);
3678 todo_wine
3679 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3680 SetLastError(0xdeadbeef);
3681 ret = pGdiAlphaBlend(hdcDst, -20, -20, 20, 20, hdcSrc, 0, -1, 50, 50, blend);
3682 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3683 SetLastError(0xdeadbeef);
3684 ret = pGdiAlphaBlend(hdcDst, -20, -20, -20, -20, hdcSrc, 0, -1, 50, 50, blend);
3685 ok( !ret, "GdiAlphaBlend succeeded\n" );
3686 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3687 SetLastError(0xdeadbeef);
3688 ret = pGdiAlphaBlend(hdcDst, -20, 0, -20, 20, hdcSrc, 0, -1, 50, 50, blend);
3689 ok( !ret, "GdiAlphaBlend succeeded\n" );
3690 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3691 SetLastError(0xdeadbeef);
3692 ret = pGdiAlphaBlend(hdcDst, 0, -20, 20, -20, hdcSrc, 0, -1, 50, 50, blend);
3693 ok( !ret, "GdiAlphaBlend succeeded\n" );
3694 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3695 SetMapMode(hdcDst, MM_TEXT);
3697 SetViewportExtEx(hdcSrc, -1, -1, NULL);
3698 SetLastError(0xdeadbeef);
3699 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, -30, -30, blend);
3700 ok( !ret, "GdiAlphaBlend succeeded\n" );
3701 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3702 SetLastError(0xdeadbeef);
3703 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, 30, -30, blend);
3704 ok( !ret, "GdiAlphaBlend succeeded\n" );
3705 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3706 SetLastError(0xdeadbeef);
3707 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, -30, 30, blend);
3708 ok( !ret, "GdiAlphaBlend succeeded\n" );
3709 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3710 SetLastError(0xdeadbeef);
3711 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, 30, 30, blend);
3712 ok( !ret, "GdiAlphaBlend succeeded\n" );
3713 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3714 SetLastError(0xdeadbeef);
3715 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 20, 20, 30, 30, blend);
3716 ok( !ret, "GdiAlphaBlend succeeded\n" );
3717 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3718 SetLastError(0xdeadbeef);
3719 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -60, -60, 30, 30, blend);
3720 ok( !ret, "GdiAlphaBlend succeeded\n" );
3721 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3722 SetViewportExtEx(hdcSrc, 1, 1, NULL);
3724 SetLastError(0xdeadbeef);
3725 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend);
3726 ok( !ret, "GdiAlphaBlend succeeded\n" );
3727 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3729 /* overlapping source and dest not allowed */
3731 SetLastError(0xdeadbeef);
3732 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 19, 19, 20, 20, blend);
3733 ok( !ret, "GdiAlphaBlend succeeded\n" );
3734 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3736 SetLastError(0xdeadbeef);
3737 ret = pGdiAlphaBlend(hdcDst, 20, 20, 20, 20, hdcDst, 1, 1, 20, 20, blend);
3738 ok( !ret, "GdiAlphaBlend succeeded\n" );
3739 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3741 SetLastError(0xdeadbeef);
3742 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 20, 10, 20, 20, blend);
3743 ok( ret, "GdiAlphaBlend succeeded\n" );
3744 SetLastError(0xdeadbeef);
3745 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 10, 20, 20, 20, blend);
3746 ok( ret, "GdiAlphaBlend succeeded\n" );
3748 /* AC_SRC_ALPHA requires 32-bpp BI_RGB format */
3750 blend.AlphaFormat = AC_SRC_ALPHA;
3751 SetLastError(0xdeadbeef);
3752 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3753 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3755 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3756 ((DWORD *)bmi->bmiColors)[0] = 0xff0000;
3757 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3758 ((DWORD *)bmi->bmiColors)[2] = 0x0000ff;
3759 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3760 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3761 oldSrc = SelectObject(hdcSrc, bmpSrc);
3762 DeleteObject( oldSrc );
3764 SetLastError(0xdeadbeef);
3765 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3766 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3768 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3769 ((DWORD *)bmi->bmiColors)[0] = 0x0000ff;
3770 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3771 ((DWORD *)bmi->bmiColors)[2] = 0xff0000;
3772 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3773 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3774 oldSrc = SelectObject(hdcSrc, bmpSrc);
3775 DeleteObject( oldSrc );
3777 SetLastError(0xdeadbeef);
3778 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3779 ok( !ret, "GdiAlphaBlend succeeded\n" );
3780 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3782 bmi->bmiHeader.biBitCount = 24;
3783 bmi->bmiHeader.biCompression = BI_RGB;
3784 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3785 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3786 oldSrc = SelectObject(hdcSrc, bmpSrc);
3787 DeleteObject( oldSrc );
3789 SetLastError(0xdeadbeef);
3790 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3791 ok( !ret, "GdiAlphaBlend succeeded\n" );
3792 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3794 bmi->bmiHeader.biBitCount = 1;
3795 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3796 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3797 oldSrc = SelectObject(hdcSrc, bmpSrc);
3798 DeleteObject( oldSrc );
3800 SetLastError(0xdeadbeef);
3801 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3802 ok( !ret, "GdiAlphaBlend succeeded\n" );
3803 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3805 bmpSrc = CreateBitmap( 100, 100, 1, 1, NULL );
3806 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3807 oldSrc = SelectObject(hdcSrc, bmpSrc);
3808 DeleteObject( oldSrc );
3810 SetLastError(0xdeadbeef);
3811 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3812 ok( !ret, "GdiAlphaBlend succeeded\n" );
3813 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3815 DeleteDC(hdcDst);
3816 DeleteDC(hdcSrc);
3817 DeleteObject(bmpSrc);
3818 DeleteObject(bmpDst);
3820 ReleaseDC(NULL, hdcNull);
3821 HeapFree(GetProcessHeap(), 0, bmi);
3824 static void test_GdiGradientFill(void)
3826 HDC hdc;
3827 BOOL ret;
3828 HBITMAP bmp;
3829 BITMAPINFO *bmi;
3830 void *bits;
3831 GRADIENT_RECT rect[] = { { 0, 0 }, { 0, 1 }, { 2, 3 } };
3832 GRADIENT_TRIANGLE tri[] = { { 0, 0, 0 }, { 0, 1, 2 }, { 0, 2, 1 }, { 0, 1, 3 } };
3833 TRIVERTEX vt[3] = { { 2, 2, 0xff00, 0x0000, 0x0000, 0x8000 },
3834 { 10, 10, 0x0000, 0xff00, 0x0000, 0x8000 },
3835 { 20, 10, 0x0000, 0x0000, 0xff00, 0xff00 } };
3837 if (!pGdiGradientFill)
3839 win_skip( "GdiGradientFill is not implemented\n" );
3840 return;
3843 hdc = CreateCompatibleDC( NULL );
3844 bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3845 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3846 bmi->bmiHeader.biHeight = 20;
3847 bmi->bmiHeader.biWidth = 20;
3848 bmi->bmiHeader.biBitCount = 32;
3849 bmi->bmiHeader.biPlanes = 1;
3850 bmi->bmiHeader.biCompression = BI_RGB;
3851 bmp = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3852 ok( bmp != NULL, "couldn't create bitmap\n" );
3853 SelectObject( hdc, bmp );
3855 SetLastError( 0xdeadbeef );
3856 ret = pGdiGradientFill( hdc, vt, 3, rect, 1, GRADIENT_FILL_RECT_H );
3857 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3858 SetLastError( 0xdeadbeef );
3859 ret = pGdiGradientFill( hdc, vt, 3, rect, 1, 3 );
3860 ok( !ret, "GdiGradientFill succeeded\n" );
3861 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3862 SetLastError( 0xdeadbeef );
3863 ret = pGdiGradientFill( (HDC)0xdead, vt, 3, rect, 1, GRADIENT_FILL_RECT_H );
3864 ok( !ret, "GdiGradientFill succeeded\n" );
3865 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3866 SetLastError( 0xdeadbeef );
3867 ret = pGdiGradientFill( NULL, NULL, 0, rect, 1, GRADIENT_FILL_RECT_H );
3868 ok( !ret, "GdiGradientFill succeeded\n" );
3869 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3870 ret = pGdiGradientFill( hdc, NULL, 0, rect, 1, GRADIENT_FILL_RECT_H );
3871 ok( !ret, "GdiGradientFill succeeded\n" );
3872 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3873 SetLastError( 0xdeadbeef );
3874 ret = pGdiGradientFill( hdc, NULL, 3, rect, 1, GRADIENT_FILL_RECT_H );
3875 ok( !ret, "GdiGradientFill succeeded\n" );
3876 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3877 SetLastError( 0xdeadbeef );
3878 ret = pGdiGradientFill( hdc, vt, 3, NULL, 0, GRADIENT_FILL_RECT_H );
3879 ok( !ret, "GdiGradientFill succeeded\n" );
3880 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3881 SetLastError( 0xdeadbeef );
3882 ret = pGdiGradientFill( hdc, vt, 3, NULL, 1, GRADIENT_FILL_RECT_H );
3883 ok( !ret, "GdiGradientFill succeeded\n" );
3884 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3885 SetLastError( 0xdeadbeef );
3886 ret = pGdiGradientFill( hdc, vt, 3, rect, 0, GRADIENT_FILL_RECT_H );
3887 ok( !ret, "GdiGradientFill succeeded\n" );
3888 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3889 SetLastError( 0xdeadbeef );
3890 ret = pGdiGradientFill( hdc, vt, 3, rect, 3, GRADIENT_FILL_RECT_H );
3891 ok( !ret, "GdiGradientFill succeeded\n" );
3892 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3893 rect[2].UpperLeft = rect[2].LowerRight = 1;
3894 SetLastError( 0xdeadbeef );
3895 ret = pGdiGradientFill( hdc, vt, 3, rect, 3, GRADIENT_FILL_RECT_H );
3896 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3897 SetLastError( 0xdeadbeef );
3898 ret = pGdiGradientFill( hdc, vt, 1, rect, 1, GRADIENT_FILL_RECT_H );
3899 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3900 SetLastError( 0xdeadbeef );
3901 ret = pGdiGradientFill( hdc, vt, 1, tri, 0, GRADIENT_FILL_TRIANGLE );
3902 ok( !ret, "GdiGradientFill succeeded\n" );
3903 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3904 SetLastError( 0xdeadbeef );
3905 ret = pGdiGradientFill( hdc, vt, 1, tri, 1, GRADIENT_FILL_TRIANGLE );
3906 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3907 SetLastError( 0xdeadbeef );
3908 ret = pGdiGradientFill( hdc, vt, 3, tri, 2, GRADIENT_FILL_TRIANGLE );
3909 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3910 SetLastError( 0xdeadbeef );
3911 ret = pGdiGradientFill( hdc, vt, 3, tri, 3, GRADIENT_FILL_TRIANGLE );
3912 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3913 SetLastError( 0xdeadbeef );
3914 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3915 ok( !ret, "GdiGradientFill succeeded\n" );
3916 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3917 tri[3].Vertex3 = 1;
3918 SetLastError( 0xdeadbeef );
3919 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3920 ok( !ret, "GdiGradientFill succeeded\n" );
3921 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3922 tri[3].Vertex3 = 0;
3923 SetLastError( 0xdeadbeef );
3924 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3925 ok( !ret, "GdiGradientFill succeeded\n" );
3926 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3927 tri[3].Vertex1 = tri[3].Vertex2 = tri[3].Vertex3 = 1;
3928 SetLastError( 0xdeadbeef );
3929 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3930 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3932 DeleteDC( hdc );
3933 DeleteObject( bmp );
3934 HeapFree(GetProcessHeap(), 0, bmi);
3937 static void test_clipping(void)
3939 HBITMAP bmpDst;
3940 HBITMAP bmpSrc;
3941 HRGN hRgn;
3942 LPVOID bits;
3943 BOOL result;
3945 HDC hdcDst = CreateCompatibleDC( NULL );
3946 HDC hdcSrc = CreateCompatibleDC( NULL );
3948 BITMAPINFO bmpinfo={{0}};
3949 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3950 bmpinfo.bmiHeader.biWidth = 100;
3951 bmpinfo.bmiHeader.biHeight = 100;
3952 bmpinfo.bmiHeader.biPlanes = 1;
3953 bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3954 bmpinfo.bmiHeader.biCompression = BI_RGB;
3956 bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3957 ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3958 SelectObject( hdcDst, bmpDst );
3960 bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3961 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3962 SelectObject( hdcSrc, bmpSrc );
3964 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3965 ok(result, "BitBlt failed\n");
3967 hRgn = CreateRectRgn( 0,0,0,0 );
3968 SelectClipRgn( hdcDst, hRgn );
3970 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3971 ok(result, "BitBlt failed\n");
3973 DeleteObject( bmpDst );
3974 DeleteObject( bmpSrc );
3975 DeleteObject( hRgn );
3976 DeleteDC( hdcDst );
3977 DeleteDC( hdcSrc );
3980 static void test_32bit_ddb(void)
3982 char buffer[sizeof(BITMAPINFOHEADER) + sizeof(DWORD)];
3983 BITMAPINFO *biDst = (BITMAPINFO *)buffer;
3984 HBITMAP bmpSrc, bmpDst;
3985 HBITMAP oldSrc, oldDst;
3986 HDC hdcSrc, hdcDst, hdcScreen;
3987 HBRUSH brush;
3988 DWORD *dstBuffer, *data;
3989 DWORD colorSrc = 0x40201008;
3991 memset(biDst, 0, sizeof(BITMAPINFOHEADER));
3992 biDst->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3993 biDst->bmiHeader.biWidth = 1;
3994 biDst->bmiHeader.biHeight = -1;
3995 biDst->bmiHeader.biPlanes = 1;
3996 biDst->bmiHeader.biBitCount = 32;
3997 biDst->bmiHeader.biCompression = BI_RGB;
3999 hdcScreen = CreateCompatibleDC(0);
4000 if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
4002 DeleteDC(hdcScreen);
4003 trace("Skipping 32-bit DDB test\n");
4004 return;
4007 hdcSrc = CreateCompatibleDC(hdcScreen);
4008 bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
4009 oldSrc = SelectObject(hdcSrc, bmpSrc);
4011 hdcDst = CreateCompatibleDC(hdcScreen);
4012 bmpDst = CreateDIBSection(hdcDst, biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
4013 oldDst = SelectObject(hdcDst, bmpDst);
4015 StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
4016 ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
4018 if (pGdiAlphaBlend)
4020 BLENDFUNCTION blend;
4021 BOOL ret;
4023 blend.BlendOp = AC_SRC_OVER;
4024 blend.BlendFlags = 0;
4025 blend.SourceConstantAlpha = 128;
4026 blend.AlphaFormat = 0;
4027 dstBuffer[0] = 0x80808080;
4028 ret = pGdiAlphaBlend( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, blend );
4029 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
4030 ok(dstBuffer[0] == 0x60504844, "wrong color %x\n", dstBuffer[0]);
4031 blend.AlphaFormat = AC_SRC_ALPHA;
4032 dstBuffer[0] = 0x80808080;
4033 ret = pGdiAlphaBlend( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, blend );
4034 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
4035 ok(dstBuffer[0] == 0x90807874, "wrong color %x\n", dstBuffer[0]);
4038 data = (DWORD *)biDst->bmiColors;
4039 data[0] = 0x20304050;
4040 brush = CreateDIBPatternBrushPt( biDst, DIB_RGB_COLORS );
4041 ok( brush != 0, "brush creation failed\n" );
4042 SelectObject( hdcSrc, brush );
4043 PatBlt( hdcSrc, 0, 0, 1, 1, PATCOPY );
4044 BitBlt( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, SRCCOPY );
4045 ok(dstBuffer[0] == data[0], "Expected color=%x, received color=%x\n", data[0], dstBuffer[0]);
4046 SelectObject( hdcSrc, GetStockObject(BLACK_BRUSH) );
4047 DeleteObject( brush );
4049 biDst->bmiHeader.biBitCount = 24;
4050 brush = CreateDIBPatternBrushPt( biDst, DIB_RGB_COLORS );
4051 ok( brush != 0, "brush creation failed\n" );
4052 SelectObject( hdcSrc, brush );
4053 PatBlt( hdcSrc, 0, 0, 1, 1, PATCOPY );
4054 BitBlt( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, SRCCOPY );
4055 ok(dstBuffer[0] == (data[0] & ~0xff000000),
4056 "Expected color=%x, received color=%x\n", data[0] & 0xff000000, dstBuffer[0]);
4057 SelectObject( hdcSrc, GetStockObject(BLACK_BRUSH) );
4058 DeleteObject( brush );
4060 /* Tidy up */
4061 SelectObject(hdcDst, oldDst);
4062 DeleteObject(bmpDst);
4063 DeleteDC(hdcDst);
4065 SelectObject(hdcSrc, oldSrc);
4066 DeleteObject(bmpSrc);
4067 DeleteDC(hdcSrc);
4069 DeleteDC(hdcScreen);
4073 * Used by test_GetDIBits_top_down to create the bitmap to test against.
4075 static void setup_picture(char *picture, int bpp)
4077 int i;
4079 switch(bpp)
4081 case 16:
4082 case 32:
4083 /*Set the first byte in each pixel to the index of that pixel.*/
4084 for (i = 0; i < 4; i++)
4085 picture[i * (bpp / 8)] = i;
4086 break;
4087 case 24:
4088 picture[0] = 0;
4089 picture[3] = 1;
4090 /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
4091 picture[8] = 2;
4092 picture[11] = 3;
4093 break;
4097 static void test_GetDIBits_top_down(int bpp)
4099 BITMAPINFO bi;
4100 HBITMAP bmptb, bmpbt;
4101 HDC hdc;
4102 int pictureOut[4];
4103 int *picture;
4104 int statusCode;
4106 memset( &bi, 0, sizeof(bi) );
4107 bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
4108 bi.bmiHeader.biWidth=2;
4109 bi.bmiHeader.biHeight=2;
4110 bi.bmiHeader.biPlanes=1;
4111 bi.bmiHeader.biBitCount=bpp;
4112 bi.bmiHeader.biCompression=BI_RGB;
4114 /*Get the device context for the screen.*/
4115 hdc = GetDC(NULL);
4116 ok(hdc != NULL, "Could not get a handle to a device context.\n");
4118 /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
4119 bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
4120 ok(bmpbt != NULL, "Could not create a DIB section.\n");
4121 /*Now that we have a pointer to the pixels, we write to them.*/
4122 setup_picture((char*)picture, bpp);
4123 /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
4124 bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
4125 bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
4126 ok(bmptb != NULL, "Could not create a DIB section.\n");
4127 /*Write to this top to bottom bitmap.*/
4128 setup_picture((char*)picture, bpp);
4130 bi.bmiHeader.biWidth = 1;
4132 bi.bmiHeader.biHeight = 2;
4133 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
4134 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4135 /*Check the first byte of the pixel.*/
4136 ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
4137 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
4138 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4139 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
4140 /*Check second scanline.*/
4141 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
4142 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4143 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
4144 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
4145 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4146 ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
4147 /*Check both scanlines.*/
4148 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
4149 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4150 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
4151 ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
4152 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
4153 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4154 ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
4155 ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
4157 /*Make destination bitmap top-down.*/
4158 bi.bmiHeader.biHeight = -2;
4159 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
4160 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4161 ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
4162 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
4163 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4164 ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
4165 /*Check second scanline.*/
4166 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
4167 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4168 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
4169 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
4170 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4171 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
4172 /*Check both scanlines.*/
4173 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
4174 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4175 ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
4176 ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
4177 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
4178 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4179 ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
4180 ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
4182 DeleteObject(bmpbt);
4183 DeleteObject(bmptb);
4186 static void test_GetSetDIBits_rtl(void)
4188 HDC hdc, hdc_mem;
4189 HBITMAP bitmap, orig_bitmap;
4190 BITMAPINFO info;
4191 int ret;
4192 DWORD bits_1[8 * 8], bits_2[8 * 8];
4194 if(!pSetLayout)
4196 win_skip("Don't have SetLayout\n");
4197 return;
4200 hdc = GetDC( NULL );
4201 hdc_mem = CreateCompatibleDC( hdc );
4202 pSetLayout( hdc_mem, LAYOUT_LTR );
4204 bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
4205 orig_bitmap = SelectObject( hdc_mem, bitmap );
4206 SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
4207 SelectObject( hdc_mem, orig_bitmap );
4209 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
4210 info.bmiHeader.biWidth = 8;
4211 info.bmiHeader.biHeight = 8;
4212 info.bmiHeader.biPlanes = 1;
4213 info.bmiHeader.biBitCount = 32;
4214 info.bmiHeader.biCompression = BI_RGB;
4216 /* First show that GetDIBits ignores the layout mode. */
4218 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
4219 ok(ret == 8, "got %d\n", ret);
4220 ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
4222 pSetLayout( hdc_mem, LAYOUT_RTL );
4224 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
4225 ok(ret == 8, "got %d\n", ret);
4227 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
4229 /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
4230 followed by a GetDIBits and show that the bits remain unchanged. */
4232 pSetLayout( hdc_mem, LAYOUT_LTR );
4234 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
4235 ok(ret == 8, "got %d\n", ret);
4236 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
4237 ok(ret == 8, "got %d\n", ret);
4238 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
4240 pSetLayout( hdc_mem, LAYOUT_RTL );
4242 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
4243 ok(ret == 8, "got %d\n", ret);
4244 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
4245 ok(ret == 8, "got %d\n", ret);
4246 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
4248 DeleteObject( bitmap );
4249 DeleteDC( hdc_mem );
4250 ReleaseDC( NULL, hdc );
4253 static void test_GetDIBits_scanlines(void)
4255 BITMAPINFO *info;
4256 DWORD *dib_bits;
4257 HDC hdc = GetDC( NULL );
4258 HBITMAP dib;
4259 DWORD data[128], inverted_bits[64];
4260 int i, ret;
4262 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4264 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4265 info->bmiHeader.biWidth = 8;
4266 info->bmiHeader.biHeight = 8;
4267 info->bmiHeader.biPlanes = 1;
4268 info->bmiHeader.biBitCount = 32;
4269 info->bmiHeader.biCompression = BI_RGB;
4271 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4273 for (i = 0; i < 64; i++)
4275 dib_bits[i] = i;
4276 inverted_bits[56 - (i & ~7) + (i & 7)] = i;
4279 /* b-u -> b-u */
4281 memset( data, 0xaa, sizeof(data) );
4283 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4284 ok( ret == 8, "got %d\n", ret );
4285 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4286 memset( data, 0xaa, sizeof(data) );
4288 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4289 ok( ret == 5, "got %d\n", ret );
4290 ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
4291 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4292 memset( data, 0xaa, sizeof(data) );
4294 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4295 ok( ret == 7, "got %d\n", ret );
4296 ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
4297 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4298 memset( data, 0xaa, sizeof(data) );
4300 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4301 ok( ret == 1, "got %d\n", ret );
4302 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4303 memset( data, 0xaa, sizeof(data) );
4305 info->bmiHeader.biHeight = 16;
4306 info->bmiHeader.biSizeImage = 0;
4307 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4308 ok( ret == 5, "got %d\n", ret );
4309 ok( info->bmiHeader.biSizeImage == 128 * 4, "got %d\n", info->bmiHeader.biSizeImage );
4310 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4311 ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
4312 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4313 memset( data, 0xaa, sizeof(data) );
4315 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
4316 ok( ret == 6, "got %d\n", ret );
4317 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4318 ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
4319 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4320 memset( data, 0xaa, sizeof(data) );
4322 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
4323 ok( ret == 0, "got %d\n", ret );
4324 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4325 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4326 memset( data, 0xaa, sizeof(data) );
4328 info->bmiHeader.biHeight = 5;
4329 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4330 ok( ret == 2, "got %d\n", ret );
4331 ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
4332 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4333 memset( data, 0xaa, sizeof(data) );
4335 /* b-u -> t-d */
4337 info->bmiHeader.biHeight = -8;
4338 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4339 ok( ret == 8, "got %d\n", ret );
4340 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4341 memset( data, 0xaa, sizeof(data) );
4343 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4344 ok( ret == 5, "got %d\n", ret );
4345 ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
4346 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4347 memset( data, 0xaa, sizeof(data) );
4349 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4350 ok( ret == 7, "got %d\n", ret );
4351 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
4352 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4353 memset( data, 0xaa, sizeof(data) );
4355 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4356 ok( ret == 4, "got %d\n", ret );
4357 ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
4358 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4359 memset( data, 0xaa, sizeof(data) );
4361 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
4362 ok( ret == 5, "got %d\n", ret );
4363 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
4364 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4365 memset( data, 0xaa, sizeof(data) );
4367 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
4368 ok( ret == 5, "got %d\n", ret );
4369 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
4370 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4371 memset( data, 0xaa, sizeof(data) );
4373 info->bmiHeader.biHeight = -16;
4374 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
4375 ok( ret == 8, "got %d\n", ret );
4376 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4377 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4378 memset( data, 0xaa, sizeof(data) );
4380 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4381 ok( ret == 5, "got %d\n", ret );
4382 ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
4383 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4384 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4385 memset( data, 0xaa, sizeof(data) );
4387 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4388 ok( ret == 8, "got %d\n", ret );
4389 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4390 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4391 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4392 memset( data, 0xaa, sizeof(data) );
4394 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4395 ok( ret == 8, "got %d\n", ret );
4396 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4397 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4398 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4399 memset( data, 0xaa, sizeof(data) );
4401 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4402 ok( ret == 7, "got %d\n", ret );
4403 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
4404 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4405 memset( data, 0xaa, sizeof(data) );
4407 ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
4408 ok( ret == 1, "got %d\n", ret );
4409 for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4410 memset( data, 0xaa, sizeof(data) );
4412 info->bmiHeader.biHeight = -5;
4413 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4414 ok( ret == 2, "got %d\n", ret );
4415 ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
4416 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4417 memset( data, 0xaa, sizeof(data) );
4419 DeleteObject( dib );
4421 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4422 info->bmiHeader.biWidth = 8;
4423 info->bmiHeader.biHeight = -8;
4424 info->bmiHeader.biPlanes = 1;
4425 info->bmiHeader.biBitCount = 32;
4426 info->bmiHeader.biCompression = BI_RGB;
4428 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4430 for (i = 0; i < 64; i++) dib_bits[i] = i;
4432 /* t-d -> t-d */
4434 info->bmiHeader.biHeight = -8;
4435 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4436 ok( ret == 8, "got %d\n", ret );
4437 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4438 memset( data, 0xaa, sizeof(data) );
4440 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4441 ok( ret == 5, "got %d\n", ret );
4442 ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
4443 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4444 memset( data, 0xaa, sizeof(data) );
4446 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4447 ok( ret == 7, "got %d\n", ret );
4448 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
4449 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4450 memset( data, 0xaa, sizeof(data) );
4452 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4453 ok( ret == 4, "got %d\n", ret );
4454 ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
4455 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4456 memset( data, 0xaa, sizeof(data) );
4458 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
4459 ok( ret == 5, "got %d\n", ret );
4460 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
4461 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4462 memset( data, 0xaa, sizeof(data) );
4464 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
4465 ok( ret == 5, "got %d\n", ret );
4466 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
4467 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4468 memset( data, 0xaa, sizeof(data) );
4470 info->bmiHeader.biHeight = -16;
4471 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
4472 ok( ret == 8, "got %d\n", ret );
4473 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4474 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4475 memset( data, 0xaa, sizeof(data) );
4477 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4478 ok( ret == 5, "got %d\n", ret );
4479 ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
4480 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4481 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4482 memset( data, 0xaa, sizeof(data) );
4484 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4485 ok( ret == 8, "got %d\n", ret );
4486 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4487 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4488 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4489 memset( data, 0xaa, sizeof(data) );
4491 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4492 ok( ret == 8, "got %d\n", ret );
4493 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4494 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4495 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4496 memset( data, 0xaa, sizeof(data) );
4498 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4499 ok( ret == 7, "got %d\n", ret );
4500 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
4501 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4502 memset( data, 0xaa, sizeof(data) );
4504 info->bmiHeader.biHeight = -5;
4505 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4506 ok( ret == 2, "got %d\n", ret );
4507 ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
4508 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4509 memset( data, 0xaa, sizeof(data) );
4512 /* t-d -> b-u */
4514 info->bmiHeader.biHeight = 8;
4516 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4517 ok( ret == 8, "got %d\n", ret );
4518 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4519 memset( data, 0xaa, sizeof(data) );
4521 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4522 ok( ret == 5, "got %d\n", ret );
4523 ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
4524 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4525 memset( data, 0xaa, sizeof(data) );
4527 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4528 ok( ret == 7, "got %d\n", ret );
4529 ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
4530 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4531 memset( data, 0xaa, sizeof(data) );
4533 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4534 ok( ret == 1, "got %d\n", ret );
4535 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4536 memset( data, 0xaa, sizeof(data) );
4538 info->bmiHeader.biHeight = 16;
4539 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4540 ok( ret == 5, "got %d\n", ret );
4541 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4542 ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
4543 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4544 memset( data, 0xaa, sizeof(data) );
4546 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
4547 ok( ret == 6, "got %d\n", ret );
4548 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4549 ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
4550 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4551 memset( data, 0xaa, sizeof(data) );
4553 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
4554 ok( ret == 0, "got %d\n", ret );
4555 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4556 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4557 memset( data, 0xaa, sizeof(data) );
4559 info->bmiHeader.biHeight = 5;
4560 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4561 ok( ret == 2, "got %d\n", ret );
4562 ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
4563 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4565 DeleteObject( dib );
4567 ReleaseDC( NULL, hdc );
4568 HeapFree( GetProcessHeap(), 0, info );
4572 static void test_SetDIBits(void)
4574 char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
4575 LOGPALETTE *pal = (LOGPALETTE *)palbuf;
4576 PALETTEENTRY *palent = pal->palPalEntry;
4577 HPALETTE palette;
4578 BITMAPINFO *info;
4579 DWORD *dib_bits;
4580 HDC hdc = GetDC( NULL );
4581 DWORD data[128], inverted_data[128];
4582 HBITMAP dib;
4583 int i, ret;
4585 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4587 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4588 info->bmiHeader.biWidth = 8;
4589 info->bmiHeader.biHeight = 8;
4590 info->bmiHeader.biPlanes = 1;
4591 info->bmiHeader.biBitCount = 32;
4592 info->bmiHeader.biCompression = BI_RGB;
4594 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4595 memset( dib_bits, 0xaa, 64 * 4 );
4597 for (i = 0; i < 128; i++)
4599 data[i] = i;
4600 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4603 /* b-u -> b-u */
4605 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4606 ok( ret == 8, "got %d\n", ret );
4607 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4608 memset( dib_bits, 0xaa, 64 * 4 );
4610 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4611 ok( ret == 5, "got %d\n", ret );
4612 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4613 ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
4614 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4615 memset( dib_bits, 0xaa, 64 * 4 );
4617 /* top of dst is aligned with startscans down for the top of the src.
4618 Then starting from the bottom of src, lines rows are copied across. */
4620 info->bmiHeader.biHeight = 16;
4621 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4622 ok( ret == 12, "got %d\n", ret );
4623 ok( !memcmp( dib_bits, data + 56, 40 * 4 ), "bits differ\n");
4624 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4625 memset( dib_bits, 0xaa, 64 * 4 );
4627 info->bmiHeader.biHeight = 5;
4628 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4629 ok( ret == 2, "got %d\n", ret );
4630 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4631 ok( !memcmp( dib_bits + 32, data, 16 * 4 ), "bits differ\n");
4632 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4633 memset( dib_bits, 0xaa, 64 * 4 );
4635 /* t-d -> b-u */
4636 info->bmiHeader.biHeight = -8;
4637 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4638 ok( ret == 8, "got %d\n", ret );
4639 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4640 memset( dib_bits, 0xaa, 64 * 4 );
4642 /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
4643 we copy lines rows from the top of the src */
4645 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4646 ok( ret == 5, "got %d\n", ret );
4647 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4648 ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
4649 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4650 memset( dib_bits, 0xaa, 64 * 4 );
4652 info->bmiHeader.biHeight = -16;
4653 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4654 ok( ret == 12, "got %d\n", ret );
4655 ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
4656 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4657 memset( dib_bits, 0xaa, 64 * 4 );
4659 ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4660 ok( ret == 12, "got %d\n", ret );
4661 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4662 memset( dib_bits, 0xaa, 64 * 4 );
4664 ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4665 ok( ret == 12, "got %d\n", ret );
4666 ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
4667 memset( dib_bits, 0xaa, 64 * 4 );
4669 info->bmiHeader.biHeight = -5;
4670 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4671 ok( ret == 2, "got %d\n", ret );
4672 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4673 ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
4674 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4675 memset( dib_bits, 0xaa, 64 * 4 );
4677 DeleteObject( dib );
4679 info->bmiHeader.biHeight = -8;
4681 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4682 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4684 /* t-d -> t-d */
4686 /* like the t-d -> b-u case. */
4688 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4689 ok( ret == 8, "got %d\n", ret );
4690 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4691 memset( dib_bits, 0xaa, 64 * 4 );
4693 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4694 ok( ret == 5, "got %d\n", ret );
4695 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4696 ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
4697 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4698 memset( dib_bits, 0xaa, 64 * 4 );
4700 info->bmiHeader.biHeight = -16;
4701 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4702 ok( ret == 12, "got %d\n", ret );
4703 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4704 ok( !memcmp( dib_bits + 24, data, 40 * 4 ), "bits differ\n");
4705 memset( dib_bits, 0xaa, 64 * 4 );
4707 info->bmiHeader.biHeight = -5;
4708 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4709 ok( ret == 2, "got %d\n", ret );
4710 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4711 ok( !memcmp( dib_bits + 16, data, 16 * 4 ), "bits differ\n");
4712 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4713 memset( dib_bits, 0xaa, 64 * 4 );
4715 /* b-u -> t-d */
4716 /* like the b-u -> b-u case */
4718 info->bmiHeader.biHeight = 8;
4719 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4720 ok( ret == 8, "got %d\n", ret );
4721 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4722 memset( dib_bits, 0xaa, 64 * 4 );
4724 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4725 ok( ret == 5, "got %d\n", ret );
4726 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4727 ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
4728 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4729 memset( dib_bits, 0xaa, 64 * 4 );
4731 info->bmiHeader.biHeight = 16;
4732 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4733 ok( ret == 12, "got %d\n", ret );
4734 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4735 ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
4736 memset( dib_bits, 0xaa, 64 * 4 );
4738 info->bmiHeader.biHeight = 5;
4739 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4740 ok( ret == 2, "got %d\n", ret );
4741 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4742 ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
4743 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4744 memset( dib_bits, 0xaa, 64 * 4 );
4746 /* handling of partial color table */
4748 info->bmiHeader.biHeight = -8;
4749 info->bmiHeader.biBitCount = 8;
4750 info->bmiHeader.biClrUsed = 137;
4751 for (i = 0; i < 256; i++)
4753 info->bmiColors[i].rgbRed = 255 - i;
4754 info->bmiColors[i].rgbGreen = i * 2;
4755 info->bmiColors[i].rgbBlue = i;
4756 info->bmiColors[i].rgbReserved = 0;
4758 for (i = 0; i < 64; i++) ((BYTE *)data)[i] = i * 4 + 1;
4759 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4760 ok( ret == 8, "got %d\n", ret );
4761 for (i = 0; i < 64; i++)
4763 int idx = i * 4 + 1;
4764 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : (info->bmiColors[idx].rgbRed << 16 |
4765 info->bmiColors[idx].rgbGreen << 8 |
4766 info->bmiColors[idx].rgbBlue);
4767 ok( dib_bits[i] == expect, "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
4769 memset( dib_bits, 0xaa, 64 * 4 );
4771 /* handling of DIB_PAL_COLORS */
4773 pal->palVersion = 0x300;
4774 pal->palNumEntries = 137;
4775 info->bmiHeader.biClrUsed = 221;
4776 for (i = 0; i < 256; i++)
4778 palent[i].peRed = i * 2;
4779 palent[i].peGreen = 255 - i;
4780 palent[i].peBlue = i;
4782 palette = CreatePalette( pal );
4783 ok( palette != 0, "palette creation failed\n" );
4784 SelectPalette( hdc, palette, FALSE );
4785 for (i = 0; i < 256; i++) ((WORD *)info->bmiColors)[i] = 255 - i;
4786 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_PAL_COLORS );
4787 ok( ret == 8, "got %d\n", ret );
4788 for (i = 0; i < 64; i++)
4790 int idx = i * 4 + 1;
4791 int ent = (255 - idx) % pal->palNumEntries;
4792 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 :
4793 (palent[ent].peRed << 16 | palent[ent].peGreen << 8 | palent[ent].peBlue);
4794 ok( dib_bits[i] == expect || broken(dib_bits[i] == 0), /* various Windows versions get some values wrong */
4795 "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
4797 memset( dib_bits, 0xaa, 64 * 4 );
4799 ReleaseDC( NULL, hdc );
4800 DeleteObject( dib );
4801 DeleteObject( palette );
4802 HeapFree( GetProcessHeap(), 0, info );
4805 static void test_SetDIBits_RLE4(void)
4807 BITMAPINFO *info;
4808 DWORD *dib_bits;
4809 HDC hdc = GetDC( NULL );
4810 BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00, /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
4811 0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
4812 0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00, /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
4813 0x00, 0x02, 0x01, 0x02, 0x05, 0x87, /* dx=1, dy=2, 8, 7, 8, 7, 8 */
4814 0x00, 0x01 }; /* <eod> */
4815 HBITMAP dib;
4816 int i, ret;
4817 DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
4818 0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
4819 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4820 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4821 0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
4822 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4823 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4824 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4826 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4828 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4829 info->bmiHeader.biWidth = 8;
4830 info->bmiHeader.biHeight = 8;
4831 info->bmiHeader.biPlanes = 1;
4832 info->bmiHeader.biBitCount = 32;
4833 info->bmiHeader.biCompression = BI_RGB;
4835 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4836 memset( dib_bits, 0xaa, 64 * 4 );
4838 info->bmiHeader.biBitCount = 4;
4839 info->bmiHeader.biCompression = BI_RLE4;
4840 info->bmiHeader.biSizeImage = sizeof(rle4_data);
4842 for (i = 0; i < 16; i++)
4844 info->bmiColors[i].rgbRed = i;
4845 info->bmiColors[i].rgbGreen = i;
4846 info->bmiColors[i].rgbBlue = i;
4847 info->bmiColors[i].rgbReserved = 0;
4850 ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
4851 ok( ret == 8, "got %d\n", ret );
4852 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
4853 memset( dib_bits, 0xaa, 64 * 4 );
4855 DeleteObject( dib );
4856 ReleaseDC( NULL, hdc );
4857 HeapFree( GetProcessHeap(), 0, info );
4860 static void test_SetDIBits_RLE8(void)
4862 BITMAPINFO *info;
4863 DWORD *dib_bits;
4864 HDC hdc = GetDC( NULL );
4865 BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00, /* 2, 2, 2, f0, f0, f0, f0, <eol> */
4866 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4867 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4868 0x00, 0x01 }; /* <eod> */
4869 HBITMAP dib;
4870 int i, ret;
4871 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4872 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4873 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4874 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4875 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4876 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4877 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4878 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4879 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4880 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4881 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4882 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4883 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4884 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4885 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4886 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4888 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4890 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4891 info->bmiHeader.biWidth = 8;
4892 info->bmiHeader.biHeight = 8;
4893 info->bmiHeader.biPlanes = 1;
4894 info->bmiHeader.biBitCount = 32;
4895 info->bmiHeader.biCompression = BI_RGB;
4897 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4898 memset( dib_bits, 0xaa, 64 * 4 );
4900 info->bmiHeader.biBitCount = 8;
4901 info->bmiHeader.biCompression = BI_RLE8;
4902 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4904 for (i = 0; i < 256; i++)
4906 info->bmiColors[i].rgbRed = i;
4907 info->bmiColors[i].rgbGreen = i;
4908 info->bmiColors[i].rgbBlue = i;
4909 info->bmiColors[i].rgbReserved = 0;
4912 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4913 ok( ret == 8, "got %d\n", ret );
4914 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4915 memset( dib_bits, 0xaa, 64 * 4 );
4917 /* startscan and lines are ignored, unless lines == 0 */
4918 ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4919 ok( ret == 8, "got %d\n", ret );
4920 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4921 memset( dib_bits, 0xaa, 64 * 4 );
4923 ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4924 ok( ret == 8, "got %d\n", ret );
4925 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4926 memset( dib_bits, 0xaa, 64 * 4 );
4928 ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4929 ok( ret == 0, "got %d\n", ret );
4930 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4931 memset( dib_bits, 0xaa, 64 * 4 );
4933 /* reduce width to 4, left-hand side of dst is touched. */
4934 info->bmiHeader.biWidth = 4;
4935 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4936 ok( ret == 8, "got %d\n", ret );
4937 for (i = 0; i < 64; i++)
4939 DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4940 ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4942 memset( dib_bits, 0xaa, 64 * 4 );
4944 /* Show that the top lines are aligned by adjusting the height of the src */
4946 /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4947 info->bmiHeader.biWidth = 8;
4948 info->bmiHeader.biHeight = 4;
4949 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4950 ok( ret == 4, "got %d\n", ret );
4951 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4952 ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4953 memset( dib_bits, 0xaa, 64 * 4 );
4955 /* increase the height to 9 -> everything moves down one row. */
4956 info->bmiHeader.biHeight = 9;
4957 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4958 ok( ret == 9, "got %d\n", ret );
4959 ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4960 for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4961 memset( dib_bits, 0xaa, 64 * 4 );
4963 /* top-down compressed dibs are invalid */
4964 info->bmiHeader.biHeight = -8;
4965 SetLastError( 0xdeadbeef );
4966 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4967 ok( ret == 0, "got %d\n", ret );
4968 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4969 DeleteObject( dib );
4971 /* top-down dst */
4973 info->bmiHeader.biHeight = -8;
4974 info->bmiHeader.biBitCount = 32;
4975 info->bmiHeader.biCompression = BI_RGB;
4976 info->bmiHeader.biSizeImage = 0;
4978 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4979 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4981 info->bmiHeader.biHeight = 8;
4982 info->bmiHeader.biBitCount = 8;
4983 info->bmiHeader.biCompression = BI_RLE8;
4984 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4986 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4987 ok( ret == 8, "got %d\n", ret );
4988 ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4989 memset( dib_bits, 0xaa, 64 * 4 );
4991 info->bmiHeader.biHeight = 4;
4992 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4993 ok( ret == 4, "got %d\n", ret );
4994 ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4995 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4996 memset( dib_bits, 0xaa, 64 * 4 );
4998 info->bmiHeader.biHeight = 9;
4999 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5000 ok( ret == 9, "got %d\n", ret );
5001 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5002 ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
5003 memset( dib_bits, 0xaa, 64 * 4 );
5005 DeleteObject( dib );
5006 ReleaseDC( NULL, hdc );
5007 HeapFree( GetProcessHeap(), 0, info );
5010 static void test_SetDIBitsToDevice(void)
5012 char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
5013 LOGPALETTE *pal = (LOGPALETTE *)palbuf;
5014 PALETTEENTRY *palent = pal->palPalEntry;
5015 HPALETTE palette;
5016 BITMAPINFO *info;
5017 DWORD *dib_bits;
5018 HDC hdc = CreateCompatibleDC( 0 );
5019 DWORD data[128], inverted_data[128];
5020 HBITMAP dib;
5021 int i, ret;
5023 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
5025 info->bmiHeader.biSize = sizeof(info->bmiHeader);
5026 info->bmiHeader.biWidth = 8;
5027 info->bmiHeader.biHeight = 8;
5028 info->bmiHeader.biPlanes = 1;
5029 info->bmiHeader.biBitCount = 32;
5030 info->bmiHeader.biCompression = BI_RGB;
5032 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5033 memset( dib_bits, 0xaa, 64 * 4 );
5034 SelectObject( hdc, dib );
5036 for (i = 0; i < 128; i++)
5038 data[i] = i;
5039 inverted_data[120 - (i & ~7) + (i & 7)] = i;
5042 /* b-u -> b-u */
5044 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5045 ok( ret == 8, "got %d\n", ret );
5046 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
5047 memset( dib_bits, 0xaa, 64 * 4 );
5049 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
5050 ok( ret == 5, "got %d\n", ret );
5051 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5052 for (i = 8; i < 48; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5053 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5054 memset( dib_bits, 0xaa, 64 * 4 );
5056 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 3, 1, 5, data, info, DIB_RGB_COLORS );
5057 ok( ret == 5, "got %d\n", ret );
5058 for (i = 0; i < 24; i++) ok( dib_bits[i] == data[i + 16], "%d: got %08x\n", i, dib_bits[i] );
5059 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5060 memset( dib_bits, 0xaa, 64 * 4 );
5062 info->bmiHeader.biHeight = 16;
5063 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
5064 ok( ret == 7, "got %d\n", ret );
5065 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5066 for (i = 8; i < 64; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5067 memset( dib_bits, 0xaa, 64 * 4 );
5069 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 8, 0, 6, 1, 12, data, info, DIB_RGB_COLORS );
5070 ok( ret == 12, "got %d\n", ret );
5071 for (i = 0; i < 40; i++) ok( dib_bits[i] == data[i + 56], "%d: got %08x\n", i, dib_bits[i] );
5072 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5073 memset( dib_bits, 0xaa, 64 * 4 );
5075 ret = SetDIBitsToDevice( hdc, 0, -4, 8, 8, 0, 3, 1, 12, data, info, DIB_RGB_COLORS );
5076 ok( ret == 10, "got %d\n", ret );
5077 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5078 for (i = 32; i < 64; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
5079 memset( dib_bits, 0xaa, 64 * 4 );
5081 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, -3, 1, 12, data, info, DIB_RGB_COLORS );
5082 ok( ret == 4, "got %d\n", ret );
5083 for (i = 0; i < 32; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
5084 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5085 memset( dib_bits, 0xaa, 64 * 4 );
5087 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 5, 0, -2, 1, 12, data, info, DIB_RGB_COLORS );
5088 ok( ret == 2, "got %d\n", ret );
5089 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5090 for (i = 32; i < 48; i++) ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
5091 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5092 memset( dib_bits, 0xaa, 64 * 4 );
5094 info->bmiHeader.biHeight = 5;
5095 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 2, 2, data, info, DIB_RGB_COLORS );
5096 ok( ret == 2, "got %d\n", ret );
5097 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5098 for (i = 16; i < 32; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
5099 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5100 memset( dib_bits, 0xaa, 64 * 4 );
5102 ret = SetDIBitsToDevice( hdc, 3, 3, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
5103 ok( ret == 3, "got %d\n", ret );
5104 for (i = 0; i < 64; i++)
5105 if (i == 27 || i == 28 || i == 35 || i == 36)
5106 ok( dib_bits[i] == data[i - 18], "%d: got %08x\n", i, dib_bits[i] );
5107 else
5108 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5109 memset( dib_bits, 0xaa, 64 * 4 );
5111 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5112 ok( ret == 5, "got %d\n", ret );
5113 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5114 memset( dib_bits, 0xaa, 64 * 4 );
5116 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
5117 ok( ret == 0, "got %d\n", ret );
5118 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5119 memset( dib_bits, 0xaa, 64 * 4 );
5121 SetMapMode( hdc, MM_ANISOTROPIC );
5122 SetWindowExtEx( hdc, 3, 3, NULL );
5123 ret = SetDIBitsToDevice( hdc, 2, 2, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
5124 ok( ret == 3, "got %d\n", ret );
5125 for (i = 0; i < 64; i++)
5126 if (i == 41 || i == 42 || i == 49 || i == 50)
5127 ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
5128 else
5129 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5130 memset( dib_bits, 0xaa, 64 * 4 );
5132 SetWindowExtEx( hdc, -1, -1, NULL );
5133 ret = SetDIBitsToDevice( hdc, 2, 2, 4, 4, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
5134 ok( ret == 4, "got %d\n", ret );
5135 for (i = 0; i < 64; i++)
5136 if (i == 48 || i == 49 || i == 56 || i == 57)
5137 ok( dib_bits[i] == data[i - 37], "%d: got %08x\n", i, dib_bits[i] );
5138 else
5139 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5140 memset( dib_bits, 0xaa, 64 * 4 );
5141 SetMapMode( hdc, MM_TEXT );
5143 if (pSetLayout)
5145 pSetLayout( hdc, LAYOUT_RTL );
5146 ret = SetDIBitsToDevice( hdc, 1, 2, 3, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
5147 ok( ret == 3, "got %d\n", ret );
5148 for (i = 0; i < 64; i++)
5149 if (i == 36 || i == 37 || i == 38 || i == 44 || i == 45 || i == 46)
5150 ok( dib_bits[i] == data[i - 27], "%d: got %08x\n", i, dib_bits[i] );
5151 else
5152 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5153 memset( dib_bits, 0xaa, 64 * 4 );
5154 pSetLayout( hdc, LAYOUT_LTR );
5157 /* t-d -> b-u */
5158 info->bmiHeader.biHeight = -8;
5159 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5160 ok( ret == 8, "got %d\n", ret );
5161 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
5162 memset( dib_bits, 0xaa, 64 * 4 );
5164 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
5165 ok( ret == 5, "got %d\n", ret );
5166 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5167 for (i = 8; i < 48; i++) ok( dib_bits[i] == inverted_data[i + 80], "%d: got %08x\n", i, dib_bits[i] );
5168 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5169 memset( dib_bits, 0xaa, 64 * 4 );
5171 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 4, 1, 5, data, info, DIB_RGB_COLORS );
5172 ok( ret == 5, "got %d\n", ret );
5173 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
5174 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5175 memset( dib_bits, 0xaa, 64 * 4 );
5177 info->bmiHeader.biHeight = -16;
5178 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
5179 ok( ret == 12, "got %d\n", ret );
5180 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5181 for (i = 8; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 24], "%d: got %08x\n", i, dib_bits[i] );
5182 memset( dib_bits, 0xaa, 64 * 4 );
5184 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, 7, 1, 12, data, info, DIB_RGB_COLORS );
5185 ok( ret == 12, "got %d\n", ret );
5186 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
5187 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5188 memset( dib_bits, 0xaa, 64 * 4 );
5190 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 4, 12, data, info, DIB_RGB_COLORS );
5191 ok( ret == 12, "got %d\n", ret );
5192 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5193 for (i = 32; i < 64; i++) ok( dib_bits[i] == inverted_data[i], "%d: got %08x\n", i, dib_bits[i] );
5194 memset( dib_bits, 0xaa, 64 * 4 );
5196 ret = SetDIBitsToDevice( hdc, 0, -3, 8, 8, 0, 2, 4, 12, data, info, DIB_RGB_COLORS );
5197 ok( ret == 12, "got %d\n", ret );
5198 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5199 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5200 memset( dib_bits, 0xaa, 64 * 4 );
5202 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, -2, 4, 12, data, info, DIB_RGB_COLORS );
5203 ok( ret == 12, "got %d\n", ret );
5204 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5205 for (i = 24; i < 40; i++) ok( dib_bits[i] == inverted_data[i + 8], "%d: got %08x\n", i, dib_bits[i] );
5206 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5207 memset( dib_bits, 0xaa, 64 * 4 );
5209 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 5, 12, data, info, DIB_RGB_COLORS );
5210 ok( ret == 12, "got %d\n", ret );
5211 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5212 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5213 memset( dib_bits, 0xaa, 64 * 4 );
5215 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
5216 ok( ret == 12, "got %d\n", ret );
5217 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5218 memset( dib_bits, 0xaa, 64 * 4 );
5220 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -2, -4, 0, 12, data, info, DIB_RGB_COLORS );
5221 ok( ret == 12, "got %d\n", ret );
5222 for (i = 0; i < 64; i++)
5223 if (i == 31 || i == 39 || i == 47 || i == 55 || i == 63)
5224 ok( dib_bits[i] == inverted_data[i + 1], "%d: got %08x\n", i, dib_bits[i] );
5225 else
5226 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5227 memset( dib_bits, 0xaa, 64 * 4 );
5229 info->bmiHeader.biHeight = -5;
5230 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
5231 ok( ret == 2, "got %d\n", ret );
5232 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5233 for (i = 8; i < 24; i++) ok( dib_bits[i] == inverted_data[i + 104], "%d: got %08x\n", i, dib_bits[i] );
5234 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5235 memset( dib_bits, 0xaa, 64 * 4 );
5237 ret = SetDIBitsToDevice( hdc, 5, 4, 2, 2, 6, 3, 1, 5, data, info, DIB_RGB_COLORS );
5238 ok( ret == 5, "got %d\n", ret );
5239 for (i = 0; i < 64; i++)
5240 if (i == 21 || i == 22 || i == 29 || i == 30)
5241 ok( dib_bits[i] == inverted_data[i + 89], "%d: got %08x\n", i, dib_bits[i] );
5242 else
5243 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5244 memset( dib_bits, 0xaa, 64 * 4 );
5246 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5247 ok( ret == 5, "got %d\n", ret );
5248 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5249 memset( dib_bits, 0xaa, 64 * 4 );
5251 info->bmiHeader.biHeight = -8;
5253 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5254 DeleteObject( SelectObject( hdc, dib ));
5255 memset( dib_bits, 0xaa, 16 * 16 * 4 );
5257 /* t-d -> t-d */
5259 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5260 ok( ret == 8, "got %d\n", ret );
5261 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
5262 memset( dib_bits, 0xaa, 64 * 4 );
5264 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
5265 ok( ret == 5, "got %d\n", ret );
5266 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5267 for (i = 16; i < 56; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
5268 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5269 memset( dib_bits, 0xaa, 64 * 4 );
5271 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 3, 0, 2, 1, 5, data, info, DIB_RGB_COLORS );
5272 ok( ret == 5, "got %d\n", ret );
5273 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5274 for (i = 24; i < 48; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
5275 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5276 memset( dib_bits, 0xaa, 64 * 4 );
5278 info->bmiHeader.biHeight = -16;
5279 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
5280 ok( ret == 12, "got %d\n", ret );
5281 for (i = 0; i < 56; i++) ok( dib_bits[i] == data[i + 40], "%d: got %08x\n", i, dib_bits[i] );
5282 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5283 memset( dib_bits, 0xaa, 64 * 4 );
5285 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -1, -8, 0, 12, data, info, DIB_RGB_COLORS );
5286 ok( ret == 12, "got %d\n", ret );
5287 for (i = 0; i < 64; i++)
5288 if (i == 6 || i == 7)
5289 ok( dib_bits[i] == data[i + 82], "%d: got %08x\n", i, dib_bits[i] );
5290 else
5291 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5292 memset( dib_bits, 0xaa, 64 * 4 );
5294 info->bmiHeader.biHeight = -5;
5295 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
5296 ok( ret == 2, "got %d\n", ret );
5297 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5298 for (i = 40; i < 56; i++) ok( dib_bits[i] == data[i - 40], "%d: got %08x\n", i, dib_bits[i] );
5299 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5300 memset( dib_bits, 0xaa, 64 * 4 );
5302 ret = SetDIBitsToDevice( hdc, 7, 2, 8, 8, 1, 0, 0, 5, data, info, DIB_RGB_COLORS );
5303 ok( ret == 5, "got %d\n", ret );
5304 for (i = 0; i < 64; i++)
5305 if (i == 47 || i == 55 || i == 63)
5306 ok( dib_bits[i] == data[i - 46], "%d: got %08x\n", i, dib_bits[i] );
5307 else
5308 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5309 memset( dib_bits, 0xaa, 64 * 4 );
5311 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5312 ok( ret == 5, "got %d\n", ret );
5313 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5314 memset( dib_bits, 0xaa, 64 * 4 );
5316 /* b-u -> t-d */
5318 info->bmiHeader.biHeight = 8;
5319 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5320 ok( ret == 8, "got %d\n", ret );
5321 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
5322 memset( dib_bits, 0xaa, 64 * 4 );
5324 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
5325 ok( ret == 5, "got %d\n", ret );
5326 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5327 for (i = 16; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
5328 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5329 memset( dib_bits, 0xaa, 64 * 4 );
5331 info->bmiHeader.biHeight = 16;
5332 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
5333 ok( ret == 7, "got %d\n", ret );
5334 for (i = 0; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
5335 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5336 memset( dib_bits, 0xaa, 64 * 4 );
5338 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, 0, -4, 1, 12, data, info, DIB_RGB_COLORS );
5339 ok( ret == 3, "got %d\n", ret );
5340 for (i = 0; i < 64; i++)
5341 if ((i >= 36 && i <= 39) || (i >= 44 && i <= 47) || (i >= 52 && i <= 55))
5342 ok( dib_bits[i] == inverted_data[i + 68], "%d: got %08x\n", i, dib_bits[i] );
5343 else
5344 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5345 memset( dib_bits, 0xaa, 64 * 4 );
5347 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, -30, -30, 1, 12, data, info, DIB_RGB_COLORS );
5348 ok( ret == 0, "got %d\n", ret );
5349 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5350 memset( dib_bits, 0xaa, 64 * 4 );
5352 ret = SetDIBitsToDevice( hdc, 5, -5, 8, 16, -2, -4, 4, 12, data, info, DIB_RGB_COLORS );
5353 ok( ret == 8, "got %d\n", ret );
5354 for (i = 0; i < 64; i++)
5355 if (i == 7 || i == 15 || i == 23)
5356 ok( dib_bits[i] == inverted_data[i + 97], "%d: got %08x\n", i, dib_bits[i] );
5357 else
5358 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5359 memset( dib_bits, 0xaa, 64 * 4 );
5361 info->bmiHeader.biHeight = 5;
5362 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
5363 ok( ret == 2, "got %d\n", ret );
5364 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5365 for (i = 40; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
5366 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5367 memset( dib_bits, 0xaa, 64 * 4 );
5369 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5370 ok( ret == 5, "got %d\n", ret );
5371 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5372 memset( dib_bits, 0xaa, 64 * 4 );
5374 /* handling of partial color table */
5376 info->bmiHeader.biHeight = -8;
5377 info->bmiHeader.biBitCount = 8;
5378 info->bmiHeader.biClrUsed = 137;
5379 for (i = 0; i < 256; i++)
5381 info->bmiColors[i].rgbRed = 255 - i;
5382 info->bmiColors[i].rgbGreen = i * 2;
5383 info->bmiColors[i].rgbBlue = i;
5384 info->bmiColors[i].rgbReserved = 0;
5386 for (i = 0; i < 64; i++) ((BYTE *)data)[i] = i * 4 + 1;
5387 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5388 ok( ret == 8, "got %d\n", ret );
5389 for (i = 0; i < 64; i++)
5391 int idx = i * 4 + 1;
5392 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : (info->bmiColors[idx].rgbRed << 16 |
5393 info->bmiColors[idx].rgbGreen << 8 |
5394 info->bmiColors[idx].rgbBlue);
5395 ok( dib_bits[i] == expect, "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
5397 memset( dib_bits, 0xaa, 64 * 4 );
5399 /* handling of DIB_PAL_COLORS */
5401 pal->palVersion = 0x300;
5402 pal->palNumEntries = 137;
5403 info->bmiHeader.biClrUsed = 221;
5404 for (i = 0; i < 256; i++)
5406 palent[i].peRed = i * 2;
5407 palent[i].peGreen = 255 - i;
5408 palent[i].peBlue = i;
5410 palette = CreatePalette( pal );
5411 ok( palette != 0, "palette creation failed\n" );
5412 SelectPalette( hdc, palette, FALSE );
5413 for (i = 0; i < 256; i++) ((WORD *)info->bmiColors)[i] = 255 - i;
5414 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_PAL_COLORS );
5415 ok( ret == 8, "got %d\n", ret );
5416 for (i = 0; i < 64; i++)
5418 int idx = i * 4 + 1;
5419 int ent = (255 - idx) % pal->palNumEntries;
5420 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 :
5421 (palent[ent].peRed << 16 | palent[ent].peGreen << 8 | palent[ent].peBlue);
5422 ok( dib_bits[i] == expect || broken(dib_bits[i] == 0),
5423 "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
5425 memset( dib_bits, 0xaa, 64 * 4 );
5427 DeleteDC( hdc );
5428 DeleteObject( dib );
5429 DeleteObject( palette );
5430 HeapFree( GetProcessHeap(), 0, info );
5433 static void test_SetDIBitsToDevice_RLE8(void)
5435 BITMAPINFO *info;
5436 DWORD *dib_bits;
5437 HDC hdc = CreateCompatibleDC( 0 );
5438 BYTE rle8_data[20] = { 0x04, 0x02, 0x03, 0xf0, 0x00, 0x00, /* 2, 2, 2, 2, f0, f0, f0, <eol> */
5439 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
5440 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
5441 0x00, 0x01 }; /* <eod> */
5442 HBITMAP dib;
5443 int i, ret;
5444 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
5445 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5446 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5447 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
5448 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5449 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5450 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5451 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
5452 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5453 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5454 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5455 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5456 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
5457 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5458 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5459 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
5461 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
5463 info->bmiHeader.biSize = sizeof(info->bmiHeader);
5464 info->bmiHeader.biWidth = 8;
5465 info->bmiHeader.biHeight = 8;
5466 info->bmiHeader.biPlanes = 1;
5467 info->bmiHeader.biBitCount = 32;
5468 info->bmiHeader.biCompression = BI_RGB;
5470 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5471 memset( dib_bits, 0xaa, 64 * 4 );
5472 SelectObject( hdc, dib );
5474 info->bmiHeader.biBitCount = 8;
5475 info->bmiHeader.biCompression = BI_RLE8;
5476 info->bmiHeader.biSizeImage = sizeof(rle8_data);
5478 for (i = 0; i < 256; i++)
5480 info->bmiColors[i].rgbRed = i;
5481 info->bmiColors[i].rgbGreen = i;
5482 info->bmiColors[i].rgbBlue = i;
5483 info->bmiColors[i].rgbReserved = 0;
5486 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5487 ok( ret == 8, "got %d\n", ret );
5488 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5489 memset( dib_bits, 0xaa, 64 * 4 );
5491 /* startscan and lines are ignored, unless lines == 0 */
5492 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 8, rle8_data, info, DIB_RGB_COLORS );
5493 ok( ret == 8, "got %d\n", ret );
5494 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5495 memset( dib_bits, 0xaa, 64 * 4 );
5497 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 1, rle8_data, info, DIB_RGB_COLORS );
5498 ok( ret == 8, "got %d\n", ret );
5499 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5500 memset( dib_bits, 0xaa, 64 * 4 );
5502 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 0, rle8_data, info, DIB_RGB_COLORS );
5503 ok( ret == 0, "got %d\n", ret );
5504 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5505 memset( dib_bits, 0xaa, 64 * 4 );
5507 info->bmiHeader.biWidth = 2;
5508 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5509 ok( ret == 8, "got %d\n", ret );
5510 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5511 memset( dib_bits, 0xaa, 64 * 4 );
5513 info->bmiHeader.biWidth = 8;
5514 info->bmiHeader.biHeight = 2;
5515 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5516 ok( ret == 2, "got %d\n", ret );
5517 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5518 memset( dib_bits, 0xaa, 64 * 4 );
5520 info->bmiHeader.biHeight = 9;
5521 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5522 ok( ret == 9, "got %d\n", ret );
5523 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5524 memset( dib_bits, 0xaa, 64 * 4 );
5526 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5527 ok( ret == 9, "got %d\n", ret );
5528 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5529 memset( dib_bits, 0xaa, 64 * 4 );
5531 info->bmiHeader.biHeight = 8;
5532 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 9, rle8_data, info, DIB_RGB_COLORS );
5533 ok( ret == 8, "got %d\n", ret );
5534 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5535 memset( dib_bits, 0xaa, 64 * 4 );
5537 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5538 ok( ret == 8, "got %d\n", ret );
5539 for (i = 0; i < 40; i++) ok( dib_bits[i] == bottom_up[i + 24], "%d: got %08x\n", i, dib_bits[i] );
5540 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5541 memset( dib_bits, 0xaa, 64 * 4 );
5543 ret = SetDIBitsToDevice( hdc, 0, 3, 4, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5544 ok( ret == 8, "got %d\n", ret );
5545 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5546 for (i = 8; i < 40; i++)
5547 if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5548 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5549 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5550 memset( dib_bits, 0xaa, 64 * 4 );
5552 ret = SetDIBitsToDevice( hdc, 3, 3, 8, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5553 ok( ret == 8, "got %d\n", ret );
5554 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5555 for (i = 8; i < 40; i++)
5556 if ((i & 7) < 3) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5557 else ok( dib_bits[i] == bottom_up[i - 11], "%d: got %08x\n", i, dib_bits[i] );
5558 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5559 memset( dib_bits, 0xaa, 64 * 4 );
5561 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 4, 2, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5562 ok( ret == 8, "got %d\n", ret );
5563 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5564 for (i = 8; i < 40; i++)
5565 if ((i & 7) < 2) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5566 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5567 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5568 memset( dib_bits, 0xaa, 64 * 4 );
5570 info->bmiHeader.biWidth = 37;
5571 info->bmiHeader.biHeight = 37;
5572 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
5573 ok( ret == 37, "got %d\n", ret );
5574 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5575 for (i = 24; i < 64; i++)
5576 if (i == 52) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
5577 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5578 else ok( dib_bits[i] == bottom_up[i - 20], "%d: got %08x\n", i, dib_bits[i] );
5579 memset( dib_bits, 0xaa, 64 * 4 );
5581 /* top-down compressed dibs are invalid */
5582 info->bmiHeader.biWidth = 8;
5583 info->bmiHeader.biHeight = -8;
5584 SetLastError( 0xdeadbeef );
5585 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5586 ok( ret == 0, "got %d\n", ret );
5587 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
5589 /* top-down dst */
5591 info->bmiHeader.biHeight = -8;
5592 info->bmiHeader.biBitCount = 32;
5593 info->bmiHeader.biCompression = BI_RGB;
5594 info->bmiHeader.biSizeImage = 0;
5596 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5597 memset( dib_bits, 0xaa, 16 * 16 * 4 );
5598 DeleteObject( SelectObject( hdc, dib ));
5600 info->bmiHeader.biHeight = 8;
5601 info->bmiHeader.biBitCount = 8;
5602 info->bmiHeader.biCompression = BI_RLE8;
5603 info->bmiHeader.biSizeImage = sizeof(rle8_data);
5605 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5606 ok( ret == 8, "got %d\n", ret );
5607 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5608 memset( dib_bits, 0xaa, 64 * 4 );
5610 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5611 ok( ret == 8, "got %d\n", ret );
5612 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5613 memset( dib_bits, 0xaa, 64 * 4 );
5615 info->bmiHeader.biHeight = 4;
5616 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5617 ok( ret == 4, "got %d\n", ret );
5618 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5619 memset( dib_bits, 0xaa, 64 * 4 );
5621 info->bmiHeader.biHeight = 9;
5622 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5623 ok( ret == 9, "got %d\n", ret );
5624 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5625 memset( dib_bits, 0xaa, 64 * 4 );
5627 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5628 ok( ret == 9, "got %d\n", ret );
5629 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5630 memset( dib_bits, 0xaa, 64 * 4 );
5632 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 6, 2, 2, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5633 ok( ret == 9, "got %d\n", ret );
5634 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5635 for (i = 24; i < 64; i++) ok( dib_bits[i] == top_down[i - 24], "%d: got %08x\n", i, dib_bits[i] );
5636 memset( dib_bits, 0xaa, 64 * 4 );
5638 info->bmiHeader.biWidth = 37;
5639 info->bmiHeader.biHeight = 37;
5640 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
5641 ok( ret == 37, "got %d\n", ret );
5642 for (i = 0; i < 40; i++)
5643 if (i == 12) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
5644 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5645 else ok( dib_bits[i] == top_down[i + 28], "%d: got %08x\n", i, dib_bits[i] );
5646 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5647 memset( dib_bits, 0xaa, 64 * 4 );
5649 DeleteDC( hdc );
5650 DeleteObject( dib );
5651 HeapFree( GetProcessHeap(), 0, info );
5654 static void test_D3DKMTCreateDCFromMemory( void )
5656 D3DKMT_DESTROYDCFROMMEMORY destroy_desc;
5657 D3DKMT_CREATEDCFROMMEMORY create_desc;
5658 unsigned int width_bytes;
5659 unsigned int i, x, y, z;
5660 DWORD expected, colour;
5661 BYTE data[12][48];
5662 NTSTATUS status;
5663 HGDIOBJ *bitmap;
5664 DIBSECTION dib;
5665 BOOL fail, ret;
5666 DWORD type, pixel;
5667 int size;
5668 HDC bmp_dc;
5669 HBITMAP bmp;
5671 static const struct
5673 const char *name;
5674 D3DDDIFORMAT format;
5675 unsigned int bit_count;
5676 DWORD mask_r, mask_g, mask_b;
5677 NTSTATUS status;
5679 test_data[] =
5681 { "R8G8B8", D3DDDIFMT_R8G8B8, 24, 0x00000000, 0x00000000, 0x00000000, STATUS_SUCCESS },
5682 { "A8R8G8B8", D3DDDIFMT_A8R8G8B8, 32, 0x00000000, 0x00000000, 0x00000000, STATUS_SUCCESS },
5683 { "X8R8G8B8", D3DDDIFMT_X8R8G8B8, 32, 0x00000000, 0x00000000, 0x00000000, STATUS_SUCCESS },
5684 { "R5G6B5", D3DDDIFMT_R5G6B5, 16, 0x0000f800, 0x000007e0, 0x0000001f, STATUS_SUCCESS },
5685 { "X1R5G5B5", D3DDDIFMT_X1R5G5B5, 16, 0x00007c00, 0x000003e0, 0x0000001f, STATUS_SUCCESS },
5686 { "A1R5G5B5", D3DDDIFMT_A1R5G5B5, 16, 0x00007c00, 0x000003e0, 0x0000001f, STATUS_SUCCESS },
5687 { "R3G3B2", D3DDDIFMT_R3G3B2, 8, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER },
5688 { "A2B10G10R10", D3DDDIFMT_A2B10G10R10, 32, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER },
5689 { "A8B8G8R8", D3DDDIFMT_A8B8G8R8, 32, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER },
5690 { "X8B8G8R8", D3DDDIFMT_A8B8G8R8, 32, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER },
5691 { "A2R10G10B10", D3DDDIFMT_A2R10G10B10, 32, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER },
5692 { "P8", D3DDDIFMT_P8, 8, 0x00000000, 0x00000000, 0x00000000, STATUS_SUCCESS },
5693 { "L8", D3DDDIFMT_L8, 8, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER },
5694 { "A8L8", D3DDDIFMT_A8L8, 16, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER },
5695 { "V8U8", D3DDDIFMT_V8U8, 16, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER },
5696 { "Q8W8V8U8", D3DDDIFMT_Q8W8V8U8, 32, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER },
5697 { "DXT1", D3DDDIFMT_DXT1, 4, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER },
5698 { "DXT2", D3DDDIFMT_DXT2, 8, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER },
5699 { "DXT3", D3DDDIFMT_DXT3, 8, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER },
5700 { "DXT4", D3DDDIFMT_DXT4, 8, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER },
5701 { "DXT5", D3DDDIFMT_DXT5, 8, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER },
5704 if (!pD3DKMTCreateDCFromMemory)
5706 win_skip("D3DKMTCreateDCFromMemory() is not implemented.\n");
5707 return;
5710 status = pD3DKMTCreateDCFromMemory( NULL );
5711 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected status %#x.\n", status);
5713 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
5715 memset( data, 0xaa, sizeof(data) );
5717 create_desc.pMemory = data;
5718 create_desc.Format = test_data[i].format;
5719 create_desc.Width = 9;
5720 create_desc.Height = 7;
5721 create_desc.Pitch = sizeof(*data);
5722 create_desc.hDeviceDc = NULL;
5723 create_desc.pColorTable = NULL;
5724 create_desc.hDc = (void *)0x010baade;
5725 create_desc.hBitmap = (void *)0x020baade;
5727 status = pD3DKMTCreateDCFromMemory( &create_desc );
5728 ok(status == STATUS_INVALID_PARAMETER, "%s: Got unexpected status %#x.\n",
5729 test_data[i].name, status);
5731 create_desc.hDeviceDc = CreateCompatibleDC( NULL );
5732 create_desc.pMemory = NULL;
5733 status = pD3DKMTCreateDCFromMemory( &create_desc );
5734 ok(status == STATUS_INVALID_PARAMETER, "%s: Got unexpected status %#x.\n",
5735 test_data[i].name, status);
5737 create_desc.pMemory = data;
5738 create_desc.Height = 0;
5739 status = pD3DKMTCreateDCFromMemory( &create_desc );
5740 ok(status == STATUS_INVALID_PARAMETER, "%s: Got unexpected status %#x.\n",
5741 test_data[i].name, status);
5742 ok(create_desc.hDc == (void *)0x010baade, "%s: Got unexpected dc %p.\n",
5743 test_data[i].name, create_desc.hDc);
5744 ok(create_desc.hBitmap == (void *)0x020baade, "%s: Got unexpected bitmap %p.\n",
5745 test_data[i].name, create_desc.hBitmap);
5747 create_desc.Height = 7;
5748 create_desc.Width = 0;
5749 status = pD3DKMTCreateDCFromMemory( &create_desc );
5750 ok(status == test_data[i].status, "%s: Got unexpected status %#x, expected %#x.\n",
5751 test_data[i].name, status, test_data[i].status);
5752 if (status == STATUS_SUCCESS)
5754 destroy_desc.hDc = create_desc.hDc;
5755 destroy_desc.hBitmap = create_desc.hBitmap;
5756 status = pD3DKMTDestroyDCFromMemory( &destroy_desc );
5757 ok(status == STATUS_SUCCESS, "%s: Got unexpected status %#x.\n", test_data[i].name, status);
5758 create_desc.hDc = (void *)0x010baade;
5759 create_desc.hBitmap = (void *)0x020baade;
5762 create_desc.Pitch = 0;
5763 status = pD3DKMTCreateDCFromMemory( &create_desc );
5764 ok(status == STATUS_INVALID_PARAMETER, "%s: Got unexpected status %#x.\n",
5765 test_data[i].name, status);
5766 ok(create_desc.hDc == (void *)0x010baade, "%s: Got unexpected dc %p.\n",
5767 test_data[i].name, create_desc.hDc);
5768 ok(create_desc.hBitmap == (void *)0x020baade, "%s: Got unexpected bitmap %p.\n",
5769 test_data[i].name, create_desc.hBitmap);
5771 create_desc.Width = 9;
5772 create_desc.Pitch = sizeof(*data);
5773 status = pD3DKMTCreateDCFromMemory( &create_desc );
5774 ok(status == test_data[i].status, "%s: Got unexpected status %#x, expected %#x.\n",
5775 test_data[i].name, status, test_data[i].status);
5776 if (status == STATUS_SUCCESS)
5778 ok(!!create_desc.hDc, "%s: Got unexpected dc %p.\n",
5779 test_data[i].name, create_desc.hDc);
5780 ok(!!create_desc.hBitmap, "%s: Got unexpected bitmap %p.\n",
5781 test_data[i].name, create_desc.hBitmap);
5783 else
5785 ok(create_desc.hDc == (void *)0x010baade, "%s: Got unexpected dc %p.\n",
5786 test_data[i].name, create_desc.hDc);
5787 ok(create_desc.hBitmap == (void *)0x020baade, "%s: Got unexpected bitmap %p.\n",
5788 test_data[i].name, create_desc.hBitmap);
5789 continue;
5792 type = GetObjectType( create_desc.hDc );
5793 ok(type == OBJ_MEMDC, "%s: Got unexpected object type %#x.\n", test_data[i].name, type);
5794 type = GetObjectType( create_desc.hBitmap );
5795 ok(type == OBJ_BITMAP, "%s: Got unexpected object type %#x.\n", test_data[i].name, type);
5796 bitmap = GetCurrentObject( create_desc.hDc, OBJ_BITMAP );
5797 ok(bitmap == create_desc.hBitmap, "%s: Got unexpected bitmap %p, expected %p.\n",
5798 test_data[i].name, bitmap, create_desc.hBitmap);
5800 size = GetObjectA( bitmap, sizeof(dib), &dib );
5801 ok(size == sizeof(dib), "%s: Got unexpected size %d.\n", test_data[i].name, size);
5802 ok(!dib.dsBm.bmType, "%s: Got unexpected type %#x.\n",
5803 test_data[i].name, dib.dsBm.bmType);
5804 ok(dib.dsBm.bmWidth == create_desc.Width, "%s: Got unexpected width %d.\n",
5805 test_data[i].name, dib.dsBm.bmWidth);
5806 ok(dib.dsBm.bmHeight == create_desc.Height, "%s: Got unexpected height %d.\n",
5807 test_data[i].name, dib.dsBm.bmHeight);
5808 width_bytes = get_dib_stride( create_desc.Width, test_data[i].bit_count );
5809 ok(dib.dsBm.bmWidthBytes == width_bytes, "%s: Got unexpected width bytes %d.\n",
5810 test_data[i].name, dib.dsBm.bmWidthBytes);
5811 ok(dib.dsBm.bmPlanes == 1, "%s: Got unexpected plane count %d.\n",
5812 test_data[i].name, dib.dsBm.bmPlanes);
5813 ok(dib.dsBm.bmBitsPixel == test_data[i].bit_count, "%s: Got unexpected bit count %d.\n",
5814 test_data[i].name, dib.dsBm.bmBitsPixel);
5815 ok(dib.dsBm.bmBits == create_desc.pMemory, "%s: Got unexpected bits %p, expected %p.\n",
5816 test_data[i].name, dib.dsBm.bmBits, create_desc.pMemory);
5818 ok(dib.dsBmih.biSize == sizeof(dib.dsBmih), "%s: Got unexpected size %u.\n",
5819 test_data[i].name, dib.dsBmih.biSize);
5820 ok(dib.dsBmih.biWidth == create_desc.Width, "%s: Got unexpected width %d.\n",
5821 test_data[i].name, dib.dsBmih.biHeight);
5822 ok(dib.dsBmih.biHeight == create_desc.Height, "%s: Got unexpected height %d.\n",
5823 test_data[i].name, dib.dsBmih.biHeight);
5824 ok(dib.dsBmih.biPlanes == 1, "%s: Got unexpected plane count %u.\n",
5825 test_data[i].name, dib.dsBmih.biPlanes);
5826 ok(dib.dsBmih.biBitCount == test_data[i].bit_count, "%s: Got unexpected bit count %u.\n",
5827 test_data[i].name, dib.dsBmih.biBitCount);
5828 ok(dib.dsBmih.biCompression == (test_data[i].bit_count == 16 ? BI_BITFIELDS : BI_RGB),
5829 "%s: Got unexpected compression %#x.\n",
5830 test_data[i].name, dib.dsBmih.biCompression);
5831 ok(!dib.dsBmih.biSizeImage, "%s: Got unexpected image size %u.\n",
5832 test_data[i].name, dib.dsBmih.biSizeImage);
5833 ok(!dib.dsBmih.biXPelsPerMeter, "%s: Got unexpected horizontal resolution %d.\n",
5834 test_data[i].name, dib.dsBmih.biXPelsPerMeter);
5835 ok(!dib.dsBmih.biYPelsPerMeter, "%s: Got unexpected vertical resolution %d.\n",
5836 test_data[i].name, dib.dsBmih.biYPelsPerMeter);
5837 if (test_data[i].format == D3DDDIFMT_P8)
5839 ok(dib.dsBmih.biClrUsed == 256, "%s: Got unexpected used colour count %u.\n",
5840 test_data[i].name, dib.dsBmih.biClrUsed);
5841 ok(dib.dsBmih.biClrImportant == 256, "%s: Got unexpected important colour count %u.\n",
5842 test_data[i].name, dib.dsBmih.biClrImportant);
5844 else
5846 ok(!dib.dsBmih.biClrUsed, "%s: Got unexpected used colour count %u.\n",
5847 test_data[i].name, dib.dsBmih.biClrUsed);
5848 ok(!dib.dsBmih.biClrImportant, "%s: Got unexpected important colour count %u.\n",
5849 test_data[i].name, dib.dsBmih.biClrImportant);
5852 ok(dib.dsBitfields[0] == test_data[i].mask_r && dib.dsBitfields[1] == test_data[i].mask_g
5853 && dib.dsBitfields[2] == test_data[i].mask_b,
5854 "%s: Got unexpected colour masks 0x%08x 0x%08x 0x%08x.\n",
5855 test_data[i].name, dib.dsBitfields[0], dib.dsBitfields[1], dib.dsBitfields[2]);
5856 ok(!dib.dshSection, "%s: Got unexpected section %p.\n", test_data[i].name, dib.dshSection);
5857 ok(!dib.dsOffset, "%s: Got unexpected offset %u.\n", test_data[i].name, dib.dsOffset);
5859 ret = BitBlt( create_desc.hDc, 0, 0, 4, 10, NULL, 0, 0, BLACKNESS );
5860 ok(ret, "Failed to blit.\n");
5861 ret = BitBlt( create_desc.hDc, 1, 1, 2, 2, NULL, 0, 0, WHITENESS );
5862 ok(ret, "Failed to blit.\n");
5864 /* Also test blitting to a regular bitmap */
5865 bmp_dc = CreateCompatibleDC( create_desc.hDeviceDc );
5866 ok(bmp_dc != NULL, "failed to create DC\n");
5867 bmp = CreateCompatibleBitmap( bmp_dc, create_desc.Width, create_desc.Height );
5868 ok(bmp != NULL, "failed to create bmp\n");
5869 bmp = SelectObject( bmp_dc, bmp );
5870 ret = BitBlt( bmp_dc, 0, 0, create_desc.Width, create_desc.Height, create_desc.hDc, 0, 0, SRCCOPY );
5871 ok(ret, "Failed to blit.\n");
5873 destroy_desc.hDc = create_desc.hDc;
5874 destroy_desc.hBitmap = create_desc.hBitmap;
5876 status = pD3DKMTDestroyDCFromMemory( NULL );
5877 ok(status == STATUS_INVALID_PARAMETER, "%s: Got unexpected status %#x.\n", test_data[i].name, status);
5878 status = pD3DKMTDestroyDCFromMemory( &destroy_desc );
5879 ok(status == STATUS_SUCCESS, "%s: Got unexpected status %#x.\n", test_data[i].name, status);
5880 status = pD3DKMTDestroyDCFromMemory( &destroy_desc );
5881 ok(status == STATUS_INVALID_PARAMETER, "%s: Got unexpected status %#x.\n", test_data[i].name, status);
5883 ret = DeleteDC( create_desc.hDeviceDc );
5884 ok(ret, "Failed to delete dc.\n");
5886 for (y = 0, fail = FALSE; y < 12 && !fail; ++y)
5888 for (x = 0; x < sizeof(*data) / (test_data[i].bit_count / 8) && !fail; ++x)
5890 for (z = 0, colour = 0; z < test_data[i].bit_count / 8; ++z)
5892 colour = colour << 8 | data[y][x * (test_data[i].bit_count / 8) + z];
5895 if ((x == 1 || x == 2) && (y == 1 || y == 2))
5896 expected = 0xffffffff >> (32 - test_data[i].bit_count);
5897 else if (x < 4 && y < 7)
5898 expected = 0x00000000;
5899 else
5900 expected = 0xaaaaaaaa >> (32 - test_data[i].bit_count);
5901 ok(colour == expected, "%s: Got unexpected colour 0x%08x at %u, %u, expected 0x%08x.\n",
5902 test_data[i].name, colour, x, y, expected);
5903 if (colour != expected)
5904 fail = TRUE;
5906 /* 'Xn' or 'An' formats don't successfully blit to the regular bmp */
5907 if (test_data[i].format == D3DDDIFMT_R8G8B8 || test_data[i].format == D3DDDIFMT_R5G6B5)
5909 pixel = GetPixel( bmp_dc, x, y );
5910 if ((x == 1 || x == 2) && (y == 1 || y == 2))
5911 expected = 0x00ffffff;
5912 else if (x < create_desc.Width && y < create_desc.Height)
5913 expected = 0x00000000;
5914 else
5915 expected = CLR_INVALID;
5916 ok(pixel == expected, "%s: got 0x%08x at %u, %u, expect 0x%08x\n", test_data[i].name,
5917 pixel, x, y, expected);
5922 DeleteObject( SelectObject( bmp_dc, bmp ) );
5923 DeleteDC( bmp_dc );
5927 START_TEST(bitmap)
5929 HMODULE hdll;
5931 hdll = GetModuleHandleA("gdi32.dll");
5932 pD3DKMTCreateDCFromMemory = (void *)GetProcAddress( hdll, "D3DKMTCreateDCFromMemory" );
5933 pD3DKMTDestroyDCFromMemory = (void *)GetProcAddress( hdll, "D3DKMTDestroyDCFromMemory" );
5934 pGdiAlphaBlend = (void *)GetProcAddress( hdll, "GdiAlphaBlend" );
5935 pGdiGradientFill = (void *)GetProcAddress( hdll, "GdiGradientFill" );
5936 pSetLayout = (void *)GetProcAddress( hdll, "SetLayout" );
5938 test_createdibitmap();
5939 test_dibsections();
5940 test_dib_formats();
5941 test_mono_dibsection();
5942 test_bitmap();
5943 test_mono_bitmap();
5944 test_bmBits();
5945 test_GetDIBits_selected_DIB(1);
5946 test_GetDIBits_selected_DIB(4);
5947 test_GetDIBits_selected_DIB(8);
5948 test_GetDIBits_selected_DDB(TRUE);
5949 test_GetDIBits_selected_DDB(FALSE);
5950 test_GetDIBits();
5951 test_GetDIBits_BI_BITFIELDS();
5952 test_select_object();
5953 test_CreateBitmap();
5954 test_BitBlt();
5955 test_StretchBlt();
5956 test_StretchDIBits();
5957 test_GdiAlphaBlend();
5958 test_GdiGradientFill();
5959 test_32bit_ddb();
5960 test_bitmapinfoheadersize();
5961 test_get16dibits();
5962 test_clipping();
5963 test_GetDIBits_top_down(16);
5964 test_GetDIBits_top_down(24);
5965 test_GetDIBits_top_down(32);
5966 test_GetSetDIBits_rtl();
5967 test_GetDIBits_scanlines();
5968 test_SetDIBits();
5969 test_SetDIBits_RLE4();
5970 test_SetDIBits_RLE8();
5971 test_SetDIBitsToDevice();
5972 test_SetDIBitsToDevice_RLE8();
5973 test_D3DKMTCreateDCFromMemory();