wined3d: Don't allow 3D depth textures.
[wine.git] / dlls / gdi32 / tests / bitmap.c
blobe19c5525ca56c0882a5f459602787e19c1d535b4
1 /*
2 * Unit test suite for bitmaps
4 * Copyright 2004 Huw Davies
5 * Copyright 2006 Dmitry Timoshkov
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdarg.h>
23 #include <assert.h>
24 #include <string.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winerror.h"
29 #include "wingdi.h"
30 #include "winuser.h"
31 #include "mmsystem.h"
33 #include "wine/test.h"
35 static BOOL (WINAPI *pGdiAlphaBlend)(HDC,int,int,int,int,HDC,int,int,int,int,BLENDFUNCTION);
36 static BOOL (WINAPI *pGdiGradientFill)(HDC,TRIVERTEX*,ULONG,void*,ULONG,ULONG);
37 static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
39 static inline int get_bitmap_stride( int width, int bpp )
41 return ((width * bpp + 15) >> 3) & ~1;
44 static inline int get_dib_stride( int width, int bpp )
46 return ((width * bpp + 31) >> 3) & ~3;
49 static inline int get_dib_image_size( const BITMAPINFO *info )
51 return get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount )
52 * abs( info->bmiHeader.biHeight );
55 static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHEADER *bmih)
57 BITMAP bm;
58 BITMAP bma[2];
59 INT ret, width_bytes, i;
60 BYTE buf[512], buf_cmp[512];
61 INT test_size[] = {0 /*first value will be changed */, 0, -1, -1000, ~0, sizeof(buf)};
63 ret = GetObjectW(hbm, sizeof(bm), &bm);
64 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
66 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
67 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
68 ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
69 width_bytes = get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel);
70 ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
71 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
72 ok(bm.bmBitsPixel == expected_depth, "wrong bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, expected_depth);
73 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
75 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
76 assert(sizeof(buf) == sizeof(buf_cmp));
78 SetLastError(0xdeadbeef);
79 test_size[0] = bm.bmWidthBytes * bm.bmHeight;
80 /* NULL output buffer with different count values */
81 for (i = 0; i < sizeof(test_size) / sizeof(test_size[0]); i++)
83 ret = GetBitmapBits(hbm, test_size[i], NULL);
84 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
87 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
88 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
90 /* Correct output buffer with different count values */
91 for (i = 0; i < sizeof(test_size) / sizeof(test_size[0]); i++)
93 int expect = i == 1 ? 0 : bm.bmWidthBytes * bm.bmHeight;
94 memset(buf, 0xAA, sizeof(buf));
95 ret = GetBitmapBits(hbm, test_size[i], buf);
96 ok(ret == expect, "Test[%d]: %d != %d\n", i, ret, expect);
97 if (expect)
98 ok(!memcmp(buf, buf_cmp, sizeof(buf)),
99 "Test[%d]: buffers do not match, depth %d\n", i, bmih->biBitCount);
102 /* test various buffer sizes for GetObject */
103 ret = GetObjectW(hbm, sizeof(*bma) * 2, bma);
104 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
106 ret = GetObjectW(hbm, sizeof(bm) / 2, &bm);
107 ok(ret == 0, "%d != 0\n", ret);
109 ret = GetObjectW(hbm, 0, &bm);
110 ok(ret == 0, "%d != 0\n", ret);
112 ret = GetObjectW(hbm, 1, &bm);
113 ok(ret == 0, "%d != 0\n", ret);
115 ret = GetObjectW(hbm, 0, NULL);
116 ok(ret == sizeof(bm), "wrong size %d\n", ret);
119 static void test_createdibitmap(void)
121 HDC hdc, hdcmem;
122 BITMAPINFOHEADER bmih;
123 BITMAPINFO bm;
124 HBITMAP hbm, hbm_colour, hbm_old;
125 INT screen_depth;
126 DWORD pixel;
128 hdc = GetDC(0);
129 screen_depth = GetDeviceCaps(hdc, BITSPIXEL);
130 memset(&bmih, 0, sizeof(bmih));
131 bmih.biSize = sizeof(bmih);
132 bmih.biWidth = 10;
133 bmih.biHeight = 10;
134 bmih.biPlanes = 1;
135 bmih.biBitCount = 32;
136 bmih.biCompression = BI_RGB;
138 hbm = CreateDIBitmap(hdc, NULL, CBM_INIT, NULL, NULL, 0);
139 ok(hbm == NULL, "CreateDIBitmap should fail\n");
140 hbm = CreateDIBitmap(hdc, NULL, 0, NULL, NULL, 0);
141 ok(hbm == NULL, "CreateDIBitmap should fail\n");
143 /* First create an un-initialised bitmap. The depth of the bitmap
144 should match that of the hdc and not that supplied in bmih.
147 /* First try 32 bits */
148 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
149 ok(hbm != NULL, "CreateDIBitmap failed\n");
150 test_bitmap_info(hbm, screen_depth, &bmih);
151 DeleteObject(hbm);
153 /* Then 16 */
154 bmih.biBitCount = 16;
155 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
156 ok(hbm != NULL, "CreateDIBitmap failed\n");
157 test_bitmap_info(hbm, screen_depth, &bmih);
158 DeleteObject(hbm);
160 /* Then 1 */
161 bmih.biBitCount = 1;
162 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
163 ok(hbm != NULL, "CreateDIBitmap failed\n");
164 test_bitmap_info(hbm, screen_depth, &bmih);
165 DeleteObject(hbm);
167 /* Now with a monochrome dc we expect a monochrome bitmap */
168 hdcmem = CreateCompatibleDC(hdc);
170 /* First try 32 bits */
171 bmih.biBitCount = 32;
172 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
173 ok(hbm != NULL, "CreateDIBitmap failed\n");
174 test_bitmap_info(hbm, 1, &bmih);
175 DeleteObject(hbm);
177 /* Then 16 */
178 bmih.biBitCount = 16;
179 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
180 ok(hbm != NULL, "CreateDIBitmap failed\n");
181 test_bitmap_info(hbm, 1, &bmih);
182 DeleteObject(hbm);
184 /* Then 1 */
185 bmih.biBitCount = 1;
186 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
187 ok(hbm != NULL, "CreateDIBitmap failed\n");
188 test_bitmap_info(hbm, 1, &bmih);
189 DeleteObject(hbm);
191 /* Now select a polychrome bitmap into the dc and we expect
192 screen_depth bitmaps again */
193 hbm_colour = CreateCompatibleBitmap(hdc, bmih.biWidth, bmih.biHeight);
194 test_bitmap_info(hbm_colour, screen_depth, &bmih);
195 hbm_old = SelectObject(hdcmem, hbm_colour);
197 /* First try 32 bits */
198 bmih.biBitCount = 32;
199 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
200 ok(hbm != NULL, "CreateDIBitmap failed\n");
201 test_bitmap_info(hbm, screen_depth, &bmih);
202 DeleteObject(hbm);
204 /* Then 16 */
205 bmih.biBitCount = 16;
206 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
207 ok(hbm != NULL, "CreateDIBitmap failed\n");
208 test_bitmap_info(hbm, screen_depth, &bmih);
209 DeleteObject(hbm);
211 /* Then 1 */
212 bmih.biBitCount = 1;
213 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
214 ok(hbm != NULL, "CreateDIBitmap failed\n");
215 test_bitmap_info(hbm, screen_depth, &bmih);
216 DeleteObject(hbm);
218 SelectObject(hdcmem, hbm_old);
219 DeleteObject(hbm_colour);
220 DeleteDC(hdcmem);
222 bmih.biBitCount = 32;
223 hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0);
224 ok(hbm != NULL, "CreateDIBitmap failed\n");
225 test_bitmap_info(hbm, 1, &bmih);
226 DeleteObject(hbm);
228 /* Test how formats are converted */
229 pixel = 0xffffffff;
230 bmih.biBitCount = 1;
231 bmih.biWidth = 1;
232 bmih.biHeight = 1;
234 memset(&bm, 0, sizeof(bm));
235 bm.bmiHeader.biSize = sizeof(bm.bmiHeader);
236 bm.bmiHeader.biWidth = 1;
237 bm.bmiHeader.biHeight = 1;
238 bm.bmiHeader.biPlanes = 1;
239 bm.bmiHeader.biBitCount= 24;
240 bm.bmiHeader.biCompression= BI_RGB;
241 bm.bmiHeader.biSizeImage = 0;
242 hbm = CreateDIBitmap(hdc, &bmih, CBM_INIT, &pixel, &bm, DIB_RGB_COLORS);
243 ok(hbm != NULL, "CreateDIBitmap failed\n");
245 pixel = 0xdeadbeef;
246 bm.bmiHeader.biBitCount= 32;
247 GetDIBits(hdc, hbm, 0, 1, &pixel, &bm, DIB_RGB_COLORS);
248 ok(pixel == 0x00ffffff, "Reading a 32 bit pixel from a DDB returned %08x\n", pixel);
249 DeleteObject(hbm);
251 ReleaseDC(0, hdc);
254 static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
256 BITMAP bm;
257 BITMAP bma[2];
258 DIBSECTION ds;
259 DIBSECTION dsa[2];
260 INT ret, bm_width_bytes, dib_width_bytes;
261 BYTE *buf;
263 ret = GetObjectW(hbm, sizeof(bm), &bm);
264 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
266 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
267 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
268 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
269 dib_width_bytes = get_dib_stride(bm.bmWidth, bm.bmBitsPixel);
270 bm_width_bytes = get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel);
271 if (bm.bmWidthBytes != dib_width_bytes) /* Win2k bug */
272 ok(bm.bmWidthBytes == bm_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, bm_width_bytes);
273 else
274 ok(bm.bmWidthBytes == dib_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, dib_width_bytes);
275 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
276 ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount);
277 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
279 buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);
281 /* GetBitmapBits returns not 32-bit aligned data */
282 SetLastError(0xdeadbeef);
283 ret = GetBitmapBits(hbm, 0, NULL);
284 ok(ret == bm_width_bytes * bm.bmHeight,
285 "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
287 memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
288 ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
289 ok(ret == bm_width_bytes * bm.bmHeight, "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
291 HeapFree(GetProcessHeap(), 0, buf);
293 /* test various buffer sizes for GetObject */
294 memset(&ds, 0xAA, sizeof(ds));
295 ret = GetObjectW(hbm, sizeof(*bma) * 2, bma);
296 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
297 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
298 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
299 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
301 ret = GetObjectW(hbm, sizeof(bm) / 2, &bm);
302 ok(ret == 0, "%d != 0\n", ret);
304 ret = GetObjectW(hbm, 0, &bm);
305 ok(ret == 0, "%d != 0\n", ret);
307 ret = GetObjectW(hbm, 1, &bm);
308 ok(ret == 0, "%d != 0\n", ret);
310 /* test various buffer sizes for GetObject */
311 ret = GetObjectW(hbm, 0, NULL);
312 ok(ret == sizeof(bm), "wrong size %d\n", ret);
314 ret = GetObjectW(hbm, sizeof(*dsa) * 2, dsa);
315 ok(ret == sizeof(*dsa), "wrong size %d\n", ret);
317 memset(&ds, 0xAA, sizeof(ds));
318 ret = GetObjectW(hbm, sizeof(ds), &ds);
319 ok(ret == sizeof(ds), "wrong size %d\n", ret);
321 ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
322 if (ds.dsBm.bmWidthBytes != bm_width_bytes) /* Win2k bug */
323 ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%u != %u\n",
324 ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
325 ok(bmih->biSizeImage == 0, "%u != 0\n", bmih->biSizeImage);
326 ds.dsBmih.biSizeImage = 0;
328 ok(ds.dsBmih.biSize == bmih->biSize, "%u != %u\n", ds.dsBmih.biSize, bmih->biSize);
329 ok(ds.dsBmih.biWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
330 ok(ds.dsBmih.biHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
331 ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes);
332 ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount);
333 ok(ds.dsBmih.biCompression == bmih->biCompression ||
334 ((bmih->biBitCount == 32) && broken(ds.dsBmih.biCompression == BI_BITFIELDS)), /* nt4 sp1 and 2 */
335 "%u != %u\n", ds.dsBmih.biCompression, bmih->biCompression);
336 ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%u != %u\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
337 ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%d != %d\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
338 ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%d != %d\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);
340 memset(&ds, 0xAA, sizeof(ds));
341 ret = GetObjectW(hbm, sizeof(ds) - 4, &ds);
342 ok(ret == sizeof(ds.dsBm), "wrong size %d\n", ret);
343 ok(ds.dsBm.bmWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
344 ok(ds.dsBm.bmHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
345 ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);
347 ret = GetObjectW(hbm, 0, &ds);
348 ok(ret == 0, "%d != 0\n", ret);
350 ret = GetObjectW(hbm, 1, &ds);
351 ok(ret == 0, "%d != 0\n", ret);
354 static void _test_color( int line, HDC hdc, COLORREF color, COLORREF exp )
356 COLORREF c;
357 c = SetPixel(hdc, 0, 0, color);
358 ok_(__FILE__, line)(c == exp, "SetPixel failed: got 0x%06x expected 0x%06x\n", c, exp);
359 c = GetPixel(hdc, 0, 0);
360 ok_(__FILE__, line)(c == exp, "GetPixel failed: got 0x%06x expected 0x%06x\n", c, exp);
361 c = GetNearestColor(hdc, color);
362 ok_(__FILE__, line)(c == exp, "GetNearestColor failed: got 0x%06x expected 0x%06x\n", c, exp);
364 #define test_color(hdc, color, exp) _test_color( __LINE__, hdc, color, exp )
367 static void test_dib_bits_access( HBITMAP hdib, void *bits )
369 MEMORY_BASIC_INFORMATION info;
370 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
371 DWORD data[256];
372 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
373 HDC hdc;
374 char filename[MAX_PATH];
375 HANDLE file;
376 DWORD written;
377 INT ret;
379 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
380 "VirtualQuery failed\n");
381 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
382 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
383 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
384 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
385 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
386 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
388 memset( pbmi, 0, sizeof(bmibuf) );
389 memset( data, 0xcc, sizeof(data) );
390 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
391 pbmi->bmiHeader.biHeight = 16;
392 pbmi->bmiHeader.biWidth = 16;
393 pbmi->bmiHeader.biBitCount = 32;
394 pbmi->bmiHeader.biPlanes = 1;
395 pbmi->bmiHeader.biCompression = BI_RGB;
397 hdc = GetDC(0);
399 ret = SetDIBits( hdc, hdib, 0, 16, data, pbmi, DIB_RGB_COLORS );
400 ok(ret == 16, "SetDIBits failed: expected 16 got %d\n", ret);
402 ReleaseDC(0, hdc);
404 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
405 "VirtualQuery failed\n");
406 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
407 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
408 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
409 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
410 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
411 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
413 /* try writing protected bits to a file */
415 GetTempFileNameA( ".", "dib", 0, filename );
416 file = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
417 CREATE_ALWAYS, 0, 0 );
418 ok( file != INVALID_HANDLE_VALUE, "failed to open %s error %u\n", filename, GetLastError() );
419 ret = WriteFile( file, bits, 8192, &written, NULL );
420 ok( ret, "WriteFile failed error %u\n", GetLastError() );
421 if (ret) ok( written == 8192, "only wrote %u bytes\n", written );
422 CloseHandle( file );
423 DeleteFileA( filename );
426 static void test_dibsections(void)
428 HDC hdc, hdcmem, hdcmem2;
429 HBITMAP hdib, oldbm, hdib2, oldbm2;
430 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
431 char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
432 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
433 BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
434 RGBQUAD *colors = pbmi->bmiColors;
435 RGBTRIPLE *ccolors = pbci->bmciColors;
436 HBITMAP hcoredib;
437 char coreBits[256];
438 BYTE *bits;
439 RGBQUAD rgb[256];
440 int ret;
441 char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
442 LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
443 PALETTEENTRY *palent = plogpal->palPalEntry;
444 WORD *index;
445 DWORD *bits32;
446 HPALETTE hpal, oldpal;
447 DIBSECTION dibsec;
448 COLORREF c0, c1;
449 int i;
450 MEMORY_BASIC_INFORMATION info;
452 hdc = GetDC(0);
454 memset(pbmi, 0, sizeof(bmibuf));
455 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
456 pbmi->bmiHeader.biHeight = 100;
457 pbmi->bmiHeader.biWidth = 512;
458 pbmi->bmiHeader.biBitCount = 24;
459 pbmi->bmiHeader.biPlanes = 1;
460 pbmi->bmiHeader.biCompression = BI_RGB;
462 SetLastError(0xdeadbeef);
464 /* invalid pointer for BITMAPINFO
465 (*bits should be NULL on error) */
466 bits = (BYTE*)0xdeadbeef;
467 hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
468 ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n");
470 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
471 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
472 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
473 ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
475 /* test the DIB memory */
476 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
477 "VirtualQuery failed\n");
478 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
479 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
480 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
481 ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
482 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
483 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
484 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
486 test_dib_bits_access( hdib, bits );
488 test_dib_info(hdib, bits, &pbmi->bmiHeader);
489 DeleteObject(hdib);
491 /* Test a top-down DIB. */
492 pbmi->bmiHeader.biHeight = -100;
493 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
494 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
495 test_dib_info(hdib, bits, &pbmi->bmiHeader);
496 DeleteObject(hdib);
498 pbmi->bmiHeader.biHeight = 100;
499 pbmi->bmiHeader.biBitCount = 8;
500 pbmi->bmiHeader.biCompression = BI_RLE8;
501 SetLastError(0xdeadbeef);
502 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
503 ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
504 ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
506 pbmi->bmiHeader.biBitCount = 16;
507 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
508 ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
509 ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
510 ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
511 SetLastError(0xdeadbeef);
512 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
513 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
515 /* test the DIB memory */
516 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
517 "VirtualQuery failed\n");
518 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
519 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
520 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
521 ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
522 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
523 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
524 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
526 test_dib_info(hdib, bits, &pbmi->bmiHeader);
527 DeleteObject(hdib);
529 memset(pbmi, 0, sizeof(bmibuf));
530 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
531 pbmi->bmiHeader.biHeight = 16;
532 pbmi->bmiHeader.biWidth = 16;
533 pbmi->bmiHeader.biBitCount = 1;
534 pbmi->bmiHeader.biPlanes = 1;
535 pbmi->bmiHeader.biCompression = BI_RGB;
536 colors[0].rgbRed = 0xff;
537 colors[0].rgbGreen = 0;
538 colors[0].rgbBlue = 0;
539 colors[1].rgbRed = 0;
540 colors[1].rgbGreen = 0;
541 colors[1].rgbBlue = 0xff;
543 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
544 ok(hdib != NULL, "CreateDIBSection failed\n");
545 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
546 ok(dibsec.dsBmih.biClrUsed == 2,
547 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
549 /* Test if the old BITMAPCOREINFO structure is supported */
551 pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
552 pbci->bmciHeader.bcBitCount = 0;
554 ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
555 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
556 ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
557 && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
558 "GetDIBits didn't fill in the BITMAPCOREHEADER structure properly\n");
560 ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
561 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
562 ok((ccolors[0].rgbtRed == 0xff) && (ccolors[0].rgbtGreen == 0) &&
563 (ccolors[0].rgbtBlue == 0) && (ccolors[1].rgbtRed == 0) &&
564 (ccolors[1].rgbtGreen == 0) && (ccolors[1].rgbtBlue == 0xff),
565 "The color table has not been translated to the old BITMAPCOREINFO format\n");
567 hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
568 ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
570 ZeroMemory(ccolors, 256 * sizeof(RGBTRIPLE));
571 ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
572 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
573 ok((ccolors[0].rgbtRed == 0xff) && (ccolors[0].rgbtGreen == 0) &&
574 (ccolors[0].rgbtBlue == 0) && (ccolors[1].rgbtRed == 0) &&
575 (ccolors[1].rgbtGreen == 0) && (ccolors[1].rgbtBlue == 0xff),
576 "The color table has not been translated to the old BITMAPCOREINFO format\n");
578 DeleteObject(hcoredib);
580 hdcmem = CreateCompatibleDC(hdc);
581 oldbm = SelectObject(hdcmem, hdib);
583 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
584 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
585 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
586 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
587 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
588 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
590 c0 = RGB(colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue);
591 c1 = RGB(colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue);
593 test_color(hdcmem, DIBINDEX(0), c0);
594 test_color(hdcmem, DIBINDEX(1), c1);
595 test_color(hdcmem, DIBINDEX(2), c0);
596 test_color(hdcmem, PALETTEINDEX(0), c0);
597 test_color(hdcmem, PALETTEINDEX(1), c0);
598 test_color(hdcmem, PALETTEINDEX(2), c0);
599 test_color(hdcmem, PALETTERGB(colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue), c0);
600 test_color(hdcmem, PALETTERGB(colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue), c1);
601 test_color(hdcmem, PALETTERGB(0, 0, 0), c0);
602 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0);
603 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1);
605 SelectObject(hdcmem, oldbm);
606 DeleteObject(hdib);
608 colors[0].rgbRed = 0xff;
609 colors[0].rgbGreen = 0xff;
610 colors[0].rgbBlue = 0xff;
611 colors[1].rgbRed = 0;
612 colors[1].rgbGreen = 0;
613 colors[1].rgbBlue = 0;
615 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
616 ok(hdib != NULL, "CreateDIBSection failed\n");
618 test_dib_info(hdib, bits, &pbmi->bmiHeader);
620 oldbm = SelectObject(hdcmem, hdib);
622 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
623 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
624 ok(!memcmp(rgb, colors, 2 * sizeof(RGBQUAD)),
625 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
626 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
627 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
629 SelectObject(hdcmem, oldbm);
630 test_dib_info(hdib, bits, &pbmi->bmiHeader);
631 DeleteObject(hdib);
633 pbmi->bmiHeader.biBitCount = 4;
634 for (i = 0; i < 16; i++) {
635 colors[i].rgbRed = i;
636 colors[i].rgbGreen = 16-i;
637 colors[i].rgbBlue = 0;
639 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
640 ok(hdib != NULL, "CreateDIBSection failed\n");
641 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
642 ok(dibsec.dsBmih.biClrUsed == 16,
643 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
644 test_dib_info(hdib, bits, &pbmi->bmiHeader);
645 DeleteObject(hdib);
647 pbmi->bmiHeader.biBitCount = 8;
649 for (i = 0; i < 128; i++) {
650 colors[i].rgbRed = 255 - i * 2;
651 colors[i].rgbGreen = i * 2;
652 colors[i].rgbBlue = 0;
653 colors[255 - i].rgbRed = 0;
654 colors[255 - i].rgbGreen = i * 2;
655 colors[255 - i].rgbBlue = 255 - i * 2;
657 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
658 ok(hdib != NULL, "CreateDIBSection failed\n");
659 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
660 ok(dibsec.dsBmih.biClrUsed == 256,
661 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
663 oldbm = SelectObject(hdcmem, hdib);
665 for (i = 0; i < 256; i++) {
666 test_color(hdcmem, DIBINDEX(i), RGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue));
667 test_color(hdcmem, PALETTERGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue),
668 RGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue));
671 SelectObject(hdcmem, oldbm);
672 test_dib_info(hdib, bits, &pbmi->bmiHeader);
673 DeleteObject(hdib);
675 pbmi->bmiHeader.biBitCount = 1;
677 /* Now create a palette and a palette indexed dib section */
678 memset(plogpal, 0, sizeof(logpalbuf));
679 plogpal->palVersion = 0x300;
680 plogpal->palNumEntries = 2;
681 palent[0].peRed = 0xff;
682 palent[0].peBlue = 0xff;
683 palent[1].peGreen = 0xff;
685 index = (WORD*)pbmi->bmiColors;
686 *index++ = 0;
687 *index = 1;
688 hpal = CreatePalette(plogpal);
689 ok(hpal != NULL, "CreatePalette failed\n");
690 oldpal = SelectPalette(hdc, hpal, TRUE);
691 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
692 ok(hdib != NULL, "CreateDIBSection failed\n");
693 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
694 ok(dibsec.dsBmih.biClrUsed == 2, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
696 /* The colour table has already been grabbed from the dc, so we select back the
697 old palette */
699 SelectPalette(hdc, oldpal, TRUE);
700 oldbm = SelectObject(hdcmem, hdib);
701 oldpal = SelectPalette(hdcmem, hpal, TRUE);
703 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
704 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
705 ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
706 rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
707 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
708 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
709 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
711 c0 = RGB(palent[0].peRed, palent[0].peGreen, palent[0].peBlue);
712 c1 = RGB(palent[1].peRed, palent[1].peGreen, palent[1].peBlue);
714 test_color(hdcmem, DIBINDEX(0), c0);
715 test_color(hdcmem, DIBINDEX(1), c1);
716 test_color(hdcmem, DIBINDEX(2), c0);
717 test_color(hdcmem, PALETTEINDEX(0), c0);
718 test_color(hdcmem, PALETTEINDEX(1), c1);
719 test_color(hdcmem, PALETTEINDEX(2), c0);
720 test_color(hdcmem, PALETTERGB(palent[0].peRed, palent[0].peGreen, palent[0].peBlue), c0);
721 test_color(hdcmem, PALETTERGB(palent[1].peRed, palent[1].peGreen, palent[1].peBlue), c1);
722 test_color(hdcmem, PALETTERGB(0, 0, 0), c1);
723 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0);
724 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0);
725 test_color(hdcmem, PALETTERGB(0, 1, 0), c1);
726 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1);
727 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0);
729 /* Bottom and 2nd row from top green, everything else magenta */
730 bits[0] = bits[1] = 0xff;
731 bits[13 * 4] = bits[13*4 + 1] = 0xff;
733 test_dib_info(hdib, bits, &pbmi->bmiHeader);
735 pbmi->bmiHeader.biBitCount = 32;
737 hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
738 ok(hdib2 != NULL, "CreateDIBSection failed\n");
739 hdcmem2 = CreateCompatibleDC(hdc);
740 oldbm2 = SelectObject(hdcmem2, hdib2);
742 BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
744 ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
745 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
747 SelectObject(hdcmem2, oldbm2);
748 test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
749 DeleteObject(hdib2);
751 SelectObject(hdcmem, oldbm);
752 SelectPalette(hdcmem, oldpal, TRUE);
753 DeleteObject(hdib);
754 DeleteObject(hpal);
757 pbmi->bmiHeader.biBitCount = 8;
759 memset(plogpal, 0, sizeof(logpalbuf));
760 plogpal->palVersion = 0x300;
761 plogpal->palNumEntries = 256;
763 for (i = 0; i < 128; i++) {
764 palent[i].peRed = 255 - i * 2;
765 palent[i].peBlue = i * 2;
766 palent[i].peGreen = 0;
767 palent[255 - i].peRed = 0;
768 palent[255 - i].peGreen = i * 2;
769 palent[255 - i].peBlue = 255 - i * 2;
772 index = (WORD*)pbmi->bmiColors;
773 for (i = 0; i < 256; i++) {
774 *index++ = i;
777 hpal = CreatePalette(plogpal);
778 ok(hpal != NULL, "CreatePalette failed\n");
779 oldpal = SelectPalette(hdc, hpal, TRUE);
780 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
781 ok(hdib != NULL, "CreateDIBSection failed\n");
782 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
783 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
785 test_dib_info(hdib, bits, &pbmi->bmiHeader);
787 SelectPalette(hdc, oldpal, TRUE);
788 oldbm = SelectObject(hdcmem, hdib);
789 oldpal = SelectPalette(hdcmem, hpal, TRUE);
791 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
792 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
793 for (i = 0; i < 256; i++) {
794 ok(rgb[i].rgbRed == palent[i].peRed &&
795 rgb[i].rgbBlue == palent[i].peBlue &&
796 rgb[i].rgbGreen == palent[i].peGreen,
797 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
798 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
801 for (i = 0; i < 256; i++) {
802 test_color(hdcmem, DIBINDEX(i), RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
803 test_color(hdcmem, PALETTEINDEX(i), RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
804 test_color(hdcmem, PALETTERGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue),
805 RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
808 SelectPalette(hdcmem, oldpal, TRUE);
809 SelectObject(hdcmem, oldbm);
810 DeleteObject(hdib);
811 DeleteObject(hpal);
813 plogpal->palNumEntries = 37;
814 hpal = CreatePalette(plogpal);
815 ok(hpal != NULL, "CreatePalette failed\n");
816 oldpal = SelectPalette(hdc, hpal, TRUE);
817 pbmi->bmiHeader.biClrUsed = 142;
818 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
819 ok(hdib != NULL, "CreateDIBSection failed\n");
820 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
821 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
823 test_dib_info(hdib, bits, &pbmi->bmiHeader);
825 SelectPalette(hdc, oldpal, TRUE);
826 oldbm = SelectObject(hdcmem, hdib);
828 memset( rgb, 0xcc, sizeof(rgb) );
829 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
830 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
831 for (i = 0; i < 256; i++)
833 if (i < pbmi->bmiHeader.biClrUsed)
835 ok(rgb[i].rgbRed == palent[i % 37].peRed &&
836 rgb[i].rgbBlue == palent[i % 37].peBlue &&
837 rgb[i].rgbGreen == palent[i % 37].peGreen,
838 "GetDIBColorTable returns table %d: r %02x g %02x b %02x res%02x\n",
839 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
840 test_color(hdcmem, DIBINDEX(i),
841 RGB(palent[i % 37].peRed, palent[i % 37].peGreen, palent[i % 37].peBlue));
843 else
845 ok(rgb[i].rgbRed == 0 && rgb[i].rgbBlue == 0 && rgb[i].rgbGreen == 0,
846 "GetDIBColorTable returns table %d: r %02x g %02x b %02x res%02x\n",
847 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
848 test_color(hdcmem, DIBINDEX(i), 0 );
851 pbmi->bmiHeader.biClrUsed = 173;
852 memset( pbmi->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
853 GetDIBits( hdc, hdib, 0, 1, NULL, pbmi, DIB_RGB_COLORS );
854 ok( pbmi->bmiHeader.biClrUsed == 0, "wrong colors %u\n", pbmi->bmiHeader.biClrUsed );
855 for (i = 0; i < 256; i++)
857 if (i < 142)
858 ok(colors[i].rgbRed == palent[i % 37].peRed &&
859 colors[i].rgbBlue == palent[i % 37].peBlue &&
860 colors[i].rgbGreen == palent[i % 37].peGreen,
861 "GetDIBits returns table %d: r %02x g %02x b %02x res%02x\n",
862 i, colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
863 else
864 ok(colors[i].rgbRed == 0 && colors[i].rgbBlue == 0 && colors[i].rgbGreen == 0,
865 "GetDIBits returns table %d: r %02x g %02x b %02x res%02x\n",
866 i, colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
869 rgb[0].rgbRed = 1;
870 rgb[0].rgbGreen = 2;
871 rgb[0].rgbBlue = 3;
872 rgb[0].rgbReserved = 123;
873 ret = SetDIBColorTable( hdcmem, 0, 1, rgb );
874 ok( ret == 1, "SetDIBColorTable returned unexpected result %u\n", ret );
875 ok( rgb[0].rgbReserved == 123, "Expected rgbReserved = 123, got %u\n", rgb[0].rgbReserved );
877 ret = GetDIBColorTable( hdcmem, 0, 1, rgb );
878 ok( ret == 1, "GetDIBColorTable returned unexpected result %u\n", ret );
879 ok( rgb[0].rgbRed == 1, "Expected rgbRed = 1, got %u\n", rgb[0].rgbRed );
880 ok( rgb[0].rgbGreen == 2, "Expected rgbGreen = 2, got %u\n", rgb[0].rgbGreen );
881 ok( rgb[0].rgbBlue == 3, "Expected rgbBlue = 3, got %u\n", rgb[0].rgbBlue );
882 todo_wine ok( rgb[0].rgbReserved == 0, "Expected rgbReserved = 0, got %u\n", rgb[0].rgbReserved );
884 SelectObject(hdcmem, oldbm);
885 DeleteObject(hdib);
886 DeleteObject(hpal);
888 /* ClrUsed ignored on > 8bpp */
889 pbmi->bmiHeader.biBitCount = 16;
890 pbmi->bmiHeader.biClrUsed = 37;
891 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
892 ok(hdib != NULL, "CreateDIBSection failed\n");
893 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
894 ok(dibsec.dsBmih.biClrUsed == 0, "created DIBSection: wrong biClrUsed field: %u\n", dibsec.dsBmih.biClrUsed);
895 oldbm = SelectObject(hdcmem, hdib);
896 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
897 ok(ret == 0, "GetDIBColorTable returned %d\n", ret);
898 SelectObject(hdcmem, oldbm);
899 DeleteObject(hdib);
901 DeleteDC(hdcmem);
902 DeleteDC(hdcmem2);
903 ReleaseDC(0, hdc);
906 static void test_dib_formats(void)
908 BITMAPINFO *bi;
909 char data[256];
910 void *bits;
911 int planes, bpp, compr, format;
912 HBITMAP hdib, hbmp;
913 HDC hdc, memdc;
914 UINT ret;
915 BOOL format_ok, expect_ok;
917 bi = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
918 hdc = GetDC( 0 );
919 memdc = CreateCompatibleDC( 0 );
920 hbmp = CreateCompatibleBitmap( hdc, 10, 10 );
922 memset( data, 0xaa, sizeof(data) );
924 for (bpp = 0; bpp <= 64; bpp++)
926 for (planes = 0; planes <= 64; planes++)
928 for (compr = 0; compr < 8; compr++)
930 for (format = DIB_RGB_COLORS; format <= DIB_PAL_COLORS; format++)
932 switch (bpp)
934 case 1:
935 case 4:
936 case 8:
937 case 24: expect_ok = (compr == BI_RGB); break;
938 case 16:
939 case 32: expect_ok = (compr == BI_RGB || compr == BI_BITFIELDS); break;
940 default: expect_ok = FALSE; break;
943 memset( bi, 0, sizeof(bi->bmiHeader) );
944 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
945 bi->bmiHeader.biWidth = 2;
946 bi->bmiHeader.biHeight = 2;
947 bi->bmiHeader.biPlanes = planes;
948 bi->bmiHeader.biBitCount = bpp;
949 bi->bmiHeader.biCompression = compr;
950 bi->bmiHeader.biSizeImage = 0;
951 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
952 ret = GetDIBits(hdc, hbmp, 0, 0, data, bi, format);
953 if (expect_ok || (!bpp && compr != BI_JPEG && compr != BI_PNG) ||
954 (bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8))
955 ok( ret, "GetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
956 else
957 ok( !ret || broken(!bpp && (compr == BI_JPEG || compr == BI_PNG)), /* nt4 */
958 "GetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
960 /* all functions check planes except GetDIBits with 0 lines */
961 format_ok = expect_ok;
962 if (!planes) expect_ok = FALSE;
963 memset( bi, 0, sizeof(bi->bmiHeader) );
964 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
965 bi->bmiHeader.biWidth = 2;
966 bi->bmiHeader.biHeight = 2;
967 bi->bmiHeader.biPlanes = planes;
968 bi->bmiHeader.biBitCount = bpp;
969 bi->bmiHeader.biCompression = compr;
970 bi->bmiHeader.biSizeImage = 0;
971 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
973 hdib = CreateDIBSection(hdc, bi, format, &bits, NULL, 0);
974 if (expect_ok && (planes == 1 || planes * bpp <= 16) &&
975 (compr != BI_BITFIELDS || format != DIB_PAL_COLORS))
976 ok( hdib != NULL, "CreateDIBSection failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
977 else
978 ok( hdib == NULL, "CreateDIBSection succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
979 if (hdib) DeleteObject( hdib );
981 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, data, bi, format );
982 /* no sanity checks in CreateDIBitmap except compression */
983 if (compr == BI_JPEG || compr == BI_PNG)
984 ok( hdib == NULL || broken(hdib != NULL), /* nt4 */
985 "CreateDIBitmap succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
986 else
987 ok( hdib != NULL, "CreateDIBitmap failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
988 if (hdib) DeleteObject( hdib );
990 /* RLE needs a size */
991 bi->bmiHeader.biSizeImage = 0;
992 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, format);
993 if (expect_ok)
994 ok( ret, "SetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
995 else
996 ok( !ret ||
997 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
998 "SetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
999 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, format );
1000 if (expect_ok)
1001 ok( ret, "SetDIBitsToDevice 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 "SetDIBitsToDevice succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1006 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, format, SRCCOPY );
1007 if (expect_ok)
1008 ok( ret, "StretchDIBits 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 "StretchDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1014 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, format);
1015 if (expect_ok)
1016 ok( ret, "GetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1017 else
1018 ok( !ret, "GetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1019 ok( bi->bmiHeader.biBitCount == bpp, "GetDIBits modified bpp %u/%u\n",
1020 bpp, bi->bmiHeader.biBitCount );
1022 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1023 bi->bmiHeader.biWidth = 2;
1024 bi->bmiHeader.biHeight = 2;
1025 bi->bmiHeader.biPlanes = planes;
1026 bi->bmiHeader.biBitCount = bpp;
1027 bi->bmiHeader.biCompression = compr;
1028 bi->bmiHeader.biSizeImage = 1;
1029 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
1030 /* RLE allowed with valid biSizeImage */
1031 if ((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)) expect_ok = TRUE;
1033 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, format);
1034 if (expect_ok)
1035 ok( ret, "SetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1036 else
1037 ok( !ret, "SetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1038 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, format );
1039 if (expect_ok)
1040 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1041 else
1042 ok( !ret, "SetDIBitsToDevice succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1043 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, format, SRCCOPY );
1044 if (expect_ok)
1045 ok( ret, "StretchDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1046 else
1047 ok( !ret, "StretchDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1049 bi->bmiHeader.biSizeImage = 0;
1050 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, format);
1051 if (expect_ok || !bpp)
1052 ok( ret, "GetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1053 else
1054 ok( !ret || broken(format_ok && !planes), /* nt4 */
1055 "GetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1061 memset( bi, 0, sizeof(bi->bmiHeader) );
1062 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1063 bi->bmiHeader.biWidth = 2;
1064 bi->bmiHeader.biHeight = 2;
1065 bi->bmiHeader.biPlanes = 1;
1066 bi->bmiHeader.biBitCount = 16;
1067 bi->bmiHeader.biCompression = BI_BITFIELDS;
1068 bi->bmiHeader.biSizeImage = 0;
1069 *(DWORD *)&bi->bmiColors[0] = 0;
1070 *(DWORD *)&bi->bmiColors[1] = 0;
1071 *(DWORD *)&bi->bmiColors[2] = 0;
1073 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1074 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1075 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1076 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1077 /* other functions don't check */
1078 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1079 ok( hdib != NULL, "CreateDIBitmap failed with null bitfields\n" );
1080 DeleteObject( hdib );
1081 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1082 ok( ret, "SetDIBitsToDevice failed with null bitfields\n" );
1083 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1084 ok( ret, "StretchDIBits failed with null bitfields\n" );
1085 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1086 ok( ret, "GetDIBits failed with null bitfields\n" );
1087 bi->bmiHeader.biPlanes = 1;
1088 bi->bmiHeader.biBitCount = 16;
1089 bi->bmiHeader.biCompression = BI_BITFIELDS;
1090 bi->bmiHeader.biSizeImage = 0;
1091 *(DWORD *)&bi->bmiColors[0] = 0;
1092 *(DWORD *)&bi->bmiColors[1] = 0;
1093 *(DWORD *)&bi->bmiColors[2] = 0;
1094 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1095 ok( ret, "GetDIBits failed with null bitfields\n" );
1097 /* all fields must be non-zero */
1098 *(DWORD *)&bi->bmiColors[0] = 3;
1099 *(DWORD *)&bi->bmiColors[1] = 0;
1100 *(DWORD *)&bi->bmiColors[2] = 7;
1101 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1102 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1103 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1104 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1106 /* garbage is ok though */
1107 *(DWORD *)&bi->bmiColors[0] = 0x55;
1108 *(DWORD *)&bi->bmiColors[1] = 0x44;
1109 *(DWORD *)&bi->bmiColors[2] = 0x33;
1110 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1111 ok( hdib != NULL, "CreateDIBSection failed with bad bitfields\n" );
1112 if (hdib) DeleteObject( hdib );
1113 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1114 ok( ret, "SetDIBits failed with bad bitfields\n" );
1116 bi->bmiHeader.biWidth = -2;
1117 bi->bmiHeader.biHeight = 2;
1118 bi->bmiHeader.biBitCount = 32;
1119 bi->bmiHeader.biCompression = BI_RGB;
1120 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1121 ok( hdib == NULL, "CreateDIBSection succeeded with negative width\n" );
1122 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1123 ok( hdib == NULL, "CreateDIBitmap succeeded with negative width\n" );
1124 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1125 ok( !ret, "SetDIBits succeeded with negative width\n" );
1126 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1127 ok( !ret, "SetDIBitsToDevice succeeded with negative width\n" );
1128 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1129 ok( !ret, "StretchDIBits succeeded with negative width\n" );
1130 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1131 ok( !ret, "GetDIBits succeeded with negative width\n" );
1132 bi->bmiHeader.biWidth = -2;
1133 bi->bmiHeader.biHeight = 2;
1134 bi->bmiHeader.biBitCount = 32;
1135 bi->bmiHeader.biCompression = BI_RGB;
1136 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1137 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with negative width\n" );
1139 bi->bmiHeader.biWidth = 0;
1140 bi->bmiHeader.biHeight = 2;
1141 bi->bmiHeader.biBitCount = 32;
1142 bi->bmiHeader.biCompression = BI_RGB;
1143 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1144 ok( hdib == NULL, "CreateDIBSection succeeded with zero width\n" );
1145 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1146 ok( hdib != NULL, "CreateDIBitmap failed with zero width\n" );
1147 DeleteObject( hdib );
1148 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1149 ok( !ret || broken(ret), /* nt4 */ "SetDIBits succeeded with zero width\n" );
1150 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1151 ok( !ret || broken(ret), /* nt4 */ "SetDIBitsToDevice succeeded with zero width\n" );
1152 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1153 ok( !ret || broken(ret), /* nt4 */ "StretchDIBits succeeded with zero width\n" );
1154 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1155 ok( !ret, "GetDIBits succeeded with zero width\n" );
1156 bi->bmiHeader.biWidth = 0;
1157 bi->bmiHeader.biHeight = 2;
1158 bi->bmiHeader.biBitCount = 32;
1159 bi->bmiHeader.biCompression = BI_RGB;
1160 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1161 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero width\n" );
1163 bi->bmiHeader.biWidth = 2;
1164 bi->bmiHeader.biHeight = 0;
1165 bi->bmiHeader.biBitCount = 32;
1166 bi->bmiHeader.biCompression = BI_RGB;
1167 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1168 ok( hdib == NULL, "CreateDIBSection succeeded with zero height\n" );
1169 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1170 ok( hdib != NULL, "CreateDIBitmap failed with zero height\n" );
1171 DeleteObject( hdib );
1172 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1173 ok( !ret, "SetDIBits succeeded with zero height\n" );
1174 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1175 ok( !ret, "SetDIBitsToDevice succeeded with zero height\n" );
1176 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1177 ok( !ret, "StretchDIBits succeeded with zero height\n" );
1178 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1179 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1180 bi->bmiHeader.biWidth = 2;
1181 bi->bmiHeader.biHeight = 0;
1182 bi->bmiHeader.biBitCount = 32;
1183 bi->bmiHeader.biCompression = BI_RGB;
1184 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1185 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1187 /* some functions accept DIB_PAL_COLORS+1, but not beyond */
1189 bi->bmiHeader.biWidth = 2;
1190 bi->bmiHeader.biHeight = 2;
1191 bi->bmiHeader.biBitCount = 1;
1192 bi->bmiHeader.biCompression = BI_RGB;
1193 hdib = CreateDIBSection(hdc, bi, DIB_PAL_COLORS+1, &bits, NULL, 0);
1194 ok( hdib == NULL, "CreateDIBSection succeeded with DIB_PAL_COLORS+1\n" );
1195 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_PAL_COLORS+1 );
1196 ok( hdib != NULL, "CreateDIBitmap failed with DIB_PAL_COLORS+1\n" );
1197 DeleteObject( hdib );
1198 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_PAL_COLORS+1);
1199 ok( !ret, "SetDIBits succeeded with DIB_PAL_COLORS+1\n" );
1200 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_PAL_COLORS+1 );
1201 ok( ret, "SetDIBitsToDevice failed with DIB_PAL_COLORS+1\n" );
1202 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_PAL_COLORS+1, SRCCOPY );
1203 ok( ret, "StretchDIBits failed with DIB_PAL_COLORS+1\n" );
1204 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_PAL_COLORS+1);
1205 ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+1\n" );
1206 bi->bmiHeader.biWidth = 2;
1207 bi->bmiHeader.biHeight = 2;
1208 bi->bmiHeader.biBitCount = 1;
1209 bi->bmiHeader.biCompression = BI_RGB;
1210 ret = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS+1);
1211 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 hdib = CreateDIBSection(hdc, bi, DIB_PAL_COLORS+2, &bits, NULL, 0);
1218 ok( hdib == NULL, "CreateDIBSection succeeded with DIB_PAL_COLORS+2\n" );
1219 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_PAL_COLORS+2 );
1220 ok( hdib == NULL, "CreateDIBitmap succeeded with DIB_PAL_COLORS+2\n" );
1221 DeleteObject( hdib );
1222 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_PAL_COLORS+2);
1223 ok( !ret, "SetDIBits succeeded with DIB_PAL_COLORS+2\n" );
1224 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_PAL_COLORS+2 );
1225 ok( !ret, "SetDIBitsToDevice succeeded with DIB_PAL_COLORS+2\n" );
1226 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_PAL_COLORS+2, SRCCOPY );
1227 ok( !ret, "StretchDIBits succeeded with DIB_PAL_COLORS+2\n" );
1228 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_PAL_COLORS+2);
1229 ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+2\n" );
1230 bi->bmiHeader.biWidth = 2;
1231 bi->bmiHeader.biHeight = 2;
1232 bi->bmiHeader.biBitCount = 1;
1233 bi->bmiHeader.biCompression = BI_RGB;
1234 ret = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS+2);
1235 ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+2\n" );
1237 bi->bmiHeader.biWidth = 0x4000;
1238 bi->bmiHeader.biHeight = 0x4000;
1239 bi->bmiHeader.biBitCount = 1;
1240 bi->bmiHeader.biCompression = BI_RGB;
1241 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1242 ok( hdib != NULL, "CreateDIBSection failed with large size\n" );
1243 DeleteObject( hdib );
1245 bi->bmiHeader.biWidth = 0x8001;
1246 bi->bmiHeader.biHeight = 0x8001;
1247 bi->bmiHeader.biBitCount = 32;
1248 bi->bmiHeader.biCompression = BI_RGB;
1249 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1250 ok( hdib == NULL, "CreateDIBSection succeeded with size overflow\n" );
1252 bi->bmiHeader.biWidth = 1;
1253 bi->bmiHeader.biHeight = 0x40000001;
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 = 2;
1260 bi->bmiHeader.biHeight = 0x40000001;
1261 bi->bmiHeader.biBitCount = 16;
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 = 0x40000001;
1267 bi->bmiHeader.biHeight = 1;
1268 bi->bmiHeader.biBitCount = 32;
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 = 4;
1275 bi->bmiHeader.biBitCount = 8;
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 DeleteDC( memdc );
1281 DeleteObject( hbmp );
1282 ReleaseDC( 0, hdc );
1283 HeapFree( GetProcessHeap(), 0, bi );
1286 static void test_mono_dibsection(void)
1288 HDC hdc, memdc;
1289 HBITMAP old_bm, mono_ds;
1290 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
1291 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
1292 RGBQUAD *colors = pbmi->bmiColors;
1293 BYTE bits[10 * 4];
1294 BYTE *ds_bits;
1295 int num;
1297 hdc = GetDC(0);
1299 memdc = CreateCompatibleDC(hdc);
1301 memset(pbmi, 0, sizeof(bmibuf));
1302 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
1303 pbmi->bmiHeader.biHeight = 10;
1304 pbmi->bmiHeader.biWidth = 10;
1305 pbmi->bmiHeader.biBitCount = 1;
1306 pbmi->bmiHeader.biPlanes = 1;
1307 pbmi->bmiHeader.biCompression = BI_RGB;
1308 colors[0].rgbRed = 0xff;
1309 colors[0].rgbGreen = 0xff;
1310 colors[0].rgbBlue = 0xff;
1311 colors[1].rgbRed = 0x0;
1312 colors[1].rgbGreen = 0x0;
1313 colors[1].rgbBlue = 0x0;
1316 * First dib section is 'inverted' ie color[0] is white, color[1] is black
1319 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1320 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1321 old_bm = SelectObject(memdc, mono_ds);
1323 /* black border, white interior */
1324 Rectangle(memdc, 0, 0, 10, 10);
1325 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1326 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1328 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1330 memset(bits, 0, sizeof(bits));
1331 bits[0] = 0xaa;
1333 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1334 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1336 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1338 colors[0].rgbRed = 0x0;
1339 colors[0].rgbGreen = 0x0;
1340 colors[0].rgbBlue = 0x0;
1341 colors[1].rgbRed = 0xff;
1342 colors[1].rgbGreen = 0xff;
1343 colors[1].rgbBlue = 0xff;
1345 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1346 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1348 SelectObject(memdc, old_bm);
1349 DeleteObject(mono_ds);
1352 * Next dib section is 'normal' ie color[0] is black, color[1] is white
1355 colors[0].rgbRed = 0x0;
1356 colors[0].rgbGreen = 0x0;
1357 colors[0].rgbBlue = 0x0;
1358 colors[1].rgbRed = 0xff;
1359 colors[1].rgbGreen = 0xff;
1360 colors[1].rgbBlue = 0xff;
1362 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1363 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1364 old_bm = SelectObject(memdc, mono_ds);
1366 /* black border, white interior */
1367 Rectangle(memdc, 0, 0, 10, 10);
1368 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
1369 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
1371 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
1373 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1374 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1376 /* SetDIBitsToDevice with an inverted bmi -> normal dib section */
1378 colors[0].rgbRed = 0xff;
1379 colors[0].rgbGreen = 0xff;
1380 colors[0].rgbBlue = 0xff;
1381 colors[1].rgbRed = 0x0;
1382 colors[1].rgbGreen = 0x0;
1383 colors[1].rgbBlue = 0x0;
1385 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1386 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1389 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
1392 colors[0].rgbRed = 0xff;
1393 colors[0].rgbGreen = 0xff;
1394 colors[0].rgbBlue = 0xff;
1395 colors[1].rgbRed = 0x0;
1396 colors[1].rgbGreen = 0x0;
1397 colors[1].rgbBlue = 0x0;
1398 num = SetDIBColorTable(memdc, 0, 2, colors);
1399 ok(num == 2, "num = %d\n", num);
1401 /* black border, white interior */
1402 Rectangle(memdc, 0, 0, 10, 10);
1403 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1404 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1406 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1408 memset(bits, 0, sizeof(bits));
1409 bits[0] = 0xaa;
1411 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1412 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1414 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1416 colors[0].rgbRed = 0x0;
1417 colors[0].rgbGreen = 0x0;
1418 colors[0].rgbBlue = 0x0;
1419 colors[1].rgbRed = 0xff;
1420 colors[1].rgbGreen = 0xff;
1421 colors[1].rgbBlue = 0xff;
1423 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1424 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1426 SelectObject(memdc, old_bm);
1427 DeleteObject(mono_ds);
1430 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
1433 colors[0].rgbRed = 0xff;
1434 colors[0].rgbGreen = 0x0;
1435 colors[0].rgbBlue = 0x0;
1436 colors[1].rgbRed = 0xfe;
1437 colors[1].rgbGreen = 0x0;
1438 colors[1].rgbBlue = 0x0;
1440 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1441 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1442 old_bm = SelectObject(memdc, mono_ds);
1444 /* black border, white interior */
1445 Rectangle(memdc, 0, 0, 10, 10);
1446 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1447 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1449 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1451 colors[0].rgbRed = 0x0;
1452 colors[0].rgbGreen = 0x0;
1453 colors[0].rgbBlue = 0x0;
1454 colors[1].rgbRed = 0xff;
1455 colors[1].rgbGreen = 0xff;
1456 colors[1].rgbBlue = 0xff;
1458 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1459 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1461 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1463 colors[0].rgbRed = 0xff;
1464 colors[0].rgbGreen = 0xff;
1465 colors[0].rgbBlue = 0xff;
1466 colors[1].rgbRed = 0x0;
1467 colors[1].rgbGreen = 0x0;
1468 colors[1].rgbBlue = 0x0;
1470 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1471 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1473 SelectObject(memdc, old_bm);
1474 DeleteObject(mono_ds);
1476 DeleteDC(memdc);
1477 ReleaseDC(0, hdc);
1480 static void test_bitmap(void)
1482 char buf[256], buf_cmp[256];
1483 HBITMAP hbmp, hbmp_old;
1484 HDC hdc;
1485 BITMAP bm;
1486 BITMAP bma[2];
1487 INT ret;
1489 hdc = CreateCompatibleDC(0);
1490 assert(hdc != 0);
1492 SetLastError(0xdeadbeef);
1493 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1494 if (!hbmp)
1496 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1497 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1498 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1500 else
1501 DeleteObject(hbmp);
1503 SetLastError(0xdeadbeef);
1504 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1505 if (!hbmp)
1507 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1508 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1509 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1511 else
1512 DeleteObject(hbmp);
1514 SetLastError(0xdeadbeef);
1515 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1516 ok(!hbmp, "CreateBitmap should fail\n");
1517 if (!hbmp)
1518 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1519 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1520 else
1521 DeleteObject(hbmp);
1523 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1524 assert(hbmp != NULL);
1526 ret = GetObjectW(hbmp, sizeof(bm), &bm);
1527 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1529 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1530 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1531 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1532 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1533 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1534 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1535 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1537 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1538 assert(sizeof(buf) == sizeof(buf_cmp));
1540 ret = GetBitmapBits(hbmp, 0, NULL);
1541 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1543 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1544 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1546 memset(buf, 0xAA, sizeof(buf));
1547 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1548 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1549 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1551 hbmp_old = SelectObject(hdc, hbmp);
1553 ret = GetObjectW(hbmp, sizeof(bm), &bm);
1554 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1556 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1557 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1558 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1559 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1560 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1561 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1562 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1564 memset(buf, 0xAA, sizeof(buf));
1565 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1566 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1567 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1569 hbmp_old = SelectObject(hdc, hbmp_old);
1570 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1572 /* test various buffer sizes for GetObject */
1573 ret = GetObjectW(hbmp, sizeof(*bma) * 2, bma);
1574 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1576 ret = GetObjectW(hbmp, sizeof(bm) / 2, &bm);
1577 ok(ret == 0, "%d != 0\n", ret);
1579 ret = GetObjectW(hbmp, 0, &bm);
1580 ok(ret == 0, "%d != 0\n", ret);
1582 ret = GetObjectW(hbmp, 1, &bm);
1583 ok(ret == 0, "%d != 0\n", ret);
1585 DeleteObject(hbmp);
1586 DeleteDC(hdc);
1589 static COLORREF get_nearest( int r, int g, int b )
1591 return (r*r + g*g + b*b < (255-r)*(255-r) + (255-g)*(255-g) + (255-b)*(255-b)) ? 0x000000 : 0xffffff;
1594 static BOOL is_black_pen( COLORREF fg, COLORREF bg, int r, int g, int b )
1596 if (fg == 0 || bg == 0xffffff) return RGB(r,g,b) != 0xffffff && RGB(r,g,b) != bg;
1597 return RGB(r,g,b) == 0x000000 || RGB(r,g,b) == bg;
1600 static void test_bitmap_colors( HDC hdc, COLORREF fg, COLORREF bg, int r, int g, int b )
1602 static const WORD pattern_bits[] = { 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa };
1603 char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors ) + 256 * sizeof(RGBQUAD)];
1604 BITMAPINFO *info = (BITMAPINFO *)buffer;
1605 RGBQUAD *colors = info->bmiColors;
1606 WORD bits[16];
1607 void *bits_ptr;
1608 COLORREF res;
1609 HBRUSH old_brush;
1610 HPEN old_pen;
1611 HBITMAP bitmap;
1612 HDC memdc;
1614 res = SetPixel( hdc, 0, 0, RGB(r,g,b) );
1615 ok( res == get_nearest( r, g, b ),
1616 "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg );
1617 res = GetPixel( hdc, 0, 0 );
1618 ok( res == get_nearest( r, g, b ),
1619 "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg );
1620 res = GetNearestColor( hdc, RGB(r,g,b) );
1621 ok( res == get_nearest( r, g, b ),
1622 "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg );
1624 /* solid pen */
1625 old_pen = SelectObject( hdc, CreatePen( PS_SOLID, 1, RGB(r,g,b) ));
1626 MoveToEx( hdc, 0, 0, NULL );
1627 LineTo( hdc, 16, 0 );
1628 res = GetPixel( hdc, 0, 0 );
1629 ok( res == (is_black_pen( fg, bg, r, g, b ) ? 0 : 0xffffff),
1630 "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg );
1631 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1632 ok( bits[0] == (is_black_pen( fg, bg, r, g, b ) ? 0x00 : 0xffff),
1633 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1634 DeleteObject( SelectObject( hdc, old_pen ));
1636 /* mono DDB pattern brush */
1637 bitmap = CreateBitmap( 16, 8, 1, 1, pattern_bits );
1638 old_brush = SelectObject( hdc, CreatePatternBrush( bitmap ));
1639 PatBlt( hdc, 0, 0, 16, 16, PATCOPY );
1640 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1641 ok( bits[0] == 0x5555 || broken(bits[0] == 0xaada) /* XP SP1 & 2003 SP0 */,
1642 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1643 DeleteObject( SelectObject( hdc, old_brush ));
1645 /* mono DDB bitmap */
1646 memdc = CreateCompatibleDC( hdc );
1647 SelectObject( memdc, bitmap );
1648 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1649 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1650 ok( bits[0] == 0x5555,
1651 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1652 SetTextColor( memdc, RGB(255,255,255) );
1653 SetBkColor( memdc, RGB(0,0,0) );
1654 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1655 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1656 ok( bits[0] == 0x5555,
1657 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1659 /* mono DIB section */
1660 memset( buffer, 0, sizeof(buffer) );
1661 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1662 info->bmiHeader.biHeight = -16;
1663 info->bmiHeader.biWidth = 16;
1664 info->bmiHeader.biBitCount = 1;
1665 info->bmiHeader.biPlanes = 1;
1666 info->bmiHeader.biCompression = BI_RGB;
1667 colors[0].rgbRed = 0xff;
1668 colors[0].rgbGreen = 0xff;
1669 colors[0].rgbBlue = 0xf0;
1670 colors[1].rgbRed = 0x20;
1671 colors[1].rgbGreen = 0x0;
1672 colors[1].rgbBlue = 0x0;
1673 bitmap = CreateDIBSection( 0, info, DIB_RGB_COLORS, &bits_ptr, NULL, 0 );
1674 memset( bits_ptr, 0x55, 64 );
1675 DeleteObject( SelectObject( memdc, bitmap ));
1676 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1677 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1678 ok( bits[0] == 0x5555,
1679 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1681 colors[0].rgbRed = 0x0;
1682 colors[0].rgbGreen = 0x0;
1683 colors[0].rgbBlue = 0x10;
1684 colors[1].rgbRed = 0xff;
1685 colors[1].rgbGreen = 0xf0;
1686 colors[1].rgbBlue = 0xff;
1687 bitmap = CreateDIBSection( 0, info, DIB_RGB_COLORS, &bits_ptr, NULL, 0 );
1688 memset( bits_ptr, 0x55, 64 );
1689 DeleteObject( SelectObject( memdc, bitmap ));
1690 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1691 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1692 ok( bits[0] == 0xaaaa,
1693 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1695 SetTextColor( memdc, RGB(0,20,0) );
1696 SetBkColor( memdc, RGB(240,240,240) );
1697 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1698 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1699 ok( bits[0] == 0x5555,
1700 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1702 SetTextColor( memdc, RGB(250,250,250) );
1703 SetBkColor( memdc, RGB(10,10,10) );
1704 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1705 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1706 ok( bits[0] == 0xaaaa,
1707 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1708 DeleteDC( memdc );
1709 DeleteObject( bitmap );
1712 static void test_mono_bitmap(void)
1714 static const COLORREF colors[][2] =
1716 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff) },
1717 { RGB(0xff,0xff,0xff), RGB(0x00,0x00,0x00) },
1718 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xfe) },
1719 { RGB(0x00,0x01,0x00), RGB(0xff,0xff,0xff) },
1720 { RGB(0x00,0x00,0x00), RGB(0x80,0x80,0x80) },
1721 { RGB(0x80,0x80,0x80), RGB(0xff,0xff,0xff) },
1722 { RGB(0x30,0x40,0x50), RGB(0x60,0x70,0x80) },
1723 { RGB(0xa0,0xa0,0xa0), RGB(0x20,0x30,0x10) },
1724 { PALETTEINDEX(0), PALETTEINDEX(255) },
1725 { PALETTEINDEX(1), PALETTEINDEX(2) },
1728 HBITMAP hbmp;
1729 HDC hdc;
1730 DWORD col;
1731 int i, r, g, b;
1733 hdc = CreateCompatibleDC(0);
1734 assert(hdc != 0);
1736 hbmp = CreateBitmap(16, 16, 1, 1, NULL);
1737 assert(hbmp != NULL);
1739 SelectObject( hdc, hbmp );
1741 for (col = 0; col < sizeof(colors) / sizeof(colors[0]); col++)
1743 SetTextColor( hdc, colors[col][0] );
1744 SetBkColor( hdc, colors[col][1] );
1746 for (i = 0; i < 256; i++)
1748 HPALETTE pal = GetCurrentObject( hdc, OBJ_PAL );
1749 PALETTEENTRY ent;
1751 if (!GetPaletteEntries( pal, i, 1, &ent )) GetPaletteEntries( pal, 0, 1, &ent );
1752 test_color( hdc, PALETTEINDEX(i), get_nearest( ent.peRed, ent.peGreen, ent.peBlue ));
1753 test_color( hdc, DIBINDEX(i), (i == 1) ? 0xffffff : 0x000000 );
1756 for (r = 0; r < 256; r += 15)
1757 for (g = 0; g < 256; g += 15)
1758 for (b = 0; b < 256; b += 15)
1759 test_bitmap_colors( hdc, colors[col][0], colors[col][1], r, g, b );
1762 DeleteDC(hdc);
1763 DeleteObject(hbmp);
1766 static void test_bmBits(void)
1768 BYTE bits[4];
1769 HBITMAP hbmp;
1770 BITMAP bmp;
1772 memset(bits, 0, sizeof(bits));
1773 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1774 ok(hbmp != NULL, "CreateBitmap failed\n");
1776 memset(&bmp, 0xFF, sizeof(bmp));
1777 ok(GetObjectW(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1778 "GetObject failed or returned a wrong structure size\n");
1779 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1781 DeleteObject(hbmp);
1784 static void test_GetDIBits_selected_DIB(UINT bpp)
1786 HBITMAP dib;
1787 BITMAPINFO *info;
1788 BITMAPINFO *info2;
1789 void * bits;
1790 void * bits2;
1791 UINT dib_size, dib32_size;
1792 DWORD pixel;
1793 HDC dib_dc, dc;
1794 HBITMAP old_bmp;
1795 UINT i;
1796 int res;
1798 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1799 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1801 /* Create a DIB section with a color table */
1803 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1804 info->bmiHeader.biWidth = 32;
1805 info->bmiHeader.biHeight = 32;
1806 info->bmiHeader.biPlanes = 1;
1807 info->bmiHeader.biBitCount = bpp;
1808 info->bmiHeader.biCompression = BI_RGB;
1809 info->bmiHeader.biXPelsPerMeter = 0;
1810 info->bmiHeader.biYPelsPerMeter = 0;
1811 info->bmiHeader.biClrUsed = 0;
1812 info->bmiHeader.biClrImportant = 0;
1814 for (i=0; i < (1u << bpp); i++)
1816 BYTE c = i * (1 << (8 - bpp));
1817 info->bmiColors[i].rgbRed = c;
1818 info->bmiColors[i].rgbGreen = c;
1819 info->bmiColors[i].rgbBlue = c;
1820 info->bmiColors[i].rgbReserved = 0;
1823 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1824 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1825 dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1827 /* Set the bits of the DIB section */
1828 for (i=0; i < dib_size; i++)
1830 ((BYTE *)bits)[i] = i % 256;
1833 /* Select the DIB into a DC */
1834 dib_dc = CreateCompatibleDC(NULL);
1835 old_bmp = SelectObject(dib_dc, dib);
1836 dc = CreateCompatibleDC(NULL);
1837 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
1839 /* Copy the DIB attributes but not the color table */
1840 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1842 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1843 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1845 /* Compare the color table and the bits */
1846 for (i=0; i < (1u << bpp); i++)
1847 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1848 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1849 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1850 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1851 "color table entry %d differs (bpp %d)\n", i, bpp );
1853 ok( !memcmp( bits, bits2, dib_size ), "bit mismatch (bpp %d)\n", bpp );
1855 /* Test various combinations of lines = 0 and bits2 = NULL */
1856 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1857 res = GetDIBits( dc, dib, 0, 0, bits2, info2, DIB_RGB_COLORS );
1858 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1859 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1860 "color table mismatch (bpp %d)\n", bpp );
1862 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1863 res = GetDIBits( dc, dib, 0, 0, NULL, info2, DIB_RGB_COLORS );
1864 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1865 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1866 "color table mismatch (bpp %d)\n", bpp );
1868 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1869 res = GetDIBits( dc, dib, 0, info->bmiHeader.biHeight, NULL, info2, DIB_RGB_COLORS );
1870 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1871 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1872 "color table mismatch (bpp %d)\n", bpp );
1874 /* Map into a 32bit-DIB */
1875 info2->bmiHeader.biBitCount = 32;
1876 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1877 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1879 /* Check if last pixel was set */
1880 pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
1881 ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
1883 HeapFree(GetProcessHeap(), 0, bits2);
1884 DeleteDC(dc);
1886 SelectObject(dib_dc, old_bmp);
1887 DeleteDC(dib_dc);
1888 DeleteObject(dib);
1889 HeapFree(GetProcessHeap(), 0, info2);
1890 HeapFree(GetProcessHeap(), 0, info);
1893 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1895 HBITMAP ddb;
1896 BITMAPINFO *info;
1897 BITMAPINFO *info2;
1898 void * bits;
1899 void * bits2;
1900 HDC ddb_dc, dc;
1901 HBITMAP old_bmp;
1902 UINT width, height;
1903 UINT bpp;
1904 UINT i, j;
1905 int res;
1907 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1908 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1910 width = height = 16;
1912 /* Create a DDB (device-dependent bitmap) */
1913 if (monochrome)
1915 bpp = 1;
1916 ddb = CreateBitmap(width, height, 1, 1, NULL);
1918 else
1920 HDC screen_dc = GetDC(NULL);
1921 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1922 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1923 ReleaseDC(NULL, screen_dc);
1926 /* Set the pixels */
1927 ddb_dc = CreateCompatibleDC(NULL);
1928 old_bmp = SelectObject(ddb_dc, ddb);
1929 for (i = 0; i < width; i++)
1931 for (j=0; j < height; j++)
1933 BYTE c = (i * width + j) % 256;
1934 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1937 SelectObject(ddb_dc, old_bmp);
1939 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1940 info->bmiHeader.biWidth = width;
1941 info->bmiHeader.biHeight = height;
1942 info->bmiHeader.biPlanes = 1;
1943 info->bmiHeader.biBitCount = bpp;
1944 info->bmiHeader.biCompression = BI_RGB;
1946 dc = CreateCompatibleDC(NULL);
1948 /* Fill in biSizeImage */
1949 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1950 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1952 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1953 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1955 /* Get the bits */
1956 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1957 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1959 /* Copy the DIB attributes but not the color table */
1960 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1962 /* Select the DDB into another DC */
1963 old_bmp = SelectObject(ddb_dc, ddb);
1965 /* Get the bits */
1966 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1967 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1969 /* Compare the color table and the bits */
1970 if (bpp <= 8)
1972 for (i=0; i < (1u << bpp); i++)
1973 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1974 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1975 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1976 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1977 "color table entry %d differs (bpp %d)\n", i, bpp );
1980 ok( !memcmp( bits, bits2, info->bmiHeader.biSizeImage ), "bit mismatch (bpp %d)\n", bpp );
1982 /* Test the palette */
1983 if (info2->bmiHeader.biBitCount <= 8)
1985 WORD *colors = (WORD*)info2->bmiColors;
1987 /* Get the palette indices */
1988 res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1989 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1991 for (i = 0; i < (1 << info->bmiHeader.biBitCount); i++)
1992 ok( colors[i] == i, "%d: got %d (bpp %d)\n", i, colors[i], bpp );
1995 HeapFree(GetProcessHeap(), 0, bits2);
1996 HeapFree(GetProcessHeap(), 0, bits);
1997 DeleteDC(dc);
1999 SelectObject(ddb_dc, old_bmp);
2000 DeleteDC(ddb_dc);
2001 DeleteObject(ddb);
2002 HeapFree(GetProcessHeap(), 0, info2);
2003 HeapFree(GetProcessHeap(), 0, info);
2006 static void test_GetDIBits(void)
2008 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
2009 static const BYTE bmp_bits_1[16 * 2] =
2011 0xff,0xff, 0,0, 0xff,0xff, 0,0,
2012 0xff,0xff, 0,0, 0xff,0xff, 0,0,
2013 0xff,0xff, 0,0, 0xff,0xff, 0,0,
2014 0xff,0xff, 0,0, 0xff,0xff, 0,0
2016 /* 4-bytes aligned 1-bit DIB data: 16x16 */
2017 static const BYTE dib_bits_1[16 * 4] =
2019 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
2020 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
2021 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
2022 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
2024 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
2025 static const BYTE bmp_bits_24[16 * 16*3] =
2027 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2028 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2029 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2030 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2031 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2032 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2033 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2034 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
2060 /* 4-bytes aligned 24-bit DIB data: 16x16 */
2061 static const BYTE dib_bits_24[16 * 16*3] =
2063 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2066 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2067 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2068 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2069 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2070 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
2096 HBITMAP hbmp;
2097 BITMAP bm;
2098 HDC hdc;
2099 int i, bytes, lines;
2100 BYTE buf[1024];
2101 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
2102 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
2103 RGBQUAD *colors = bi->bmiColors;
2104 PALETTEENTRY pal_ents[20];
2106 hdc = GetDC(0);
2108 /* 1-bit source bitmap data */
2109 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
2110 ok(hbmp != 0, "CreateBitmap failed\n");
2112 memset(&bm, 0xAA, sizeof(bm));
2113 bytes = GetObjectW(hbmp, sizeof(bm), &bm);
2114 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2115 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2116 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
2117 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
2118 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2119 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
2120 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2121 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2123 bytes = GetBitmapBits(hbmp, 0, NULL);
2124 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
2125 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
2126 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
2127 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
2129 /* retrieve 1-bit DIB data */
2130 memset(bi, 0, sizeof(*bi));
2131 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2132 bi->bmiHeader.biWidth = bm.bmWidth;
2133 bi->bmiHeader.biHeight = bm.bmHeight;
2134 bi->bmiHeader.biPlanes = 1;
2135 bi->bmiHeader.biBitCount = 1;
2136 bi->bmiHeader.biCompression = BI_RGB;
2137 bi->bmiHeader.biClrUsed = 37;
2138 bi->bmiHeader.biSizeImage = 0;
2139 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2140 SetLastError(0xdeadbeef);
2141 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2142 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
2143 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
2144 broken(GetLastError() == 0xdeadbeef), /* winnt */
2145 "wrong error %u\n", GetLastError());
2146 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
2147 ok(bi->bmiHeader.biClrUsed == 37 || broken(bi->bmiHeader.biClrUsed == 0),
2148 "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2150 memset(buf, 0xAA, sizeof(buf));
2151 SetLastError(0xdeadbeef);
2152 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2153 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2154 lines, bm.bmHeight, GetLastError());
2155 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
2156 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2158 /* the color table consists of black and white */
2159 ok(colors[0].rgbRed == 0 && colors[0].rgbGreen == 0 &&
2160 colors[0].rgbBlue == 0 && colors[0].rgbReserved == 0,
2161 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
2162 colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue, colors[0].rgbReserved);
2163 ok(colors[1].rgbRed == 0xff && colors[1].rgbGreen == 0xff &&
2164 colors[1].rgbBlue == 0xff && colors[1].rgbReserved == 0,
2165 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
2166 colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue, colors[1].rgbReserved);
2167 for (i = 2; i < 256; i++)
2169 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2170 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2171 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2172 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2175 /* returned bits are DWORD aligned and upside down */
2176 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
2178 /* Test the palette indices */
2179 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2180 SetLastError(0xdeadbeef);
2181 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
2182 ok(((WORD*)colors)[0] == 0, "Color 0 is %d\n", ((WORD*)colors)[0]);
2183 ok(((WORD*)colors)[1] == 1, "Color 1 is %d\n", ((WORD*)colors)[1]);
2184 for (i = 2; i < 256; i++)
2185 ok(((WORD*)colors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)colors)[1]);
2187 /* retrieve 24-bit DIB data */
2188 memset(bi, 0, sizeof(*bi));
2189 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2190 bi->bmiHeader.biWidth = bm.bmWidth;
2191 bi->bmiHeader.biHeight = bm.bmHeight;
2192 bi->bmiHeader.biPlanes = 1;
2193 bi->bmiHeader.biBitCount = 24;
2194 bi->bmiHeader.biCompression = BI_RGB;
2195 bi->bmiHeader.biClrUsed = 37;
2196 bi->bmiHeader.biSizeImage = 0;
2197 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2198 memset(buf, 0xAA, sizeof(buf));
2199 SetLastError(0xdeadbeef);
2200 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2201 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2202 lines, bm.bmHeight, GetLastError());
2203 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2204 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2206 /* the color table doesn't exist for 24-bit images */
2207 for (i = 0; i < 256; i++)
2209 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2210 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2211 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2212 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2215 /* returned bits are DWORD aligned and upside down */
2216 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2217 DeleteObject(hbmp);
2219 /* 24-bit source bitmap data */
2220 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
2221 ok(hbmp != 0, "CreateBitmap failed\n");
2222 SetLastError(0xdeadbeef);
2223 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
2224 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
2225 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
2226 lines, bm.bmHeight, GetLastError());
2228 memset(&bm, 0xAA, sizeof(bm));
2229 bytes = GetObjectW(hbmp, sizeof(bm), &bm);
2230 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2231 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2232 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
2233 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
2234 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2235 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
2236 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2237 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2239 bytes = GetBitmapBits(hbmp, 0, NULL);
2240 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
2241 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
2242 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
2243 bm.bmWidthBytes * bm.bmHeight, bytes);
2245 /* retrieve 1-bit DIB data */
2246 memset(bi, 0, sizeof(*bi));
2247 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2248 bi->bmiHeader.biWidth = bm.bmWidth;
2249 bi->bmiHeader.biHeight = bm.bmHeight;
2250 bi->bmiHeader.biPlanes = 1;
2251 bi->bmiHeader.biBitCount = 1;
2252 bi->bmiHeader.biCompression = BI_RGB;
2253 bi->bmiHeader.biClrUsed = 37;
2254 bi->bmiHeader.biSizeImage = 0;
2255 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2256 memset(buf, 0xAA, sizeof(buf));
2257 SetLastError(0xdeadbeef);
2258 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2259 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2260 lines, bm.bmHeight, GetLastError());
2261 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
2262 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2264 /* the color table consists of black and white */
2265 ok(colors[0].rgbRed == 0 && colors[0].rgbGreen == 0 &&
2266 colors[0].rgbBlue == 0 && colors[0].rgbReserved == 0,
2267 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
2268 colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue, colors[0].rgbReserved);
2269 ok(colors[1].rgbRed == 0xff && colors[1].rgbGreen == 0xff &&
2270 colors[1].rgbBlue == 0xff && colors[1].rgbReserved == 0,
2271 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
2272 colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue, colors[1].rgbReserved);
2273 for (i = 2; i < 256; i++)
2275 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2276 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2277 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2278 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2281 /* returned bits are DWORD aligned and upside down */
2282 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
2284 /* Test the palette indices */
2285 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2286 SetLastError(0xdeadbeef);
2287 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
2288 ok(((WORD*)colors)[0] == 0, "Color 0 is %d\n", ((WORD*)colors)[0]);
2289 ok(((WORD*)colors)[1] == 1, "Color 1 is %d\n", ((WORD*)colors)[1]);
2290 for (i = 2; i < 256; i++)
2291 ok(((WORD*)colors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)colors)[i]);
2293 /* retrieve 4-bit DIB data */
2294 memset(bi, 0, sizeof(*bi));
2295 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2296 bi->bmiHeader.biWidth = bm.bmWidth;
2297 bi->bmiHeader.biHeight = bm.bmHeight;
2298 bi->bmiHeader.biPlanes = 1;
2299 bi->bmiHeader.biBitCount = 4;
2300 bi->bmiHeader.biCompression = BI_RGB;
2301 bi->bmiHeader.biClrUsed = 37;
2302 bi->bmiHeader.biSizeImage = 0;
2303 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2304 memset(buf, 0xAA, sizeof(buf));
2305 SetLastError(0xdeadbeef);
2306 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2307 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2308 lines, bm.bmHeight, GetLastError());
2309 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2311 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2313 for (i = 0; i < 16; i++)
2315 RGBQUAD expect;
2316 int entry = i < 8 ? i : i + 4;
2318 if(entry == 7) entry = 12;
2319 else if(entry == 12) entry = 7;
2321 expect.rgbRed = pal_ents[entry].peRed;
2322 expect.rgbGreen = pal_ents[entry].peGreen;
2323 expect.rgbBlue = pal_ents[entry].peBlue;
2324 expect.rgbReserved = 0;
2326 ok(!memcmp(colors + i, &expect, sizeof(expect)),
2327 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2328 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2329 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2332 /* retrieve 8-bit DIB data */
2333 memset(bi, 0, sizeof(*bi));
2334 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2335 bi->bmiHeader.biWidth = bm.bmWidth;
2336 bi->bmiHeader.biHeight = bm.bmHeight;
2337 bi->bmiHeader.biPlanes = 1;
2338 bi->bmiHeader.biBitCount = 8;
2339 bi->bmiHeader.biCompression = BI_RGB;
2340 bi->bmiHeader.biClrUsed = 37;
2341 bi->bmiHeader.biSizeImage = 0;
2342 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2343 memset(buf, 0xAA, sizeof(buf));
2344 SetLastError(0xdeadbeef);
2345 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2346 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2347 lines, bm.bmHeight, GetLastError());
2348 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2350 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2352 for (i = 0; i < 256; i++)
2354 RGBQUAD expect;
2356 if (i < 10 || i >= 246)
2358 int entry = i < 10 ? i : i - 236;
2359 expect.rgbRed = pal_ents[entry].peRed;
2360 expect.rgbGreen = pal_ents[entry].peGreen;
2361 expect.rgbBlue = pal_ents[entry].peBlue;
2363 else
2365 expect.rgbRed = (i & 0x07) << 5;
2366 expect.rgbGreen = (i & 0x38) << 2;
2367 expect.rgbBlue = i & 0xc0;
2369 expect.rgbReserved = 0;
2371 ok(!memcmp(colors + i, &expect, sizeof(expect)),
2372 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2373 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2374 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2377 /* retrieve 24-bit DIB data */
2378 memset(bi, 0, sizeof(*bi));
2379 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2380 bi->bmiHeader.biWidth = bm.bmWidth;
2381 bi->bmiHeader.biHeight = bm.bmHeight;
2382 bi->bmiHeader.biPlanes = 1;
2383 bi->bmiHeader.biBitCount = 24;
2384 bi->bmiHeader.biCompression = BI_RGB;
2385 bi->bmiHeader.biClrUsed = 37;
2386 bi->bmiHeader.biSizeImage = 0;
2387 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2388 memset(buf, 0xAA, sizeof(buf));
2389 SetLastError(0xdeadbeef);
2390 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2391 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2392 lines, bm.bmHeight, GetLastError());
2393 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2394 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2396 /* the color table doesn't exist for 24-bit images */
2397 for (i = 0; i < 256; i++)
2399 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2400 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2401 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2402 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2405 /* returned bits are DWORD aligned and upside down */
2406 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2407 DeleteObject(hbmp);
2409 ReleaseDC(0, hdc);
2412 static void test_GetDIBits_BI_BITFIELDS(void)
2414 /* Try a screen resolution detection technique
2415 * from the September 1999 issue of Windows Developer's Journal
2416 * which seems to be in widespread use.
2417 * http://www.lesher.ws/highcolor.html
2418 * http://www.lesher.ws/vidfmt.c
2419 * It hinges on being able to retrieve the bitmaps
2420 * for the three primary colors in non-paletted 16 bit mode.
2422 char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
2423 DWORD bits[32];
2424 LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
2425 DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
2426 HDC hdc;
2427 HBITMAP hbm;
2428 int ret;
2429 void *ptr;
2431 memset(dibinfo, 0, sizeof(dibinfo_buf));
2432 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2434 hdc = GetDC(NULL);
2435 ok(hdc != NULL, "GetDC failed?\n");
2436 hbm = CreateCompatibleBitmap(hdc, 1, 1);
2437 ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
2439 /* Call GetDIBits to fill in bmiHeader. */
2440 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2441 ok(ret == 1, "GetDIBits failed\n");
2442 if (dibinfo->bmiHeader.biBitCount > 8)
2444 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2445 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2446 "compression is %u (%d bpp)\n", dibinfo->bmiHeader.biCompression, dibinfo->bmiHeader.biBitCount );
2448 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2450 ok( !bitmasks[0], "red mask is set\n" );
2451 ok( !bitmasks[1], "green mask is set\n" );
2452 ok( !bitmasks[2], "blue mask is set\n" );
2454 /* test with NULL bits pointer and correct bpp */
2455 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2456 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2457 ok(ret == 1, "GetDIBits failed\n");
2459 ok( bitmasks[0] != 0, "red mask is not set\n" );
2460 ok( bitmasks[1] != 0, "green mask is not set\n" );
2461 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2462 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2464 /* test with valid bits pointer */
2465 memset(dibinfo, 0, sizeof(dibinfo_buf));
2466 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2467 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2468 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2469 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2470 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2471 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2473 ok( bitmasks[0] != 0, "red mask is not set\n" );
2474 ok( bitmasks[1] != 0, "green mask is not set\n" );
2475 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2476 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2478 /* now with bits and 0 lines */
2479 memset(dibinfo, 0, sizeof(dibinfo_buf));
2480 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2481 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2482 SetLastError(0xdeadbeef);
2483 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2484 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2486 ok( !bitmasks[0], "red mask is set\n" );
2487 ok( !bitmasks[1], "green mask is set\n" );
2488 ok( !bitmasks[2], "blue mask is set\n" );
2489 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2491 memset(bitmasks, 0, 3*sizeof(DWORD));
2492 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2493 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2494 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2496 ok( bitmasks[0] != 0, "red mask is not set\n" );
2497 ok( bitmasks[1] != 0, "green mask is not set\n" );
2498 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2499 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2502 else skip("bitmap in colortable mode, skipping BI_BITFIELDS tests\n");
2504 DeleteObject(hbm);
2506 /* same thing now with a 32-bpp DIB section */
2508 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2509 dibinfo->bmiHeader.biWidth = 1;
2510 dibinfo->bmiHeader.biHeight = 1;
2511 dibinfo->bmiHeader.biPlanes = 1;
2512 dibinfo->bmiHeader.biBitCount = 32;
2513 dibinfo->bmiHeader.biCompression = BI_RGB;
2514 dibinfo->bmiHeader.biSizeImage = 0;
2515 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2516 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2517 dibinfo->bmiHeader.biClrUsed = 0;
2518 dibinfo->bmiHeader.biClrImportant = 0;
2519 bitmasks[0] = 0x0000ff;
2520 bitmasks[1] = 0x00ff00;
2521 bitmasks[2] = 0xff0000;
2522 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2523 ok( hbm != 0, "failed to create bitmap\n" );
2525 memset(dibinfo, 0, sizeof(dibinfo_buf));
2526 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2527 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2528 ok(ret == 1, "GetDIBits failed\n");
2529 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2531 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2532 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2533 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2534 ok( !bitmasks[0], "red mask is set\n" );
2535 ok( !bitmasks[1], "green mask is set\n" );
2536 ok( !bitmasks[2], "blue mask is set\n" );
2538 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2539 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2540 ok(ret == 1, "GetDIBits failed\n");
2541 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2542 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2543 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2544 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2545 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2547 ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
2548 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2549 ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
2551 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2553 DeleteObject(hbm);
2555 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2556 dibinfo->bmiHeader.biWidth = 1;
2557 dibinfo->bmiHeader.biHeight = 1;
2558 dibinfo->bmiHeader.biPlanes = 1;
2559 dibinfo->bmiHeader.biBitCount = 32;
2560 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2561 dibinfo->bmiHeader.biSizeImage = 0;
2562 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2563 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2564 dibinfo->bmiHeader.biClrUsed = 0;
2565 dibinfo->bmiHeader.biClrImportant = 0;
2566 bitmasks[0] = 0x0000ff;
2567 bitmasks[1] = 0x00ff00;
2568 bitmasks[2] = 0xff0000;
2569 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2570 ok( hbm != 0, "failed to create bitmap\n" );
2572 if (hbm)
2574 memset(dibinfo, 0, sizeof(dibinfo_buf));
2575 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2576 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2577 ok(ret == 1, "GetDIBits failed\n");
2579 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
2580 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2581 ok( !bitmasks[0], "red mask is set\n" );
2582 ok( !bitmasks[1], "green mask is set\n" );
2583 ok( !bitmasks[2], "blue mask is set\n" );
2585 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2586 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2587 ok(ret == 1, "GetDIBits failed\n");
2588 ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
2589 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2590 ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
2591 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2593 DeleteObject(hbm);
2596 /* 24-bpp DIB sections don't have bitfields */
2598 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2599 dibinfo->bmiHeader.biWidth = 1;
2600 dibinfo->bmiHeader.biHeight = 1;
2601 dibinfo->bmiHeader.biPlanes = 1;
2602 dibinfo->bmiHeader.biBitCount = 24;
2603 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2604 dibinfo->bmiHeader.biSizeImage = 0;
2605 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2606 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2607 dibinfo->bmiHeader.biClrUsed = 0;
2608 dibinfo->bmiHeader.biClrImportant = 0;
2609 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2610 ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
2611 dibinfo->bmiHeader.biCompression = BI_RGB;
2612 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2613 ok( hbm != 0, "failed to create bitmap\n" );
2615 memset(dibinfo, 0, sizeof(dibinfo_buf));
2616 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2617 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2618 ok(ret == 1, "GetDIBits failed\n");
2619 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2621 ok( dibinfo->bmiHeader.biCompression == BI_RGB,
2622 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2623 ok( !bitmasks[0], "red mask is set\n" );
2624 ok( !bitmasks[1], "green mask is set\n" );
2625 ok( !bitmasks[2], "blue mask is set\n" );
2627 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2628 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2629 ok(ret == 1, "GetDIBits failed\n");
2630 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2631 ok( !bitmasks[0], "red mask is set\n" );
2632 ok( !bitmasks[1], "green mask is set\n" );
2633 ok( !bitmasks[2], "blue mask is set\n" );
2634 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2636 DeleteObject(hbm);
2637 ReleaseDC(NULL, hdc);
2640 static void test_select_object(void)
2642 HDC hdc;
2643 HBITMAP hbm, hbm_old;
2644 INT planes, bpp, i;
2645 DWORD depths[] = {8, 15, 16, 24, 32};
2646 BITMAP bm;
2647 DWORD bytes;
2649 hdc = GetDC(0);
2650 ok(hdc != 0, "GetDC(0) failed\n");
2651 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2652 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2654 hbm_old = SelectObject(hdc, hbm);
2655 ok(hbm_old == 0, "SelectObject should fail\n");
2657 DeleteObject(hbm);
2658 ReleaseDC(0, hdc);
2660 hdc = CreateCompatibleDC(0);
2661 ok(hdc != 0, "GetDC(0) failed\n");
2662 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2663 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2665 hbm_old = SelectObject(hdc, hbm);
2666 ok(hbm_old != 0, "SelectObject failed\n");
2667 hbm_old = SelectObject(hdc, hbm_old);
2668 ok(hbm_old == hbm, "SelectObject failed\n");
2670 DeleteObject(hbm);
2672 /* test an 1-bpp bitmap */
2673 planes = GetDeviceCaps(hdc, PLANES);
2674 bpp = 1;
2676 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
2677 ok(hbm != 0, "CreateBitmap failed\n");
2679 hbm_old = SelectObject(hdc, hbm);
2680 ok(hbm_old != 0, "SelectObject failed\n");
2681 hbm_old = SelectObject(hdc, hbm_old);
2682 ok(hbm_old == hbm, "SelectObject failed\n");
2684 DeleteObject(hbm);
2686 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
2687 /* test a color bitmap to dc bpp matching */
2688 planes = GetDeviceCaps(hdc, PLANES);
2689 bpp = GetDeviceCaps(hdc, BITSPIXEL);
2691 hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
2692 ok(hbm != 0, "CreateBitmap failed\n");
2694 hbm_old = SelectObject(hdc, hbm);
2695 if(depths[i] == bpp ||
2696 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
2698 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
2699 SelectObject(hdc, hbm_old);
2700 } else {
2701 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
2704 memset(&bm, 0xAA, sizeof(bm));
2705 bytes = GetObjectW(hbm, sizeof(bm), &bm);
2706 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2707 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2708 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
2709 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
2710 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2711 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
2712 if(depths[i] == 15) {
2713 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
2714 } else {
2715 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2717 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2719 DeleteObject(hbm);
2722 DeleteDC(hdc);
2725 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
2727 INT ret;
2728 BITMAP bm;
2730 ret = GetObjectType(hbmp);
2731 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
2733 ret = GetObjectW(hbmp, 0, 0);
2734 ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
2736 memset(&bm, 0xDA, sizeof(bm));
2737 SetLastError(0xdeadbeef);
2738 ret = GetObjectW(hbmp, sizeof(bm), &bm);
2739 if (!ret) /* XP, only for curObj2 */ return;
2740 ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
2741 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2742 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2743 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2744 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2745 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2746 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2747 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2750 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2752 static void test_CreateBitmap(void)
2754 BITMAP bmp;
2755 HDC screenDC = GetDC(0);
2756 HDC hdc = CreateCompatibleDC(screenDC);
2757 UINT i, expect = 0;
2759 /* all of these are the stock monochrome bitmap */
2760 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2761 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2762 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2763 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2764 HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2765 HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2767 /* these 2 are not the stock monochrome bitmap */
2768 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2769 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2771 HBITMAP old1 = SelectObject(hdc, bm2);
2772 HBITMAP old2 = SelectObject(screenDC, bm3);
2773 SelectObject(hdc, old1);
2774 SelectObject(screenDC, old2);
2776 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2777 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2778 bm, bm1, bm4, bm5, curObj1, old1);
2779 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2780 todo_wine
2781 ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
2782 ok(old2 == 0, "old2 %p\n", old2);
2784 test_mono_1x1_bmp(bm);
2785 test_mono_1x1_bmp(bm1);
2786 test_mono_1x1_bmp(bm2);
2787 test_mono_1x1_bmp(bm3);
2788 test_mono_1x1_bmp(bm4);
2789 test_mono_1x1_bmp(bm5);
2790 test_mono_1x1_bmp(old1);
2791 test_mono_1x1_bmp(curObj1);
2793 DeleteObject(bm);
2794 DeleteObject(bm1);
2795 DeleteObject(bm2);
2796 DeleteObject(bm3);
2797 DeleteObject(bm4);
2798 DeleteObject(bm5);
2800 DeleteDC(hdc);
2801 ReleaseDC(0, screenDC);
2803 /* show that Windows ignores the provided bm.bmWidthBytes */
2804 bmp.bmType = 0;
2805 bmp.bmWidth = 1;
2806 bmp.bmHeight = 1;
2807 bmp.bmWidthBytes = 28;
2808 bmp.bmPlanes = 1;
2809 bmp.bmBitsPixel = 1;
2810 bmp.bmBits = NULL;
2811 bm = CreateBitmapIndirect(&bmp);
2812 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2813 test_mono_1x1_bmp(bm);
2814 DeleteObject(bm);
2816 /* Test how the bmBitsPixel field is treated */
2817 for(i = 1; i <= 33; i++) {
2818 bmp.bmType = 0;
2819 bmp.bmWidth = 1;
2820 bmp.bmHeight = 1;
2821 bmp.bmWidthBytes = 28;
2822 bmp.bmPlanes = 1;
2823 bmp.bmBitsPixel = i;
2824 bmp.bmBits = NULL;
2825 SetLastError(0xdeadbeef);
2826 bm = CreateBitmapIndirect(&bmp);
2827 if(i > 32) {
2828 DWORD error = GetLastError();
2829 ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
2830 ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2831 DeleteObject(bm);
2832 continue;
2834 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2835 GetObjectW(bm, sizeof(bmp), &bmp);
2836 if(i == 1) {
2837 expect = 1;
2838 } else if(i <= 4) {
2839 expect = 4;
2840 } else if(i <= 8) {
2841 expect = 8;
2842 } else if(i <= 16) {
2843 expect = 16;
2844 } else if(i <= 24) {
2845 expect = 24;
2846 } else if(i <= 32) {
2847 expect = 32;
2849 ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2850 i, bmp.bmBitsPixel, expect);
2851 DeleteObject(bm);
2855 static void test_bitmapinfoheadersize(void)
2857 HBITMAP hdib;
2858 BITMAPINFO bmi;
2859 BITMAPCOREINFO bci;
2860 HDC hdc = GetDC(0);
2862 memset(&bmi, 0, sizeof(BITMAPINFO));
2863 bmi.bmiHeader.biHeight = 100;
2864 bmi.bmiHeader.biWidth = 512;
2865 bmi.bmiHeader.biBitCount = 24;
2866 bmi.bmiHeader.biPlanes = 1;
2868 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2870 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2871 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2873 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2875 SetLastError(0xdeadbeef);
2876 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2877 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2878 DeleteObject(hdib);
2880 bmi.bmiHeader.biSize++;
2882 SetLastError(0xdeadbeef);
2883 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2884 ok(hdib != NULL ||
2885 broken(!hdib), /* Win98, WinMe */
2886 "CreateDIBSection error %d\n", GetLastError());
2887 DeleteObject(hdib);
2889 bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2891 SetLastError(0xdeadbeef);
2892 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2893 ok(hdib != NULL ||
2894 broken(!hdib), /* Win98, WinMe */
2895 "CreateDIBSection error %d\n", GetLastError());
2896 DeleteObject(hdib);
2898 bmi.bmiHeader.biSize++;
2900 SetLastError(0xdeadbeef);
2901 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2902 ok(hdib != NULL ||
2903 broken(!hdib), /* Win98, WinMe */
2904 "CreateDIBSection error %d\n", GetLastError());
2905 DeleteObject(hdib);
2907 bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2909 SetLastError(0xdeadbeef);
2910 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2911 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2912 DeleteObject(hdib);
2914 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2916 SetLastError(0xdeadbeef);
2917 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2918 ok(hdib != NULL ||
2919 broken(!hdib), /* Win95 */
2920 "CreateDIBSection error %d\n", GetLastError());
2921 DeleteObject(hdib);
2923 memset(&bci, 0, sizeof(BITMAPCOREINFO));
2924 bci.bmciHeader.bcHeight = 100;
2925 bci.bmciHeader.bcWidth = 512;
2926 bci.bmciHeader.bcBitCount = 24;
2927 bci.bmciHeader.bcPlanes = 1;
2929 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2931 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2932 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2934 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2936 SetLastError(0xdeadbeef);
2937 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2938 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2939 DeleteObject(hdib);
2941 bci.bmciHeader.bcSize++;
2943 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2944 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2946 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2948 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2949 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2951 ReleaseDC(0, hdc);
2954 static void test_get16dibits(void)
2956 BYTE bits[4 * (16 / sizeof(BYTE))];
2957 HBITMAP hbmp;
2958 HDC screen_dc = GetDC(NULL);
2959 int ret;
2960 BITMAPINFO * info;
2961 int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2962 BYTE *p;
2963 int overwritten_bytes = 0;
2965 memset(bits, 0, sizeof(bits));
2966 hbmp = CreateBitmap(2, 2, 1, 16, bits);
2967 ok(hbmp != NULL, "CreateBitmap failed\n");
2969 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2970 assert(info);
2972 memset(info, '!', info_len);
2973 memset(info, 0, sizeof(info->bmiHeader));
2975 info->bmiHeader.biSize = sizeof(info->bmiHeader);
2976 info->bmiHeader.biWidth = 2;
2977 info->bmiHeader.biHeight = 2;
2978 info->bmiHeader.biPlanes = 1;
2979 info->bmiHeader.biCompression = BI_RGB;
2981 ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2982 ok(ret != 0, "GetDIBits failed got %d\n", ret);
2984 for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2985 if (*p != '!')
2986 overwritten_bytes++;
2987 ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2989 HeapFree(GetProcessHeap(), 0, info);
2990 DeleteObject(hbmp);
2991 ReleaseDC(NULL, screen_dc);
2994 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2995 DWORD dwRop, UINT32 expected, int line)
2997 *srcBuffer = 0xFEDCBA98;
2998 *dstBuffer = 0x89ABCDEF;
2999 BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
3000 ok(expected == *dstBuffer,
3001 "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
3002 dwRop, expected, *dstBuffer, line);
3005 static void test_BitBlt(void)
3007 HBITMAP bmpDst, bmpSrc;
3008 HBITMAP oldDst, oldSrc;
3009 HDC hdcScreen, hdcDst, hdcSrc;
3010 UINT32 *dstBuffer, *srcBuffer;
3011 HBRUSH hBrush, hOldBrush;
3012 BITMAPINFO bitmapInfo;
3014 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3015 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3016 bitmapInfo.bmiHeader.biWidth = 1;
3017 bitmapInfo.bmiHeader.biHeight = 1;
3018 bitmapInfo.bmiHeader.biPlanes = 1;
3019 bitmapInfo.bmiHeader.biBitCount = 32;
3020 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3021 bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
3023 hdcScreen = CreateCompatibleDC(0);
3024 hdcDst = CreateCompatibleDC(hdcScreen);
3025 hdcSrc = CreateCompatibleDC(hdcDst);
3027 /* Setup the destination dib section */
3028 bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
3029 NULL, 0);
3030 oldDst = SelectObject(hdcDst, bmpDst);
3032 hBrush = CreateSolidBrush(0x12345678);
3033 hOldBrush = SelectObject(hdcDst, hBrush);
3035 /* Setup the source dib section */
3036 bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
3037 NULL, 0);
3038 oldSrc = SelectObject(hdcSrc, bmpSrc);
3040 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3041 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3042 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3043 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3044 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3045 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3046 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3047 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3048 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3049 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3050 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3051 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3052 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3053 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3054 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3056 /* Tidy up */
3057 SelectObject(hdcSrc, oldSrc);
3058 DeleteObject(bmpSrc);
3059 DeleteDC(hdcSrc);
3061 SelectObject(hdcDst, hOldBrush);
3062 DeleteObject(hBrush);
3063 SelectObject(hdcDst, oldDst);
3064 DeleteObject(bmpDst);
3065 DeleteDC(hdcDst);
3068 DeleteDC(hdcScreen);
3071 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
3072 DWORD dwRop, UINT32 expected, int line)
3074 *srcBuffer = 0xFEDCBA98;
3075 *dstBuffer = 0x89ABCDEF;
3076 StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
3077 ok(expected == *dstBuffer,
3078 "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
3079 dwRop, expected, *dstBuffer, line);
3082 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, BITMAPINFO *dst_info, UINT32 *dstBuffer, UINT32 *srcBuffer,
3083 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
3084 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
3085 UINT32 *expected, int line)
3087 int dst_size = get_dib_image_size( dst_info );
3089 memset(dstBuffer, 0, dst_size);
3090 StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
3091 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
3092 ok(memcmp(dstBuffer, expected, dst_size) == 0,
3093 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
3094 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
3095 expected[0], expected[1], expected[2], expected[3],
3096 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
3097 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3098 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
3101 static void test_StretchBlt(void)
3103 HBITMAP bmpDst, bmpSrc;
3104 HBITMAP oldDst, oldSrc;
3105 HDC hdcScreen, hdcDst, hdcSrc;
3106 UINT32 *dstBuffer, *srcBuffer;
3107 HBRUSH hBrush, hOldBrush;
3108 BITMAPINFO biDst, biSrc;
3109 UINT32 expected[256];
3110 RGBQUAD colors[2];
3112 memset(&biDst, 0, sizeof(BITMAPINFO));
3113 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3114 biDst.bmiHeader.biWidth = 16;
3115 biDst.bmiHeader.biHeight = -16;
3116 biDst.bmiHeader.biPlanes = 1;
3117 biDst.bmiHeader.biBitCount = 32;
3118 biDst.bmiHeader.biCompression = BI_RGB;
3119 memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
3121 hdcScreen = CreateCompatibleDC(0);
3122 hdcDst = CreateCompatibleDC(hdcScreen);
3123 hdcSrc = CreateCompatibleDC(hdcDst);
3125 /* Pixel Tests */
3126 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3127 NULL, 0);
3128 oldDst = SelectObject(hdcDst, bmpDst);
3130 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
3131 NULL, 0);
3132 oldSrc = SelectObject(hdcSrc, bmpSrc);
3134 hBrush = CreateSolidBrush(0x012345678);
3135 hOldBrush = SelectObject(hdcDst, hBrush);
3137 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3138 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3139 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3140 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3141 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3142 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3143 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3144 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3145 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3146 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3147 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3148 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3149 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3150 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3151 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3153 SelectObject(hdcDst, hOldBrush);
3154 DeleteObject(hBrush);
3156 /* Top-down to top-down tests */
3157 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3158 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
3160 memset( expected, 0, get_dib_image_size( &biDst ) );
3161 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
3162 expected[16] = 0xFEDCBA98, expected[17] = 0x76543210;
3163 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3164 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3166 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3167 expected[16] = 0x00000000, expected[17] = 0x00000000;
3168 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3169 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
3171 expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
3172 expected[16] = 0xCAFED00D, expected[17] = 0xCAFED00D;
3173 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3174 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
3176 /* This is an example of the dst width (height) == 1 exception, explored below */
3177 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3178 expected[16] = 0x00000000, expected[17] = 0x00000000;
3179 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3180 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
3182 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
3183 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
3184 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3185 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3187 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
3188 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
3189 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3190 1, 1, -2, -2, 0, 0, 2, 2, expected, __LINE__);
3192 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3193 expected[16] = 0x00000000, expected[17] = 0x00000000;
3194 todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3195 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
3197 expected[0] = 0x00000000, expected[1] = 0x00000000;
3198 expected[16] = 0x00000000, expected[17] = 0xCAFED00D, expected[18] = 0xFEEDFACE;
3199 expected[32] = 0x00000000, expected[33] = 0xFEDCBA98, expected[34] = 0x76543210;
3201 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3202 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3204 /* when dst width is 1 merge src width - 1 pixels */
3205 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
3206 srcBuffer[0] = 0x0000ff00, srcBuffer[1] = 0x0000f0f0, srcBuffer[2] = 0x0000cccc, srcBuffer[3] = 0x0000aaaa;
3207 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
3209 memset( expected, 0, get_dib_image_size( &biDst ) );
3210 expected[0] = srcBuffer[0];
3211 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3212 0, 0, 1, 1, 0, 0, 2, 1, expected, __LINE__);
3214 expected[0] = srcBuffer[0] & srcBuffer[1];
3215 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3216 0, 0, 1, 1, 0, 0, 3, 1, expected, __LINE__);
3218 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
3219 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3220 0, 0, 1, 1, 0, 0, 4, 1, expected, __LINE__);
3222 /* this doesn't happen if the src width is -ve */
3223 expected[0] = srcBuffer[1] & srcBuffer[2];
3224 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3225 0, 0, 1, 1, 2, 0, -2, 1, expected, __LINE__);
3227 /* when dst width > 1 behaviour reverts to what one would expect */
3228 expected[0] = srcBuffer[0] & srcBuffer[1], expected[1] = srcBuffer[2] & srcBuffer[3];
3229 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3230 0, 0, 2, 1, 0, 0, 4, 1, expected, __LINE__);
3232 /* similarly in the vertical direction */
3233 memset( expected, 0, get_dib_image_size( &biDst ) );
3234 expected[0] = srcBuffer[0];
3235 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3236 0, 0, 1, 1, 0, 0, 1, 2, expected, __LINE__);
3238 /* check that it's the dst size in device units that needs to be 1 */
3239 SetMapMode( hdcDst, MM_ISOTROPIC );
3240 SetWindowExtEx( hdcDst, 200, 200, NULL );
3241 SetViewportExtEx( hdcDst, 100, 100, NULL );
3243 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
3244 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3245 0, 0, 2, 2, 0, 0, 4, 1, expected, __LINE__);
3246 SetMapMode( hdcDst, MM_TEXT );
3248 SelectObject(hdcDst, oldDst);
3249 DeleteObject(bmpDst);
3251 /* Top-down to bottom-up tests */
3252 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
3253 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3254 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
3256 biDst.bmiHeader.biHeight = 16;
3257 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3258 NULL, 0);
3259 oldDst = SelectObject(hdcDst, bmpDst);
3261 memset( expected, 0, get_dib_image_size( &biDst ) );
3263 expected[224] = 0xFEDCBA98, expected[225] = 0x76543210;
3264 expected[240] = 0xCAFED00D, expected[241] = 0xFEEDFACE;
3265 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3266 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3268 expected[224] = 0xFEEDFACE, expected[225] = 0xCAFED00D;
3269 expected[240] = 0x76543210, expected[241] = 0xFEDCBA98;
3270 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3271 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3273 SelectObject(hdcSrc, oldSrc);
3274 DeleteObject(bmpSrc);
3276 /* Bottom-up to bottom-up tests */
3277 biSrc.bmiHeader.biHeight = 16;
3278 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
3279 NULL, 0);
3280 srcBuffer[224] = 0xCAFED00D, srcBuffer[225] = 0xFEEDFACE;
3281 srcBuffer[240] = 0xFEDCBA98, srcBuffer[241] = 0x76543210;
3282 oldSrc = SelectObject(hdcSrc, bmpSrc);
3284 memset( expected, 0, get_dib_image_size( &biDst ) );
3286 expected[224] = 0xCAFED00D, expected[225] = 0xFEEDFACE;
3287 expected[240] = 0xFEDCBA98, expected[241] = 0x76543210;
3288 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3289 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3291 expected[224] = 0x76543210, expected[225] = 0xFEDCBA98;
3292 expected[240] = 0xFEEDFACE, expected[241] = 0xCAFED00D;
3293 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3294 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3296 SelectObject(hdcDst, oldDst);
3297 DeleteObject(bmpDst);
3299 /* Bottom-up to top-down tests */
3300 biDst.bmiHeader.biHeight = -16;
3301 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3302 NULL, 0);
3303 oldDst = SelectObject(hdcDst, bmpDst);
3305 memset( expected, 0, get_dib_image_size( &biDst ) );
3306 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3307 expected[16] = 0xCAFED00D, expected[17] = 0xFEEDFACE;
3308 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3309 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3311 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3312 expected[16] = 0x76543210, expected[17] = 0xFEDCBA98;
3313 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3314 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3316 SelectObject(hdcSrc, oldSrc);
3317 DeleteObject(bmpSrc);
3319 biSrc.bmiHeader.biHeight = -2;
3320 biSrc.bmiHeader.biBitCount = 24;
3321 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
3322 oldSrc = SelectObject(hdcSrc, bmpSrc);
3324 memset( expected, 0, get_dib_image_size( &biDst ) );
3325 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3326 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
3327 memcpy(dstBuffer, expected, 4 * sizeof(*dstBuffer));
3328 StretchBlt(hdcSrc, 0, 0, 4, 1, hdcDst, 0, 0, 4, 1, SRCCOPY );
3329 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
3330 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3331 expected[0] = 0x00EDFACE, expected[1] = 0x00FED00D;
3332 expected[2] = 0x00543210, expected[3] = 0x00DCBA98;
3333 ok(!memcmp(dstBuffer, expected, 16),
3334 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3335 expected[0], expected[1], expected[2], expected[3],
3336 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3338 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3339 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
3340 memcpy(srcBuffer, expected, 4 * sizeof(*dstBuffer));
3341 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
3342 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3343 expected[0] = 0x00EDFACE, expected[1] = 0x00D00DFE;
3344 expected[2] = 0x0010CAFE, expected[3] = 0x00765432;
3345 ok(!memcmp(dstBuffer, expected, 16),
3346 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3347 expected[0], expected[1], expected[2], expected[3],
3348 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3350 SelectObject(hdcSrc, oldSrc);
3351 DeleteObject(bmpSrc);
3353 biSrc.bmiHeader.biBitCount = 1;
3354 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
3355 oldSrc = SelectObject(hdcSrc, bmpSrc);
3356 *((DWORD *)colors + 0) = 0x123456;
3357 *((DWORD *)colors + 1) = 0x335577;
3358 SetDIBColorTable( hdcSrc, 0, 2, colors );
3359 srcBuffer[0] = 0x55555555;
3360 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
3361 SetTextColor( hdcDst, 0 );
3362 SetBkColor( hdcDst, 0 );
3363 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3364 expected[0] = expected[2] = 0x00123456;
3365 expected[1] = expected[3] = 0x00335577;
3366 ok(!memcmp(dstBuffer, expected, 16),
3367 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3368 expected[0], expected[1], expected[2], expected[3],
3369 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3371 SelectObject(hdcSrc, oldSrc);
3372 DeleteObject(bmpSrc);
3374 bmpSrc = CreateBitmap( 16, 16, 1, 1, 0 );
3375 oldSrc = SelectObject(hdcSrc, bmpSrc);
3376 SetPixel( hdcSrc, 0, 0, 0 );
3377 SetPixel( hdcSrc, 1, 0, 0xffffff );
3378 SetPixel( hdcSrc, 2, 0, 0xffffff );
3379 SetPixel( hdcSrc, 3, 0, 0 );
3380 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
3381 SetTextColor( hdcDst, RGB(0x22,0x44,0x66) );
3382 SetBkColor( hdcDst, RGB(0x65,0x43,0x21) );
3383 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3384 expected[0] = expected[3] = 0x00224466;
3385 expected[1] = expected[2] = 0x00654321;
3386 ok(!memcmp(dstBuffer, expected, 16),
3387 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3388 expected[0], expected[1], expected[2], expected[3],
3389 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3391 SelectObject(hdcSrc, oldSrc);
3392 DeleteObject(bmpSrc);
3394 DeleteDC(hdcSrc);
3396 SelectObject(hdcDst, oldDst);
3397 DeleteObject(bmpDst);
3398 DeleteDC(hdcDst);
3400 DeleteDC(hdcScreen);
3403 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3404 DWORD dwRop, UINT32 expected, int line)
3406 const UINT32 buffer[2] = { 0xFEDCBA98, 0 };
3407 BITMAPINFO bitmapInfo;
3409 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3410 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3411 bitmapInfo.bmiHeader.biWidth = 2;
3412 bitmapInfo.bmiHeader.biHeight = 1;
3413 bitmapInfo.bmiHeader.biPlanes = 1;
3414 bitmapInfo.bmiHeader.biBitCount = 32;
3415 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3416 bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer);
3418 *dstBuffer = 0x89ABCDEF;
3420 StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop);
3421 ok(expected == *dstBuffer,
3422 "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
3423 dwRop, expected, *dstBuffer, line);
3426 static INT check_StretchDIBits_stretch( HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3427 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
3428 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
3429 UINT32 expected[4], int line)
3431 BITMAPINFO bitmapInfo;
3432 INT ret;
3434 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3435 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3436 bitmapInfo.bmiHeader.biWidth = 2;
3437 bitmapInfo.bmiHeader.biHeight = -2;
3438 bitmapInfo.bmiHeader.biPlanes = 1;
3439 bitmapInfo.bmiHeader.biBitCount = 32;
3440 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3442 memset(dstBuffer, 0, 16);
3443 ret = StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
3444 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3445 srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
3446 ok(memcmp(dstBuffer, expected, 16) == 0,
3447 "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
3448 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
3449 expected[0], expected[1], expected[2], expected[3],
3450 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
3451 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3452 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
3453 return ret;
3456 static void test_StretchDIBits(void)
3458 HBITMAP bmpDst;
3459 HBITMAP oldDst;
3460 HDC hdcScreen, hdcDst;
3461 UINT32 *dstBuffer, srcBuffer[4];
3462 HBRUSH hBrush, hOldBrush;
3463 BITMAPINFO biDst;
3464 UINT32 expected[4];
3465 INT ret;
3467 memset(&biDst, 0, sizeof(BITMAPINFO));
3468 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3469 biDst.bmiHeader.biWidth = 2;
3470 biDst.bmiHeader.biHeight = -2;
3471 biDst.bmiHeader.biPlanes = 1;
3472 biDst.bmiHeader.biBitCount = 32;
3473 biDst.bmiHeader.biCompression = BI_RGB;
3475 hdcScreen = CreateCompatibleDC(0);
3476 hdcDst = CreateCompatibleDC(hdcScreen);
3478 /* Pixel Tests */
3479 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3480 NULL, 0);
3481 oldDst = SelectObject(hdcDst, bmpDst);
3483 hBrush = CreateSolidBrush(0x012345678);
3484 hOldBrush = SelectObject(hdcDst, hBrush);
3486 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3487 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3488 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3489 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3490 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3491 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3492 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3493 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3494 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3495 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3496 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3497 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3498 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3499 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3500 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3502 SelectObject(hdcDst, hOldBrush);
3503 DeleteObject(hBrush);
3505 /* Top-down destination tests */
3506 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3507 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
3509 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
3510 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
3511 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3512 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3513 ok( ret == 2, "got ret %d\n", ret );
3515 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3516 expected[2] = 0x00000000, expected[3] = 0x00000000;
3517 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3518 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
3519 todo_wine ok( ret == 1, "got ret %d\n", ret );
3521 expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
3522 expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
3523 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3524 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
3525 ok( ret == 2, "got ret %d\n", ret );
3527 expected[0] = 0x42441000, expected[1] = 0x00000000;
3528 expected[2] = 0x00000000, expected[3] = 0x00000000;
3529 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3530 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
3531 ok( ret == 2, "got ret %d\n", ret );
3533 expected[0] = 0x00000000, expected[1] = 0x00000000;
3534 expected[2] = 0x00000000, expected[3] = 0x00000000;
3535 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3536 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3537 ok( ret == 0, "got ret %d\n", ret );
3539 expected[0] = 0x00000000, expected[1] = 0x00000000;
3540 expected[2] = 0x00000000, expected[3] = 0x00000000;
3541 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3542 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3543 ok( ret == 0, "got ret %d\n", ret );
3545 expected[0] = 0x00000000, expected[1] = 0x00000000;
3546 expected[2] = 0x00000000, expected[3] = 0x00000000;
3547 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3548 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
3549 ok( ret == 0, "got ret %d\n", ret );
3551 expected[0] = 0x00000000, expected[1] = 0x00000000;
3552 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
3553 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3554 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3555 ok( ret == 2, "got ret %d\n", ret );
3557 expected[0] = 0x00000000, expected[1] = 0x00000000;
3558 expected[2] = 0x00000000, expected[3] = 0x00000000;
3559 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3560 2, 2, 4, 4, 0, 0, 2, 2, expected, __LINE__);
3561 ok( ret == 2, "got ret %d\n", ret );
3563 expected[0] = 0x00000000, expected[1] = 0x00000000;
3564 expected[2] = 0x00000000, expected[3] = 0x00000000;
3565 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3566 -4, -4, 4, 4, 0, 0, 4, 4, expected, __LINE__);
3567 ok( ret == 2, "got ret %d\n", ret );
3569 SelectObject(hdcDst, oldDst);
3570 DeleteObject(bmpDst);
3572 /* Bottom up destination tests */
3573 biDst.bmiHeader.biHeight = 2;
3574 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3575 NULL, 0);
3576 oldDst = SelectObject(hdcDst, bmpDst);
3578 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3579 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
3580 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3581 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3583 /* Tidy up */
3584 SelectObject(hdcDst, oldDst);
3585 DeleteObject(bmpDst);
3586 DeleteDC(hdcDst);
3588 DeleteDC(hdcScreen);
3591 static void test_GdiAlphaBlend(void)
3593 HDC hdcNull;
3594 HDC hdcDst;
3595 HBITMAP bmpDst;
3596 BITMAPINFO *bmi;
3597 HDC hdcSrc;
3598 HBITMAP bmpSrc;
3599 HBITMAP oldSrc;
3600 LPVOID bits;
3601 BOOL ret;
3602 BLENDFUNCTION blend;
3604 if (!pGdiAlphaBlend)
3606 win_skip("GdiAlphaBlend() is not implemented\n");
3607 return;
3610 hdcNull = GetDC(NULL);
3611 hdcDst = CreateCompatibleDC(hdcNull);
3612 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
3613 hdcSrc = CreateCompatibleDC(hdcNull);
3615 bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3616 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3617 bmi->bmiHeader.biHeight = 20;
3618 bmi->bmiHeader.biWidth = 20;
3619 bmi->bmiHeader.biBitCount = 32;
3620 bmi->bmiHeader.biPlanes = 1;
3621 bmi->bmiHeader.biCompression = BI_RGB;
3622 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3623 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3625 SelectObject(hdcDst, bmpDst);
3626 oldSrc = SelectObject(hdcSrc, bmpSrc);
3628 blend.BlendOp = AC_SRC_OVER;
3629 blend.BlendFlags = 0;
3630 blend.SourceConstantAlpha = 128;
3631 blend.AlphaFormat = 0;
3633 SetLastError(0xdeadbeef);
3634 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3635 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3637 SetLastError(0xdeadbeef);
3638 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3639 ok( !ret, "GdiAlphaBlend succeeded\n" );
3640 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3642 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3643 ok( !ret, "GdiAlphaBlend succeeded\n" );
3644 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend);
3645 ok( !ret, "GdiAlphaBlend succeeded\n" );
3646 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3647 ok( !ret, "GdiAlphaBlend succeeded\n" );
3648 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3649 ok( !ret, "GdiAlphaBlend succeeded\n" );
3651 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
3652 SetLastError(0xdeadbeef);
3653 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3654 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3655 SetLastError(0xdeadbeef);
3656 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3657 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3658 SetMapMode(hdcSrc, MM_ANISOTROPIC);
3659 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
3660 SetLastError(0xdeadbeef);
3661 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend);
3662 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3663 SetLastError(0xdeadbeef);
3664 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend);
3665 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3667 SetMapMode(hdcDst, MM_ANISOTROPIC);
3668 SetViewportExtEx(hdcDst, -1, -1, NULL);
3669 SetLastError(0xdeadbeef);
3670 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 50, 50, blend);
3671 todo_wine
3672 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3673 SetLastError(0xdeadbeef);
3674 ret = pGdiAlphaBlend(hdcDst, -20, -20, 20, 20, hdcSrc, 0, -1, 50, 50, blend);
3675 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3676 SetLastError(0xdeadbeef);
3677 ret = pGdiAlphaBlend(hdcDst, -20, -20, -20, -20, hdcSrc, 0, -1, 50, 50, blend);
3678 ok( !ret, "GdiAlphaBlend succeeded\n" );
3679 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3680 SetLastError(0xdeadbeef);
3681 ret = pGdiAlphaBlend(hdcDst, -20, 0, -20, 20, hdcSrc, 0, -1, 50, 50, blend);
3682 ok( !ret, "GdiAlphaBlend succeeded\n" );
3683 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3684 SetLastError(0xdeadbeef);
3685 ret = pGdiAlphaBlend(hdcDst, 0, -20, 20, -20, hdcSrc, 0, -1, 50, 50, blend);
3686 ok( !ret, "GdiAlphaBlend succeeded\n" );
3687 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3688 SetMapMode(hdcDst, MM_TEXT);
3690 SetViewportExtEx(hdcSrc, -1, -1, NULL);
3691 SetLastError(0xdeadbeef);
3692 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, -30, -30, blend);
3693 ok( !ret, "GdiAlphaBlend succeeded\n" );
3694 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3695 SetLastError(0xdeadbeef);
3696 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, 30, -30, blend);
3697 ok( !ret, "GdiAlphaBlend succeeded\n" );
3698 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3699 SetLastError(0xdeadbeef);
3700 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, -30, 30, blend);
3701 ok( !ret, "GdiAlphaBlend succeeded\n" );
3702 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3703 SetLastError(0xdeadbeef);
3704 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, 30, 30, blend);
3705 ok( !ret, "GdiAlphaBlend succeeded\n" );
3706 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3707 SetLastError(0xdeadbeef);
3708 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 20, 20, 30, 30, blend);
3709 ok( !ret, "GdiAlphaBlend succeeded\n" );
3710 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3711 SetLastError(0xdeadbeef);
3712 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -60, -60, 30, 30, blend);
3713 ok( !ret, "GdiAlphaBlend succeeded\n" );
3714 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3715 SetViewportExtEx(hdcSrc, 1, 1, NULL);
3717 SetLastError(0xdeadbeef);
3718 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend);
3719 ok( !ret, "GdiAlphaBlend succeeded\n" );
3720 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3722 /* overlapping source and dest not allowed */
3724 SetLastError(0xdeadbeef);
3725 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 19, 19, 20, 20, blend);
3726 ok( !ret, "GdiAlphaBlend succeeded\n" );
3727 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3729 SetLastError(0xdeadbeef);
3730 ret = pGdiAlphaBlend(hdcDst, 20, 20, 20, 20, hdcDst, 1, 1, 20, 20, blend);
3731 ok( !ret, "GdiAlphaBlend succeeded\n" );
3732 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3734 SetLastError(0xdeadbeef);
3735 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 20, 10, 20, 20, blend);
3736 ok( ret, "GdiAlphaBlend succeeded\n" );
3737 SetLastError(0xdeadbeef);
3738 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 10, 20, 20, 20, blend);
3739 ok( ret, "GdiAlphaBlend succeeded\n" );
3741 /* AC_SRC_ALPHA requires 32-bpp BI_RGB format */
3743 blend.AlphaFormat = AC_SRC_ALPHA;
3744 SetLastError(0xdeadbeef);
3745 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3746 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3748 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3749 ((DWORD *)bmi->bmiColors)[0] = 0xff0000;
3750 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3751 ((DWORD *)bmi->bmiColors)[2] = 0x0000ff;
3752 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3753 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3754 oldSrc = SelectObject(hdcSrc, bmpSrc);
3755 DeleteObject( oldSrc );
3757 SetLastError(0xdeadbeef);
3758 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3759 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3761 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3762 ((DWORD *)bmi->bmiColors)[0] = 0x0000ff;
3763 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3764 ((DWORD *)bmi->bmiColors)[2] = 0xff0000;
3765 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3766 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3767 oldSrc = SelectObject(hdcSrc, bmpSrc);
3768 DeleteObject( oldSrc );
3770 SetLastError(0xdeadbeef);
3771 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3772 ok( !ret, "GdiAlphaBlend succeeded\n" );
3773 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3775 bmi->bmiHeader.biBitCount = 24;
3776 bmi->bmiHeader.biCompression = BI_RGB;
3777 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3778 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3779 oldSrc = SelectObject(hdcSrc, bmpSrc);
3780 DeleteObject( oldSrc );
3782 SetLastError(0xdeadbeef);
3783 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3784 ok( !ret, "GdiAlphaBlend succeeded\n" );
3785 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3787 bmi->bmiHeader.biBitCount = 1;
3788 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3789 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3790 oldSrc = SelectObject(hdcSrc, bmpSrc);
3791 DeleteObject( oldSrc );
3793 SetLastError(0xdeadbeef);
3794 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3795 ok( !ret, "GdiAlphaBlend succeeded\n" );
3796 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3798 bmpSrc = CreateBitmap( 100, 100, 1, 1, NULL );
3799 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3800 oldSrc = SelectObject(hdcSrc, bmpSrc);
3801 DeleteObject( oldSrc );
3803 SetLastError(0xdeadbeef);
3804 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3805 ok( !ret, "GdiAlphaBlend succeeded\n" );
3806 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3808 DeleteDC(hdcDst);
3809 DeleteDC(hdcSrc);
3810 DeleteObject(bmpSrc);
3811 DeleteObject(bmpDst);
3813 ReleaseDC(NULL, hdcNull);
3814 HeapFree(GetProcessHeap(), 0, bmi);
3817 static void test_GdiGradientFill(void)
3819 HDC hdc;
3820 BOOL ret;
3821 HBITMAP bmp;
3822 BITMAPINFO *bmi;
3823 void *bits;
3824 GRADIENT_RECT rect[] = { { 0, 0 }, { 0, 1 }, { 2, 3 } };
3825 GRADIENT_TRIANGLE tri[] = { { 0, 0, 0 }, { 0, 1, 2 }, { 0, 2, 1 }, { 0, 1, 3 } };
3826 TRIVERTEX vt[3] = { { 2, 2, 0xff00, 0x0000, 0x0000, 0x8000 },
3827 { 10, 10, 0x0000, 0xff00, 0x0000, 0x8000 },
3828 { 20, 10, 0x0000, 0x0000, 0xff00, 0xff00 } };
3830 if (!pGdiGradientFill)
3832 win_skip( "GdiGradientFill is not implemented\n" );
3833 return;
3836 hdc = CreateCompatibleDC( NULL );
3837 bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3838 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3839 bmi->bmiHeader.biHeight = 20;
3840 bmi->bmiHeader.biWidth = 20;
3841 bmi->bmiHeader.biBitCount = 32;
3842 bmi->bmiHeader.biPlanes = 1;
3843 bmi->bmiHeader.biCompression = BI_RGB;
3844 bmp = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3845 ok( bmp != NULL, "couldn't create bitmap\n" );
3846 SelectObject( hdc, bmp );
3848 SetLastError( 0xdeadbeef );
3849 ret = pGdiGradientFill( hdc, vt, 3, rect, 1, GRADIENT_FILL_RECT_H );
3850 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3851 SetLastError( 0xdeadbeef );
3852 ret = pGdiGradientFill( hdc, vt, 3, rect, 1, 3 );
3853 ok( !ret, "GdiGradientFill succeeded\n" );
3854 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3855 SetLastError( 0xdeadbeef );
3856 ret = pGdiGradientFill( (HDC)0xdead, vt, 3, rect, 1, GRADIENT_FILL_RECT_H );
3857 ok( !ret, "GdiGradientFill succeeded\n" );
3858 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3859 SetLastError( 0xdeadbeef );
3860 ret = pGdiGradientFill( NULL, NULL, 0, rect, 1, GRADIENT_FILL_RECT_H );
3861 ok( !ret, "GdiGradientFill succeeded\n" );
3862 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3863 ret = pGdiGradientFill( hdc, NULL, 0, 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( hdc, NULL, 3, rect, 1, GRADIENT_FILL_RECT_H );
3868 ok( !ret, "GdiGradientFill succeeded\n" );
3869 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3870 SetLastError( 0xdeadbeef );
3871 ret = pGdiGradientFill( hdc, vt, 3, NULL, 0, GRADIENT_FILL_RECT_H );
3872 ok( !ret, "GdiGradientFill succeeded\n" );
3873 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3874 SetLastError( 0xdeadbeef );
3875 ret = pGdiGradientFill( hdc, vt, 3, NULL, 1, GRADIENT_FILL_RECT_H );
3876 ok( !ret, "GdiGradientFill succeeded\n" );
3877 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3878 SetLastError( 0xdeadbeef );
3879 ret = pGdiGradientFill( hdc, vt, 3, rect, 0, GRADIENT_FILL_RECT_H );
3880 ok( !ret, "GdiGradientFill succeeded\n" );
3881 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3882 SetLastError( 0xdeadbeef );
3883 ret = pGdiGradientFill( hdc, vt, 3, rect, 3, GRADIENT_FILL_RECT_H );
3884 ok( !ret, "GdiGradientFill succeeded\n" );
3885 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3886 rect[2].UpperLeft = rect[2].LowerRight = 1;
3887 SetLastError( 0xdeadbeef );
3888 ret = pGdiGradientFill( hdc, vt, 3, rect, 3, GRADIENT_FILL_RECT_H );
3889 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3890 SetLastError( 0xdeadbeef );
3891 ret = pGdiGradientFill( hdc, vt, 1, rect, 1, GRADIENT_FILL_RECT_H );
3892 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3893 SetLastError( 0xdeadbeef );
3894 ret = pGdiGradientFill( hdc, vt, 1, tri, 0, GRADIENT_FILL_TRIANGLE );
3895 ok( !ret, "GdiGradientFill succeeded\n" );
3896 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3897 SetLastError( 0xdeadbeef );
3898 ret = pGdiGradientFill( hdc, vt, 1, tri, 1, GRADIENT_FILL_TRIANGLE );
3899 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3900 SetLastError( 0xdeadbeef );
3901 ret = pGdiGradientFill( hdc, vt, 3, tri, 2, GRADIENT_FILL_TRIANGLE );
3902 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3903 SetLastError( 0xdeadbeef );
3904 ret = pGdiGradientFill( hdc, vt, 3, tri, 3, GRADIENT_FILL_TRIANGLE );
3905 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3906 SetLastError( 0xdeadbeef );
3907 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3908 ok( !ret, "GdiGradientFill succeeded\n" );
3909 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3910 tri[3].Vertex3 = 1;
3911 SetLastError( 0xdeadbeef );
3912 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3913 ok( !ret, "GdiGradientFill succeeded\n" );
3914 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3915 tri[3].Vertex3 = 0;
3916 SetLastError( 0xdeadbeef );
3917 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3918 ok( !ret, "GdiGradientFill succeeded\n" );
3919 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3920 tri[3].Vertex1 = tri[3].Vertex2 = tri[3].Vertex3 = 1;
3921 SetLastError( 0xdeadbeef );
3922 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3923 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3925 DeleteDC( hdc );
3926 DeleteObject( bmp );
3927 HeapFree(GetProcessHeap(), 0, bmi);
3930 static void test_clipping(void)
3932 HBITMAP bmpDst;
3933 HBITMAP bmpSrc;
3934 HRGN hRgn;
3935 LPVOID bits;
3936 BOOL result;
3938 HDC hdcDst = CreateCompatibleDC( NULL );
3939 HDC hdcSrc = CreateCompatibleDC( NULL );
3941 BITMAPINFO bmpinfo={{0}};
3942 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3943 bmpinfo.bmiHeader.biWidth = 100;
3944 bmpinfo.bmiHeader.biHeight = 100;
3945 bmpinfo.bmiHeader.biPlanes = 1;
3946 bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3947 bmpinfo.bmiHeader.biCompression = BI_RGB;
3949 bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3950 ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3951 SelectObject( hdcDst, bmpDst );
3953 bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3954 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3955 SelectObject( hdcSrc, bmpSrc );
3957 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3958 ok(result, "BitBlt failed\n");
3960 hRgn = CreateRectRgn( 0,0,0,0 );
3961 SelectClipRgn( hdcDst, hRgn );
3963 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3964 ok(result, "BitBlt failed\n");
3966 DeleteObject( bmpDst );
3967 DeleteObject( bmpSrc );
3968 DeleteObject( hRgn );
3969 DeleteDC( hdcDst );
3970 DeleteDC( hdcSrc );
3973 static void test_32bit_ddb(void)
3975 char buffer[sizeof(BITMAPINFOHEADER) + sizeof(DWORD)];
3976 BITMAPINFO *biDst = (BITMAPINFO *)buffer;
3977 HBITMAP bmpSrc, bmpDst;
3978 HBITMAP oldSrc, oldDst;
3979 HDC hdcSrc, hdcDst, hdcScreen;
3980 HBRUSH brush;
3981 DWORD *dstBuffer, *data;
3982 DWORD colorSrc = 0x40201008;
3984 memset(biDst, 0, sizeof(BITMAPINFOHEADER));
3985 biDst->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3986 biDst->bmiHeader.biWidth = 1;
3987 biDst->bmiHeader.biHeight = -1;
3988 biDst->bmiHeader.biPlanes = 1;
3989 biDst->bmiHeader.biBitCount = 32;
3990 biDst->bmiHeader.biCompression = BI_RGB;
3992 hdcScreen = CreateCompatibleDC(0);
3993 if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3995 DeleteDC(hdcScreen);
3996 trace("Skipping 32-bit DDB test\n");
3997 return;
4000 hdcSrc = CreateCompatibleDC(hdcScreen);
4001 bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
4002 oldSrc = SelectObject(hdcSrc, bmpSrc);
4004 hdcDst = CreateCompatibleDC(hdcScreen);
4005 bmpDst = CreateDIBSection(hdcDst, biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
4006 oldDst = SelectObject(hdcDst, bmpDst);
4008 StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
4009 ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
4011 if (pGdiAlphaBlend)
4013 BLENDFUNCTION blend;
4014 BOOL ret;
4016 blend.BlendOp = AC_SRC_OVER;
4017 blend.BlendFlags = 0;
4018 blend.SourceConstantAlpha = 128;
4019 blend.AlphaFormat = 0;
4020 dstBuffer[0] = 0x80808080;
4021 ret = pGdiAlphaBlend( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, blend );
4022 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
4023 ok(dstBuffer[0] == 0x60504844, "wrong color %x\n", dstBuffer[0]);
4024 blend.AlphaFormat = AC_SRC_ALPHA;
4025 dstBuffer[0] = 0x80808080;
4026 ret = pGdiAlphaBlend( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, blend );
4027 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
4028 ok(dstBuffer[0] == 0x90807874, "wrong color %x\n", dstBuffer[0]);
4031 data = (DWORD *)biDst->bmiColors;
4032 data[0] = 0x20304050;
4033 brush = CreateDIBPatternBrushPt( biDst, DIB_RGB_COLORS );
4034 ok( brush != 0, "brush creation failed\n" );
4035 SelectObject( hdcSrc, brush );
4036 PatBlt( hdcSrc, 0, 0, 1, 1, PATCOPY );
4037 BitBlt( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, SRCCOPY );
4038 ok(dstBuffer[0] == data[0], "Expected color=%x, received color=%x\n", data[0], dstBuffer[0]);
4039 SelectObject( hdcSrc, GetStockObject(BLACK_BRUSH) );
4040 DeleteObject( brush );
4042 biDst->bmiHeader.biBitCount = 24;
4043 brush = CreateDIBPatternBrushPt( biDst, DIB_RGB_COLORS );
4044 ok( brush != 0, "brush creation failed\n" );
4045 SelectObject( hdcSrc, brush );
4046 PatBlt( hdcSrc, 0, 0, 1, 1, PATCOPY );
4047 BitBlt( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, SRCCOPY );
4048 ok(dstBuffer[0] == (data[0] & ~0xff000000),
4049 "Expected color=%x, received color=%x\n", data[0] & 0xff000000, dstBuffer[0]);
4050 SelectObject( hdcSrc, GetStockObject(BLACK_BRUSH) );
4051 DeleteObject( brush );
4053 /* Tidy up */
4054 SelectObject(hdcDst, oldDst);
4055 DeleteObject(bmpDst);
4056 DeleteDC(hdcDst);
4058 SelectObject(hdcSrc, oldSrc);
4059 DeleteObject(bmpSrc);
4060 DeleteDC(hdcSrc);
4062 DeleteDC(hdcScreen);
4066 * Used by test_GetDIBits_top_down to create the bitmap to test against.
4068 static void setup_picture(char *picture, int bpp)
4070 int i;
4072 switch(bpp)
4074 case 16:
4075 case 32:
4076 /*Set the first byte in each pixel to the index of that pixel.*/
4077 for (i = 0; i < 4; i++)
4078 picture[i * (bpp / 8)] = i;
4079 break;
4080 case 24:
4081 picture[0] = 0;
4082 picture[3] = 1;
4083 /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
4084 picture[8] = 2;
4085 picture[11] = 3;
4086 break;
4090 static void test_GetDIBits_top_down(int bpp)
4092 BITMAPINFO bi;
4093 HBITMAP bmptb, bmpbt;
4094 HDC hdc;
4095 int pictureOut[4];
4096 int *picture;
4097 int statusCode;
4099 memset( &bi, 0, sizeof(bi) );
4100 bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
4101 bi.bmiHeader.biWidth=2;
4102 bi.bmiHeader.biHeight=2;
4103 bi.bmiHeader.biPlanes=1;
4104 bi.bmiHeader.biBitCount=bpp;
4105 bi.bmiHeader.biCompression=BI_RGB;
4107 /*Get the device context for the screen.*/
4108 hdc = GetDC(NULL);
4109 ok(hdc != NULL, "Could not get a handle to a device context.\n");
4111 /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
4112 bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
4113 ok(bmpbt != NULL, "Could not create a DIB section.\n");
4114 /*Now that we have a pointer to the pixels, we write to them.*/
4115 setup_picture((char*)picture, bpp);
4116 /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
4117 bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
4118 bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
4119 ok(bmptb != NULL, "Could not create a DIB section.\n");
4120 /*Write to this top to bottom bitmap.*/
4121 setup_picture((char*)picture, bpp);
4123 bi.bmiHeader.biWidth = 1;
4125 bi.bmiHeader.biHeight = 2;
4126 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
4127 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4128 /*Check the first byte of the pixel.*/
4129 ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
4130 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
4131 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4132 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
4133 /*Check second scanline.*/
4134 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
4135 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4136 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
4137 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
4138 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4139 ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
4140 /*Check both scanlines.*/
4141 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
4142 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4143 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
4144 ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
4145 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
4146 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4147 ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
4148 ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
4150 /*Make destination bitmap top-down.*/
4151 bi.bmiHeader.biHeight = -2;
4152 statusCode = GetDIBits(hdc, bmpbt, 0, 1, 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 -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
4155 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
4156 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4157 ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
4158 /*Check second scanline.*/
4159 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
4160 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4161 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
4162 statusCode = GetDIBits(hdc, bmpbt, 1, 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 -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
4165 /*Check both scanlines.*/
4166 statusCode = GetDIBits(hdc, bmptb, 0, 2, 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 -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
4169 ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
4170 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
4171 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4172 ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
4173 ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
4175 DeleteObject(bmpbt);
4176 DeleteObject(bmptb);
4179 static void test_GetSetDIBits_rtl(void)
4181 HDC hdc, hdc_mem;
4182 HBITMAP bitmap, orig_bitmap;
4183 BITMAPINFO info;
4184 int ret;
4185 DWORD bits_1[8 * 8], bits_2[8 * 8];
4187 if(!pSetLayout)
4189 win_skip("Don't have SetLayout\n");
4190 return;
4193 hdc = GetDC( NULL );
4194 hdc_mem = CreateCompatibleDC( hdc );
4195 pSetLayout( hdc_mem, LAYOUT_LTR );
4197 bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
4198 orig_bitmap = SelectObject( hdc_mem, bitmap );
4199 SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
4200 SelectObject( hdc_mem, orig_bitmap );
4202 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
4203 info.bmiHeader.biWidth = 8;
4204 info.bmiHeader.biHeight = 8;
4205 info.bmiHeader.biPlanes = 1;
4206 info.bmiHeader.biBitCount = 32;
4207 info.bmiHeader.biCompression = BI_RGB;
4209 /* First show that GetDIBits ignores the layout mode. */
4211 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
4212 ok(ret == 8, "got %d\n", ret);
4213 ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
4215 pSetLayout( hdc_mem, LAYOUT_RTL );
4217 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
4218 ok(ret == 8, "got %d\n", ret);
4220 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
4222 /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
4223 followed by a GetDIBits and show that the bits remain unchanged. */
4225 pSetLayout( hdc_mem, LAYOUT_LTR );
4227 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
4228 ok(ret == 8, "got %d\n", ret);
4229 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
4230 ok(ret == 8, "got %d\n", ret);
4231 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
4233 pSetLayout( hdc_mem, LAYOUT_RTL );
4235 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
4236 ok(ret == 8, "got %d\n", ret);
4237 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
4238 ok(ret == 8, "got %d\n", ret);
4239 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
4241 DeleteObject( bitmap );
4242 DeleteDC( hdc_mem );
4243 ReleaseDC( NULL, hdc );
4246 static void test_GetDIBits_scanlines(void)
4248 BITMAPINFO *info;
4249 DWORD *dib_bits;
4250 HDC hdc = GetDC( NULL );
4251 HBITMAP dib;
4252 DWORD data[128], inverted_bits[64];
4253 int i, ret;
4255 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4257 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4258 info->bmiHeader.biWidth = 8;
4259 info->bmiHeader.biHeight = 8;
4260 info->bmiHeader.biPlanes = 1;
4261 info->bmiHeader.biBitCount = 32;
4262 info->bmiHeader.biCompression = BI_RGB;
4264 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4266 for (i = 0; i < 64; i++)
4268 dib_bits[i] = i;
4269 inverted_bits[56 - (i & ~7) + (i & 7)] = i;
4272 /* b-u -> b-u */
4274 memset( data, 0xaa, sizeof(data) );
4276 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4277 ok( ret == 8, "got %d\n", ret );
4278 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4279 memset( data, 0xaa, sizeof(data) );
4281 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4282 ok( ret == 5, "got %d\n", ret );
4283 ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
4284 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4285 memset( data, 0xaa, sizeof(data) );
4287 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4288 ok( ret == 7, "got %d\n", ret );
4289 ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
4290 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4291 memset( data, 0xaa, sizeof(data) );
4293 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4294 ok( ret == 1, "got %d\n", ret );
4295 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4296 memset( data, 0xaa, sizeof(data) );
4298 info->bmiHeader.biHeight = 16;
4299 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4300 ok( ret == 5, "got %d\n", ret );
4301 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4302 ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
4303 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4304 memset( data, 0xaa, sizeof(data) );
4306 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
4307 ok( ret == 6, "got %d\n", ret );
4308 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4309 ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
4310 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4311 memset( data, 0xaa, sizeof(data) );
4313 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
4314 ok( ret == 0, "got %d\n", ret );
4315 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4316 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4317 memset( data, 0xaa, sizeof(data) );
4319 info->bmiHeader.biHeight = 5;
4320 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4321 ok( ret == 2, "got %d\n", ret );
4322 ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
4323 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4324 memset( data, 0xaa, sizeof(data) );
4326 /* b-u -> t-d */
4328 info->bmiHeader.biHeight = -8;
4329 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4330 ok( ret == 8, "got %d\n", ret );
4331 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4332 memset( data, 0xaa, sizeof(data) );
4334 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4335 ok( ret == 5, "got %d\n", ret );
4336 ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
4337 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4338 memset( data, 0xaa, sizeof(data) );
4340 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4341 ok( ret == 7, "got %d\n", ret );
4342 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
4343 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4344 memset( data, 0xaa, sizeof(data) );
4346 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4347 ok( ret == 4, "got %d\n", ret );
4348 ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
4349 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4350 memset( data, 0xaa, sizeof(data) );
4352 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
4353 ok( ret == 5, "got %d\n", ret );
4354 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
4355 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4356 memset( data, 0xaa, sizeof(data) );
4358 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
4359 ok( ret == 5, "got %d\n", ret );
4360 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
4361 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4362 memset( data, 0xaa, sizeof(data) );
4364 info->bmiHeader.biHeight = -16;
4365 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
4366 ok( ret == 8, "got %d\n", ret );
4367 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4368 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4369 memset( data, 0xaa, sizeof(data) );
4371 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4372 ok( ret == 5, "got %d\n", ret );
4373 ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
4374 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4375 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4376 memset( data, 0xaa, sizeof(data) );
4378 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4379 ok( ret == 8, "got %d\n", ret );
4380 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4381 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4382 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4383 memset( data, 0xaa, sizeof(data) );
4385 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4386 ok( ret == 8, "got %d\n", ret );
4387 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4388 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4389 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4390 memset( data, 0xaa, sizeof(data) );
4392 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4393 ok( ret == 7, "got %d\n", ret );
4394 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
4395 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4396 memset( data, 0xaa, sizeof(data) );
4398 ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
4399 ok( ret == 1, "got %d\n", ret );
4400 for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4401 memset( data, 0xaa, sizeof(data) );
4403 info->bmiHeader.biHeight = -5;
4404 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4405 ok( ret == 2, "got %d\n", ret );
4406 ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
4407 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4408 memset( data, 0xaa, sizeof(data) );
4410 DeleteObject( dib );
4412 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4413 info->bmiHeader.biWidth = 8;
4414 info->bmiHeader.biHeight = -8;
4415 info->bmiHeader.biPlanes = 1;
4416 info->bmiHeader.biBitCount = 32;
4417 info->bmiHeader.biCompression = BI_RGB;
4419 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4421 for (i = 0; i < 64; i++) dib_bits[i] = i;
4423 /* t-d -> t-d */
4425 info->bmiHeader.biHeight = -8;
4426 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4427 ok( ret == 8, "got %d\n", ret );
4428 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4429 memset( data, 0xaa, sizeof(data) );
4431 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4432 ok( ret == 5, "got %d\n", ret );
4433 ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
4434 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4435 memset( data, 0xaa, sizeof(data) );
4437 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4438 ok( ret == 7, "got %d\n", ret );
4439 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
4440 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4441 memset( data, 0xaa, sizeof(data) );
4443 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4444 ok( ret == 4, "got %d\n", ret );
4445 ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
4446 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4447 memset( data, 0xaa, sizeof(data) );
4449 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
4450 ok( ret == 5, "got %d\n", ret );
4451 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
4452 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4453 memset( data, 0xaa, sizeof(data) );
4455 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
4456 ok( ret == 5, "got %d\n", ret );
4457 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
4458 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4459 memset( data, 0xaa, sizeof(data) );
4461 info->bmiHeader.biHeight = -16;
4462 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
4463 ok( ret == 8, "got %d\n", ret );
4464 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4465 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4466 memset( data, 0xaa, sizeof(data) );
4468 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4469 ok( ret == 5, "got %d\n", ret );
4470 ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
4471 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4472 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4473 memset( data, 0xaa, sizeof(data) );
4475 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4476 ok( ret == 8, "got %d\n", ret );
4477 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4478 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4479 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4480 memset( data, 0xaa, sizeof(data) );
4482 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4483 ok( ret == 8, "got %d\n", ret );
4484 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4485 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4486 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4487 memset( data, 0xaa, sizeof(data) );
4489 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4490 ok( ret == 7, "got %d\n", ret );
4491 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
4492 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4493 memset( data, 0xaa, sizeof(data) );
4495 info->bmiHeader.biHeight = -5;
4496 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4497 ok( ret == 2, "got %d\n", ret );
4498 ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
4499 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4500 memset( data, 0xaa, sizeof(data) );
4503 /* t-d -> b-u */
4505 info->bmiHeader.biHeight = 8;
4507 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4508 ok( ret == 8, "got %d\n", ret );
4509 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4510 memset( data, 0xaa, sizeof(data) );
4512 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4513 ok( ret == 5, "got %d\n", ret );
4514 ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
4515 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4516 memset( data, 0xaa, sizeof(data) );
4518 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4519 ok( ret == 7, "got %d\n", ret );
4520 ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
4521 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4522 memset( data, 0xaa, sizeof(data) );
4524 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4525 ok( ret == 1, "got %d\n", ret );
4526 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4527 memset( data, 0xaa, sizeof(data) );
4529 info->bmiHeader.biHeight = 16;
4530 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4531 ok( ret == 5, "got %d\n", ret );
4532 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4533 ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
4534 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4535 memset( data, 0xaa, sizeof(data) );
4537 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
4538 ok( ret == 6, "got %d\n", ret );
4539 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4540 ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
4541 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4542 memset( data, 0xaa, sizeof(data) );
4544 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
4545 ok( ret == 0, "got %d\n", ret );
4546 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4547 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4548 memset( data, 0xaa, sizeof(data) );
4550 info->bmiHeader.biHeight = 5;
4551 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4552 ok( ret == 2, "got %d\n", ret );
4553 ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
4554 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4556 DeleteObject( dib );
4558 ReleaseDC( NULL, hdc );
4559 HeapFree( GetProcessHeap(), 0, info );
4563 static void test_SetDIBits(void)
4565 char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
4566 LOGPALETTE *pal = (LOGPALETTE *)palbuf;
4567 PALETTEENTRY *palent = pal->palPalEntry;
4568 HPALETTE palette;
4569 BITMAPINFO *info;
4570 DWORD *dib_bits;
4571 HDC hdc = GetDC( NULL );
4572 DWORD data[128], inverted_data[128];
4573 HBITMAP dib;
4574 int i, ret;
4576 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4578 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4579 info->bmiHeader.biWidth = 8;
4580 info->bmiHeader.biHeight = 8;
4581 info->bmiHeader.biPlanes = 1;
4582 info->bmiHeader.biBitCount = 32;
4583 info->bmiHeader.biCompression = BI_RGB;
4585 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4586 memset( dib_bits, 0xaa, 64 * 4 );
4588 for (i = 0; i < 128; i++)
4590 data[i] = i;
4591 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4594 /* b-u -> b-u */
4596 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4597 ok( ret == 8, "got %d\n", ret );
4598 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4599 memset( dib_bits, 0xaa, 64 * 4 );
4601 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4602 ok( ret == 5, "got %d\n", ret );
4603 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4604 ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
4605 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4606 memset( dib_bits, 0xaa, 64 * 4 );
4608 /* top of dst is aligned with startscans down for the top of the src.
4609 Then starting from the bottom of src, lines rows are copied across. */
4611 info->bmiHeader.biHeight = 16;
4612 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4613 ok( ret == 12, "got %d\n", ret );
4614 ok( !memcmp( dib_bits, data + 56, 40 * 4 ), "bits differ\n");
4615 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4616 memset( dib_bits, 0xaa, 64 * 4 );
4618 info->bmiHeader.biHeight = 5;
4619 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4620 ok( ret == 2, "got %d\n", ret );
4621 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4622 ok( !memcmp( dib_bits + 32, data, 16 * 4 ), "bits differ\n");
4623 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4624 memset( dib_bits, 0xaa, 64 * 4 );
4626 /* t-d -> b-u */
4627 info->bmiHeader.biHeight = -8;
4628 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4629 ok( ret == 8, "got %d\n", ret );
4630 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4631 memset( dib_bits, 0xaa, 64 * 4 );
4633 /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
4634 we copy lines rows from the top of the src */
4636 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4637 ok( ret == 5, "got %d\n", ret );
4638 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4639 ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
4640 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4641 memset( dib_bits, 0xaa, 64 * 4 );
4643 info->bmiHeader.biHeight = -16;
4644 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4645 ok( ret == 12, "got %d\n", ret );
4646 ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
4647 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4648 memset( dib_bits, 0xaa, 64 * 4 );
4650 ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4651 ok( ret == 12, "got %d\n", ret );
4652 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4653 memset( dib_bits, 0xaa, 64 * 4 );
4655 ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4656 ok( ret == 12, "got %d\n", ret );
4657 ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
4658 memset( dib_bits, 0xaa, 64 * 4 );
4660 info->bmiHeader.biHeight = -5;
4661 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4662 ok( ret == 2, "got %d\n", ret );
4663 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4664 ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
4665 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4666 memset( dib_bits, 0xaa, 64 * 4 );
4668 DeleteObject( dib );
4670 info->bmiHeader.biHeight = -8;
4672 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4673 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4675 /* t-d -> t-d */
4677 /* like the t-d -> b-u case. */
4679 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4680 ok( ret == 8, "got %d\n", ret );
4681 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4682 memset( dib_bits, 0xaa, 64 * 4 );
4684 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4685 ok( ret == 5, "got %d\n", ret );
4686 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4687 ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
4688 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4689 memset( dib_bits, 0xaa, 64 * 4 );
4691 info->bmiHeader.biHeight = -16;
4692 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4693 ok( ret == 12, "got %d\n", ret );
4694 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4695 ok( !memcmp( dib_bits + 24, data, 40 * 4 ), "bits differ\n");
4696 memset( dib_bits, 0xaa, 64 * 4 );
4698 info->bmiHeader.biHeight = -5;
4699 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4700 ok( ret == 2, "got %d\n", ret );
4701 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4702 ok( !memcmp( dib_bits + 16, data, 16 * 4 ), "bits differ\n");
4703 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4704 memset( dib_bits, 0xaa, 64 * 4 );
4706 /* b-u -> t-d */
4707 /* like the b-u -> b-u case */
4709 info->bmiHeader.biHeight = 8;
4710 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4711 ok( ret == 8, "got %d\n", ret );
4712 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4713 memset( dib_bits, 0xaa, 64 * 4 );
4715 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4716 ok( ret == 5, "got %d\n", ret );
4717 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4718 ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
4719 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4720 memset( dib_bits, 0xaa, 64 * 4 );
4722 info->bmiHeader.biHeight = 16;
4723 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4724 ok( ret == 12, "got %d\n", ret );
4725 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4726 ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
4727 memset( dib_bits, 0xaa, 64 * 4 );
4729 info->bmiHeader.biHeight = 5;
4730 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4731 ok( ret == 2, "got %d\n", ret );
4732 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4733 ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
4734 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4735 memset( dib_bits, 0xaa, 64 * 4 );
4737 /* handling of partial color table */
4739 info->bmiHeader.biHeight = -8;
4740 info->bmiHeader.biBitCount = 8;
4741 info->bmiHeader.biClrUsed = 137;
4742 for (i = 0; i < 256; i++)
4744 info->bmiColors[i].rgbRed = 255 - i;
4745 info->bmiColors[i].rgbGreen = i * 2;
4746 info->bmiColors[i].rgbBlue = i;
4747 info->bmiColors[i].rgbReserved = 0;
4749 for (i = 0; i < 64; i++) ((BYTE *)data)[i] = i * 4 + 1;
4750 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4751 ok( ret == 8, "got %d\n", ret );
4752 for (i = 0; i < 64; i++)
4754 int idx = i * 4 + 1;
4755 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : (info->bmiColors[idx].rgbRed << 16 |
4756 info->bmiColors[idx].rgbGreen << 8 |
4757 info->bmiColors[idx].rgbBlue);
4758 ok( dib_bits[i] == expect, "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
4760 memset( dib_bits, 0xaa, 64 * 4 );
4762 /* handling of DIB_PAL_COLORS */
4764 pal->palVersion = 0x300;
4765 pal->palNumEntries = 137;
4766 info->bmiHeader.biClrUsed = 221;
4767 for (i = 0; i < 256; i++)
4769 palent[i].peRed = i * 2;
4770 palent[i].peGreen = 255 - i;
4771 palent[i].peBlue = i;
4773 palette = CreatePalette( pal );
4774 ok( palette != 0, "palette creation failed\n" );
4775 SelectPalette( hdc, palette, FALSE );
4776 for (i = 0; i < 256; i++) ((WORD *)info->bmiColors)[i] = 255 - i;
4777 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_PAL_COLORS );
4778 ok( ret == 8, "got %d\n", ret );
4779 for (i = 0; i < 64; i++)
4781 int idx = i * 4 + 1;
4782 int ent = (255 - idx) % pal->palNumEntries;
4783 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 :
4784 (palent[ent].peRed << 16 | palent[ent].peGreen << 8 | palent[ent].peBlue);
4785 ok( dib_bits[i] == expect || broken(dib_bits[i] == 0), /* various Windows versions get some values wrong */
4786 "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
4788 memset( dib_bits, 0xaa, 64 * 4 );
4790 ReleaseDC( NULL, hdc );
4791 DeleteObject( dib );
4792 DeleteObject( palette );
4793 HeapFree( GetProcessHeap(), 0, info );
4796 static void test_SetDIBits_RLE4(void)
4798 BITMAPINFO *info;
4799 DWORD *dib_bits;
4800 HDC hdc = GetDC( NULL );
4801 BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00, /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
4802 0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
4803 0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00, /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
4804 0x00, 0x02, 0x01, 0x02, 0x05, 0x87, /* dx=1, dy=2, 8, 7, 8, 7, 8 */
4805 0x00, 0x01 }; /* <eod> */
4806 HBITMAP dib;
4807 int i, ret;
4808 DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
4809 0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
4810 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4811 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4812 0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
4813 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4814 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4815 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4817 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4819 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4820 info->bmiHeader.biWidth = 8;
4821 info->bmiHeader.biHeight = 8;
4822 info->bmiHeader.biPlanes = 1;
4823 info->bmiHeader.biBitCount = 32;
4824 info->bmiHeader.biCompression = BI_RGB;
4826 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4827 memset( dib_bits, 0xaa, 64 * 4 );
4829 info->bmiHeader.biBitCount = 4;
4830 info->bmiHeader.biCompression = BI_RLE4;
4831 info->bmiHeader.biSizeImage = sizeof(rle4_data);
4833 for (i = 0; i < 16; i++)
4835 info->bmiColors[i].rgbRed = i;
4836 info->bmiColors[i].rgbGreen = i;
4837 info->bmiColors[i].rgbBlue = i;
4838 info->bmiColors[i].rgbReserved = 0;
4841 ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
4842 ok( ret == 8, "got %d\n", ret );
4843 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
4844 memset( dib_bits, 0xaa, 64 * 4 );
4846 DeleteObject( dib );
4847 ReleaseDC( NULL, hdc );
4848 HeapFree( GetProcessHeap(), 0, info );
4851 static void test_SetDIBits_RLE8(void)
4853 BITMAPINFO *info;
4854 DWORD *dib_bits;
4855 HDC hdc = GetDC( NULL );
4856 BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00, /* 2, 2, 2, f0, f0, f0, f0, <eol> */
4857 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4858 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4859 0x00, 0x01 }; /* <eod> */
4860 HBITMAP dib;
4861 int i, ret;
4862 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4863 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4864 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4865 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4866 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4867 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4868 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4869 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4870 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4871 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4872 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 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 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4877 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4879 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4881 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4882 info->bmiHeader.biWidth = 8;
4883 info->bmiHeader.biHeight = 8;
4884 info->bmiHeader.biPlanes = 1;
4885 info->bmiHeader.biBitCount = 32;
4886 info->bmiHeader.biCompression = BI_RGB;
4888 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4889 memset( dib_bits, 0xaa, 64 * 4 );
4891 info->bmiHeader.biBitCount = 8;
4892 info->bmiHeader.biCompression = BI_RLE8;
4893 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4895 for (i = 0; i < 256; i++)
4897 info->bmiColors[i].rgbRed = i;
4898 info->bmiColors[i].rgbGreen = i;
4899 info->bmiColors[i].rgbBlue = i;
4900 info->bmiColors[i].rgbReserved = 0;
4903 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4904 ok( ret == 8, "got %d\n", ret );
4905 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4906 memset( dib_bits, 0xaa, 64 * 4 );
4908 /* startscan and lines are ignored, unless lines == 0 */
4909 ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4910 ok( ret == 8, "got %d\n", ret );
4911 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4912 memset( dib_bits, 0xaa, 64 * 4 );
4914 ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4915 ok( ret == 8, "got %d\n", ret );
4916 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4917 memset( dib_bits, 0xaa, 64 * 4 );
4919 ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4920 ok( ret == 0, "got %d\n", ret );
4921 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4922 memset( dib_bits, 0xaa, 64 * 4 );
4924 /* reduce width to 4, left-hand side of dst is touched. */
4925 info->bmiHeader.biWidth = 4;
4926 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4927 ok( ret == 8, "got %d\n", ret );
4928 for (i = 0; i < 64; i++)
4930 DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4931 ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4933 memset( dib_bits, 0xaa, 64 * 4 );
4935 /* Show that the top lines are aligned by adjusting the height of the src */
4937 /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4938 info->bmiHeader.biWidth = 8;
4939 info->bmiHeader.biHeight = 4;
4940 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4941 ok( ret == 4, "got %d\n", ret );
4942 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4943 ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4944 memset( dib_bits, 0xaa, 64 * 4 );
4946 /* increase the height to 9 -> everything moves down one row. */
4947 info->bmiHeader.biHeight = 9;
4948 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4949 ok( ret == 9, "got %d\n", ret );
4950 ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4951 for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4952 memset( dib_bits, 0xaa, 64 * 4 );
4954 /* top-down compressed dibs are invalid */
4955 info->bmiHeader.biHeight = -8;
4956 SetLastError( 0xdeadbeef );
4957 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4958 ok( ret == 0, "got %d\n", ret );
4959 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4960 DeleteObject( dib );
4962 /* top-down dst */
4964 info->bmiHeader.biHeight = -8;
4965 info->bmiHeader.biBitCount = 32;
4966 info->bmiHeader.biCompression = BI_RGB;
4967 info->bmiHeader.biSizeImage = 0;
4969 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4970 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4972 info->bmiHeader.biHeight = 8;
4973 info->bmiHeader.biBitCount = 8;
4974 info->bmiHeader.biCompression = BI_RLE8;
4975 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4977 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4978 ok( ret == 8, "got %d\n", ret );
4979 ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4980 memset( dib_bits, 0xaa, 64 * 4 );
4982 info->bmiHeader.biHeight = 4;
4983 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4984 ok( ret == 4, "got %d\n", ret );
4985 ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4986 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4987 memset( dib_bits, 0xaa, 64 * 4 );
4989 info->bmiHeader.biHeight = 9;
4990 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4991 ok( ret == 9, "got %d\n", ret );
4992 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4993 ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4994 memset( dib_bits, 0xaa, 64 * 4 );
4996 DeleteObject( dib );
4997 ReleaseDC( NULL, hdc );
4998 HeapFree( GetProcessHeap(), 0, info );
5001 static void test_SetDIBitsToDevice(void)
5003 char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
5004 LOGPALETTE *pal = (LOGPALETTE *)palbuf;
5005 PALETTEENTRY *palent = pal->palPalEntry;
5006 HPALETTE palette;
5007 BITMAPINFO *info;
5008 DWORD *dib_bits;
5009 HDC hdc = CreateCompatibleDC( 0 );
5010 DWORD data[128], inverted_data[128];
5011 HBITMAP dib;
5012 int i, ret;
5014 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
5016 info->bmiHeader.biSize = sizeof(info->bmiHeader);
5017 info->bmiHeader.biWidth = 8;
5018 info->bmiHeader.biHeight = 8;
5019 info->bmiHeader.biPlanes = 1;
5020 info->bmiHeader.biBitCount = 32;
5021 info->bmiHeader.biCompression = BI_RGB;
5023 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5024 memset( dib_bits, 0xaa, 64 * 4 );
5025 SelectObject( hdc, dib );
5027 for (i = 0; i < 128; i++)
5029 data[i] = i;
5030 inverted_data[120 - (i & ~7) + (i & 7)] = i;
5033 /* b-u -> b-u */
5035 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5036 ok( ret == 8, "got %d\n", ret );
5037 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
5038 memset( dib_bits, 0xaa, 64 * 4 );
5040 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
5041 ok( ret == 5, "got %d\n", ret );
5042 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5043 for (i = 8; i < 48; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5044 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5045 memset( dib_bits, 0xaa, 64 * 4 );
5047 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 3, 1, 5, data, info, DIB_RGB_COLORS );
5048 ok( ret == 5, "got %d\n", ret );
5049 for (i = 0; i < 24; i++) ok( dib_bits[i] == data[i + 16], "%d: got %08x\n", i, dib_bits[i] );
5050 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5051 memset( dib_bits, 0xaa, 64 * 4 );
5053 info->bmiHeader.biHeight = 16;
5054 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
5055 ok( ret == 7, "got %d\n", ret );
5056 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5057 for (i = 8; i < 64; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5058 memset( dib_bits, 0xaa, 64 * 4 );
5060 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 8, 0, 6, 1, 12, data, info, DIB_RGB_COLORS );
5061 ok( ret == 12, "got %d\n", ret );
5062 for (i = 0; i < 40; i++) ok( dib_bits[i] == data[i + 56], "%d: got %08x\n", i, dib_bits[i] );
5063 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5064 memset( dib_bits, 0xaa, 64 * 4 );
5066 ret = SetDIBitsToDevice( hdc, 0, -4, 8, 8, 0, 3, 1, 12, data, info, DIB_RGB_COLORS );
5067 ok( ret == 10, "got %d\n", ret );
5068 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5069 for (i = 32; i < 64; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
5070 memset( dib_bits, 0xaa, 64 * 4 );
5072 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, -3, 1, 12, data, info, DIB_RGB_COLORS );
5073 ok( ret == 4, "got %d\n", ret );
5074 for (i = 0; i < 32; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
5075 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5076 memset( dib_bits, 0xaa, 64 * 4 );
5078 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 5, 0, -2, 1, 12, data, info, DIB_RGB_COLORS );
5079 ok( ret == 2, "got %d\n", ret );
5080 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5081 for (i = 32; i < 48; i++) ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
5082 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5083 memset( dib_bits, 0xaa, 64 * 4 );
5085 info->bmiHeader.biHeight = 5;
5086 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 2, 2, data, info, DIB_RGB_COLORS );
5087 ok( ret == 2, "got %d\n", ret );
5088 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5089 for (i = 16; i < 32; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
5090 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5091 memset( dib_bits, 0xaa, 64 * 4 );
5093 ret = SetDIBitsToDevice( hdc, 3, 3, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
5094 ok( ret == 3, "got %d\n", ret );
5095 for (i = 0; i < 64; i++)
5096 if (i == 27 || i == 28 || i == 35 || i == 36)
5097 ok( dib_bits[i] == data[i - 18], "%d: got %08x\n", i, dib_bits[i] );
5098 else
5099 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5100 memset( dib_bits, 0xaa, 64 * 4 );
5102 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5103 ok( ret == 5, "got %d\n", ret );
5104 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5105 memset( dib_bits, 0xaa, 64 * 4 );
5107 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
5108 ok( ret == 0, "got %d\n", ret );
5109 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5110 memset( dib_bits, 0xaa, 64 * 4 );
5112 SetMapMode( hdc, MM_ANISOTROPIC );
5113 SetWindowExtEx( hdc, 3, 3, NULL );
5114 ret = SetDIBitsToDevice( hdc, 2, 2, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
5115 ok( ret == 3, "got %d\n", ret );
5116 for (i = 0; i < 64; i++)
5117 if (i == 41 || i == 42 || i == 49 || i == 50)
5118 ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
5119 else
5120 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5121 memset( dib_bits, 0xaa, 64 * 4 );
5123 SetWindowExtEx( hdc, -1, -1, NULL );
5124 ret = SetDIBitsToDevice( hdc, 2, 2, 4, 4, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
5125 ok( ret == 4, "got %d\n", ret );
5126 for (i = 0; i < 64; i++)
5127 if (i == 48 || i == 49 || i == 56 || i == 57)
5128 ok( dib_bits[i] == data[i - 37], "%d: got %08x\n", i, dib_bits[i] );
5129 else
5130 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5131 memset( dib_bits, 0xaa, 64 * 4 );
5132 SetMapMode( hdc, MM_TEXT );
5134 if (pSetLayout)
5136 pSetLayout( hdc, LAYOUT_RTL );
5137 ret = SetDIBitsToDevice( hdc, 1, 2, 3, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
5138 ok( ret == 3, "got %d\n", ret );
5139 for (i = 0; i < 64; i++)
5140 if (i == 36 || i == 37 || i == 38 || i == 44 || i == 45 || i == 46)
5141 ok( dib_bits[i] == data[i - 27], "%d: got %08x\n", i, dib_bits[i] );
5142 else
5143 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5144 memset( dib_bits, 0xaa, 64 * 4 );
5145 pSetLayout( hdc, LAYOUT_LTR );
5148 /* t-d -> b-u */
5149 info->bmiHeader.biHeight = -8;
5150 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5151 ok( ret == 8, "got %d\n", ret );
5152 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
5153 memset( dib_bits, 0xaa, 64 * 4 );
5155 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
5156 ok( ret == 5, "got %d\n", ret );
5157 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5158 for (i = 8; i < 48; i++) ok( dib_bits[i] == inverted_data[i + 80], "%d: got %08x\n", i, dib_bits[i] );
5159 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5160 memset( dib_bits, 0xaa, 64 * 4 );
5162 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 4, 1, 5, data, info, DIB_RGB_COLORS );
5163 ok( ret == 5, "got %d\n", ret );
5164 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
5165 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5166 memset( dib_bits, 0xaa, 64 * 4 );
5168 info->bmiHeader.biHeight = -16;
5169 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
5170 ok( ret == 12, "got %d\n", ret );
5171 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5172 for (i = 8; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 24], "%d: got %08x\n", i, dib_bits[i] );
5173 memset( dib_bits, 0xaa, 64 * 4 );
5175 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, 7, 1, 12, data, info, DIB_RGB_COLORS );
5176 ok( ret == 12, "got %d\n", ret );
5177 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
5178 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5179 memset( dib_bits, 0xaa, 64 * 4 );
5181 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 4, 12, data, info, DIB_RGB_COLORS );
5182 ok( ret == 12, "got %d\n", ret );
5183 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5184 for (i = 32; i < 64; i++) ok( dib_bits[i] == inverted_data[i], "%d: got %08x\n", i, dib_bits[i] );
5185 memset( dib_bits, 0xaa, 64 * 4 );
5187 ret = SetDIBitsToDevice( hdc, 0, -3, 8, 8, 0, 2, 4, 12, data, info, DIB_RGB_COLORS );
5188 ok( ret == 12, "got %d\n", ret );
5189 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5190 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5191 memset( dib_bits, 0xaa, 64 * 4 );
5193 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, -2, 4, 12, data, info, DIB_RGB_COLORS );
5194 ok( ret == 12, "got %d\n", ret );
5195 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5196 for (i = 24; i < 40; i++) ok( dib_bits[i] == inverted_data[i + 8], "%d: got %08x\n", i, dib_bits[i] );
5197 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5198 memset( dib_bits, 0xaa, 64 * 4 );
5200 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 5, 12, data, info, DIB_RGB_COLORS );
5201 ok( ret == 12, "got %d\n", ret );
5202 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5203 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5204 memset( dib_bits, 0xaa, 64 * 4 );
5206 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
5207 ok( ret == 12, "got %d\n", ret );
5208 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5209 memset( dib_bits, 0xaa, 64 * 4 );
5211 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -2, -4, 0, 12, data, info, DIB_RGB_COLORS );
5212 ok( ret == 12, "got %d\n", ret );
5213 for (i = 0; i < 64; i++)
5214 if (i == 31 || i == 39 || i == 47 || i == 55 || i == 63)
5215 ok( dib_bits[i] == inverted_data[i + 1], "%d: got %08x\n", i, dib_bits[i] );
5216 else
5217 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5218 memset( dib_bits, 0xaa, 64 * 4 );
5220 info->bmiHeader.biHeight = -5;
5221 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
5222 ok( ret == 2, "got %d\n", ret );
5223 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5224 for (i = 8; i < 24; i++) ok( dib_bits[i] == inverted_data[i + 104], "%d: got %08x\n", i, dib_bits[i] );
5225 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5226 memset( dib_bits, 0xaa, 64 * 4 );
5228 ret = SetDIBitsToDevice( hdc, 5, 4, 2, 2, 6, 3, 1, 5, data, info, DIB_RGB_COLORS );
5229 ok( ret == 5, "got %d\n", ret );
5230 for (i = 0; i < 64; i++)
5231 if (i == 21 || i == 22 || i == 29 || i == 30)
5232 ok( dib_bits[i] == inverted_data[i + 89], "%d: got %08x\n", i, dib_bits[i] );
5233 else
5234 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5235 memset( dib_bits, 0xaa, 64 * 4 );
5237 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5238 ok( ret == 5, "got %d\n", ret );
5239 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5240 memset( dib_bits, 0xaa, 64 * 4 );
5242 info->bmiHeader.biHeight = -8;
5244 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5245 DeleteObject( SelectObject( hdc, dib ));
5246 memset( dib_bits, 0xaa, 16 * 16 * 4 );
5248 /* t-d -> t-d */
5250 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5251 ok( ret == 8, "got %d\n", ret );
5252 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
5253 memset( dib_bits, 0xaa, 64 * 4 );
5255 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
5256 ok( ret == 5, "got %d\n", ret );
5257 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5258 for (i = 16; i < 56; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
5259 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5260 memset( dib_bits, 0xaa, 64 * 4 );
5262 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 3, 0, 2, 1, 5, data, info, DIB_RGB_COLORS );
5263 ok( ret == 5, "got %d\n", ret );
5264 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5265 for (i = 24; i < 48; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
5266 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5267 memset( dib_bits, 0xaa, 64 * 4 );
5269 info->bmiHeader.biHeight = -16;
5270 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
5271 ok( ret == 12, "got %d\n", ret );
5272 for (i = 0; i < 56; i++) ok( dib_bits[i] == data[i + 40], "%d: got %08x\n", i, dib_bits[i] );
5273 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5274 memset( dib_bits, 0xaa, 64 * 4 );
5276 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -1, -8, 0, 12, data, info, DIB_RGB_COLORS );
5277 ok( ret == 12, "got %d\n", ret );
5278 for (i = 0; i < 64; i++)
5279 if (i == 6 || i == 7)
5280 ok( dib_bits[i] == data[i + 82], "%d: got %08x\n", i, dib_bits[i] );
5281 else
5282 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5283 memset( dib_bits, 0xaa, 64 * 4 );
5285 info->bmiHeader.biHeight = -5;
5286 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
5287 ok( ret == 2, "got %d\n", ret );
5288 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5289 for (i = 40; i < 56; i++) ok( dib_bits[i] == data[i - 40], "%d: got %08x\n", i, dib_bits[i] );
5290 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5291 memset( dib_bits, 0xaa, 64 * 4 );
5293 ret = SetDIBitsToDevice( hdc, 7, 2, 8, 8, 1, 0, 0, 5, data, info, DIB_RGB_COLORS );
5294 ok( ret == 5, "got %d\n", ret );
5295 for (i = 0; i < 64; i++)
5296 if (i == 47 || i == 55 || i == 63)
5297 ok( dib_bits[i] == data[i - 46], "%d: got %08x\n", i, dib_bits[i] );
5298 else
5299 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5300 memset( dib_bits, 0xaa, 64 * 4 );
5302 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5303 ok( ret == 5, "got %d\n", ret );
5304 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5305 memset( dib_bits, 0xaa, 64 * 4 );
5307 /* b-u -> t-d */
5309 info->bmiHeader.biHeight = 8;
5310 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5311 ok( ret == 8, "got %d\n", ret );
5312 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
5313 memset( dib_bits, 0xaa, 64 * 4 );
5315 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
5316 ok( ret == 5, "got %d\n", ret );
5317 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5318 for (i = 16; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
5319 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5320 memset( dib_bits, 0xaa, 64 * 4 );
5322 info->bmiHeader.biHeight = 16;
5323 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
5324 ok( ret == 7, "got %d\n", ret );
5325 for (i = 0; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
5326 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5327 memset( dib_bits, 0xaa, 64 * 4 );
5329 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, 0, -4, 1, 12, data, info, DIB_RGB_COLORS );
5330 ok( ret == 3, "got %d\n", ret );
5331 for (i = 0; i < 64; i++)
5332 if ((i >= 36 && i <= 39) || (i >= 44 && i <= 47) || (i >= 52 && i <= 55))
5333 ok( dib_bits[i] == inverted_data[i + 68], "%d: got %08x\n", i, dib_bits[i] );
5334 else
5335 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, -30, -30, 1, 12, data, info, DIB_RGB_COLORS );
5339 ok( ret == 0, "got %d\n", ret );
5340 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5341 memset( dib_bits, 0xaa, 64 * 4 );
5343 ret = SetDIBitsToDevice( hdc, 5, -5, 8, 16, -2, -4, 4, 12, data, info, DIB_RGB_COLORS );
5344 ok( ret == 8, "got %d\n", ret );
5345 for (i = 0; i < 64; i++)
5346 if (i == 7 || i == 15 || i == 23)
5347 ok( dib_bits[i] == inverted_data[i + 97], "%d: got %08x\n", i, dib_bits[i] );
5348 else
5349 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5350 memset( dib_bits, 0xaa, 64 * 4 );
5352 info->bmiHeader.biHeight = 5;
5353 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
5354 ok( ret == 2, "got %d\n", ret );
5355 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5356 for (i = 40; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
5357 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5358 memset( dib_bits, 0xaa, 64 * 4 );
5360 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5361 ok( ret == 5, "got %d\n", ret );
5362 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5363 memset( dib_bits, 0xaa, 64 * 4 );
5365 /* handling of partial color table */
5367 info->bmiHeader.biHeight = -8;
5368 info->bmiHeader.biBitCount = 8;
5369 info->bmiHeader.biClrUsed = 137;
5370 for (i = 0; i < 256; i++)
5372 info->bmiColors[i].rgbRed = 255 - i;
5373 info->bmiColors[i].rgbGreen = i * 2;
5374 info->bmiColors[i].rgbBlue = i;
5375 info->bmiColors[i].rgbReserved = 0;
5377 for (i = 0; i < 64; i++) ((BYTE *)data)[i] = i * 4 + 1;
5378 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5379 ok( ret == 8, "got %d\n", ret );
5380 for (i = 0; i < 64; i++)
5382 int idx = i * 4 + 1;
5383 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : (info->bmiColors[idx].rgbRed << 16 |
5384 info->bmiColors[idx].rgbGreen << 8 |
5385 info->bmiColors[idx].rgbBlue);
5386 ok( dib_bits[i] == expect, "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
5388 memset( dib_bits, 0xaa, 64 * 4 );
5390 /* handling of DIB_PAL_COLORS */
5392 pal->palVersion = 0x300;
5393 pal->palNumEntries = 137;
5394 info->bmiHeader.biClrUsed = 221;
5395 for (i = 0; i < 256; i++)
5397 palent[i].peRed = i * 2;
5398 palent[i].peGreen = 255 - i;
5399 palent[i].peBlue = i;
5401 palette = CreatePalette( pal );
5402 ok( palette != 0, "palette creation failed\n" );
5403 SelectPalette( hdc, palette, FALSE );
5404 for (i = 0; i < 256; i++) ((WORD *)info->bmiColors)[i] = 255 - i;
5405 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_PAL_COLORS );
5406 ok( ret == 8, "got %d\n", ret );
5407 for (i = 0; i < 64; i++)
5409 int idx = i * 4 + 1;
5410 int ent = (255 - idx) % pal->palNumEntries;
5411 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 :
5412 (palent[ent].peRed << 16 | palent[ent].peGreen << 8 | palent[ent].peBlue);
5413 ok( dib_bits[i] == expect || broken(dib_bits[i] == 0),
5414 "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
5416 memset( dib_bits, 0xaa, 64 * 4 );
5418 DeleteDC( hdc );
5419 DeleteObject( dib );
5420 DeleteObject( palette );
5421 HeapFree( GetProcessHeap(), 0, info );
5424 static void test_SetDIBitsToDevice_RLE8(void)
5426 BITMAPINFO *info;
5427 DWORD *dib_bits;
5428 HDC hdc = CreateCompatibleDC( 0 );
5429 BYTE rle8_data[20] = { 0x04, 0x02, 0x03, 0xf0, 0x00, 0x00, /* 2, 2, 2, 2, f0, f0, f0, <eol> */
5430 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
5431 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
5432 0x00, 0x01 }; /* <eod> */
5433 HBITMAP dib;
5434 int i, ret;
5435 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
5436 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5437 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5438 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
5439 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5440 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5441 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5442 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
5443 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5444 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5445 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 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 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5450 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
5452 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
5454 info->bmiHeader.biSize = sizeof(info->bmiHeader);
5455 info->bmiHeader.biWidth = 8;
5456 info->bmiHeader.biHeight = 8;
5457 info->bmiHeader.biPlanes = 1;
5458 info->bmiHeader.biBitCount = 32;
5459 info->bmiHeader.biCompression = BI_RGB;
5461 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5462 memset( dib_bits, 0xaa, 64 * 4 );
5463 SelectObject( hdc, dib );
5465 info->bmiHeader.biBitCount = 8;
5466 info->bmiHeader.biCompression = BI_RLE8;
5467 info->bmiHeader.biSizeImage = sizeof(rle8_data);
5469 for (i = 0; i < 256; i++)
5471 info->bmiColors[i].rgbRed = i;
5472 info->bmiColors[i].rgbGreen = i;
5473 info->bmiColors[i].rgbBlue = i;
5474 info->bmiColors[i].rgbReserved = 0;
5477 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5478 ok( ret == 8, "got %d\n", ret );
5479 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5480 memset( dib_bits, 0xaa, 64 * 4 );
5482 /* startscan and lines are ignored, unless lines == 0 */
5483 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 8, rle8_data, info, DIB_RGB_COLORS );
5484 ok( ret == 8, "got %d\n", ret );
5485 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5486 memset( dib_bits, 0xaa, 64 * 4 );
5488 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 1, rle8_data, info, DIB_RGB_COLORS );
5489 ok( ret == 8, "got %d\n", ret );
5490 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5491 memset( dib_bits, 0xaa, 64 * 4 );
5493 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 0, rle8_data, info, DIB_RGB_COLORS );
5494 ok( ret == 0, "got %d\n", ret );
5495 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5496 memset( dib_bits, 0xaa, 64 * 4 );
5498 info->bmiHeader.biWidth = 2;
5499 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5500 ok( ret == 8, "got %d\n", ret );
5501 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5502 memset( dib_bits, 0xaa, 64 * 4 );
5504 info->bmiHeader.biWidth = 8;
5505 info->bmiHeader.biHeight = 2;
5506 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5507 ok( ret == 2, "got %d\n", ret );
5508 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5509 memset( dib_bits, 0xaa, 64 * 4 );
5511 info->bmiHeader.biHeight = 9;
5512 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5513 ok( ret == 9, "got %d\n", ret );
5514 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5515 memset( dib_bits, 0xaa, 64 * 4 );
5517 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5518 ok( ret == 9, "got %d\n", ret );
5519 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5520 memset( dib_bits, 0xaa, 64 * 4 );
5522 info->bmiHeader.biHeight = 8;
5523 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 9, rle8_data, info, DIB_RGB_COLORS );
5524 ok( ret == 8, "got %d\n", ret );
5525 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5526 memset( dib_bits, 0xaa, 64 * 4 );
5528 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5529 ok( ret == 8, "got %d\n", ret );
5530 for (i = 0; i < 40; i++) ok( dib_bits[i] == bottom_up[i + 24], "%d: got %08x\n", i, dib_bits[i] );
5531 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5532 memset( dib_bits, 0xaa, 64 * 4 );
5534 ret = SetDIBitsToDevice( hdc, 0, 3, 4, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5535 ok( ret == 8, "got %d\n", ret );
5536 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5537 for (i = 8; i < 40; i++)
5538 if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5539 else ok( dib_bits[i] == bottom_up[i - 8], "%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, 3, 3, 8, 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 & 7) < 3) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5548 else ok( dib_bits[i] == bottom_up[i - 11], "%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, 2, 3, 8, 4, 2, 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) < 2) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5557 else ok( dib_bits[i] == bottom_up[i - 8], "%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 info->bmiHeader.biWidth = 37;
5562 info->bmiHeader.biHeight = 37;
5563 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
5564 ok( ret == 37, "got %d\n", ret );
5565 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5566 for (i = 24; i < 64; i++)
5567 if (i == 52) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
5568 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5569 else ok( dib_bits[i] == bottom_up[i - 20], "%d: got %08x\n", i, dib_bits[i] );
5570 memset( dib_bits, 0xaa, 64 * 4 );
5572 /* top-down compressed dibs are invalid */
5573 info->bmiHeader.biWidth = 8;
5574 info->bmiHeader.biHeight = -8;
5575 SetLastError( 0xdeadbeef );
5576 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5577 ok( ret == 0, "got %d\n", ret );
5578 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
5580 /* top-down dst */
5582 info->bmiHeader.biHeight = -8;
5583 info->bmiHeader.biBitCount = 32;
5584 info->bmiHeader.biCompression = BI_RGB;
5585 info->bmiHeader.biSizeImage = 0;
5587 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5588 memset( dib_bits, 0xaa, 16 * 16 * 4 );
5589 DeleteObject( SelectObject( hdc, dib ));
5591 info->bmiHeader.biHeight = 8;
5592 info->bmiHeader.biBitCount = 8;
5593 info->bmiHeader.biCompression = BI_RLE8;
5594 info->bmiHeader.biSizeImage = sizeof(rle8_data);
5596 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5597 ok( ret == 8, "got %d\n", ret );
5598 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5599 memset( dib_bits, 0xaa, 64 * 4 );
5601 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5602 ok( ret == 8, "got %d\n", ret );
5603 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5604 memset( dib_bits, 0xaa, 64 * 4 );
5606 info->bmiHeader.biHeight = 4;
5607 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5608 ok( ret == 4, "got %d\n", ret );
5609 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5610 memset( dib_bits, 0xaa, 64 * 4 );
5612 info->bmiHeader.biHeight = 9;
5613 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5614 ok( ret == 9, "got %d\n", ret );
5615 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5616 memset( dib_bits, 0xaa, 64 * 4 );
5618 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5619 ok( ret == 9, "got %d\n", ret );
5620 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5621 memset( dib_bits, 0xaa, 64 * 4 );
5623 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 6, 2, 2, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5624 ok( ret == 9, "got %d\n", ret );
5625 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5626 for (i = 24; i < 64; i++) ok( dib_bits[i] == top_down[i - 24], "%d: got %08x\n", i, dib_bits[i] );
5627 memset( dib_bits, 0xaa, 64 * 4 );
5629 info->bmiHeader.biWidth = 37;
5630 info->bmiHeader.biHeight = 37;
5631 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
5632 ok( ret == 37, "got %d\n", ret );
5633 for (i = 0; i < 40; i++)
5634 if (i == 12) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
5635 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5636 else ok( dib_bits[i] == top_down[i + 28], "%d: got %08x\n", i, dib_bits[i] );
5637 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5638 memset( dib_bits, 0xaa, 64 * 4 );
5640 DeleteDC( hdc );
5641 DeleteObject( dib );
5642 HeapFree( GetProcessHeap(), 0, info );
5645 START_TEST(bitmap)
5647 HMODULE hdll;
5649 hdll = GetModuleHandleA("gdi32.dll");
5650 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
5651 pGdiGradientFill = (void*)GetProcAddress(hdll, "GdiGradientFill");
5652 pSetLayout = (void*)GetProcAddress(hdll, "SetLayout");
5654 test_createdibitmap();
5655 test_dibsections();
5656 test_dib_formats();
5657 test_mono_dibsection();
5658 test_bitmap();
5659 test_mono_bitmap();
5660 test_bmBits();
5661 test_GetDIBits_selected_DIB(1);
5662 test_GetDIBits_selected_DIB(4);
5663 test_GetDIBits_selected_DIB(8);
5664 test_GetDIBits_selected_DDB(TRUE);
5665 test_GetDIBits_selected_DDB(FALSE);
5666 test_GetDIBits();
5667 test_GetDIBits_BI_BITFIELDS();
5668 test_select_object();
5669 test_CreateBitmap();
5670 test_BitBlt();
5671 test_StretchBlt();
5672 test_StretchDIBits();
5673 test_GdiAlphaBlend();
5674 test_GdiGradientFill();
5675 test_32bit_ddb();
5676 test_bitmapinfoheadersize();
5677 test_get16dibits();
5678 test_clipping();
5679 test_GetDIBits_top_down(16);
5680 test_GetDIBits_top_down(24);
5681 test_GetDIBits_top_down(32);
5682 test_GetSetDIBits_rtl();
5683 test_GetDIBits_scanlines();
5684 test_SetDIBits();
5685 test_SetDIBits_RLE4();
5686 test_SetDIBits_RLE8();
5687 test_SetDIBitsToDevice();
5688 test_SetDIBitsToDevice_RLE8();