gdi32/tests: Add some tests for behavior of 32-bit DDBs.
[wine/multimedia.git] / dlls / gdi32 / tests / bitmap.c
blob9a34f63b33168bbd78ee2b11e14990e3c4fc38d4
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;
60 BYTE buf[512], buf_cmp[512];
62 ret = GetObject(hbm, sizeof(bm), &bm);
63 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
65 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
66 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
67 ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
68 width_bytes = get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel);
69 ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
70 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
71 ok(bm.bmBitsPixel == expected_depth, "wrong bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, expected_depth);
72 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
74 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
75 assert(sizeof(buf) == sizeof(buf_cmp));
77 SetLastError(0xdeadbeef);
78 ret = GetBitmapBits(hbm, 0, NULL);
79 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
81 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
82 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
84 memset(buf, 0xAA, sizeof(buf));
85 ret = GetBitmapBits(hbm, sizeof(buf), buf);
86 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
87 ok(!memcmp(buf, buf_cmp, sizeof(buf)),
88 "buffers do not match, depth %d\n", bmih->biBitCount);
90 /* test various buffer sizes for GetObject */
91 ret = GetObject(hbm, sizeof(*bma) * 2, bma);
92 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
94 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
95 ok(ret == 0, "%d != 0\n", ret);
97 ret = GetObject(hbm, 0, &bm);
98 ok(ret == 0, "%d != 0\n", ret);
100 ret = GetObject(hbm, 1, &bm);
101 ok(ret == 0, "%d != 0\n", ret);
103 ret = GetObject(hbm, 0, NULL);
104 ok(ret == sizeof(bm), "wrong size %d\n", ret);
107 static void test_createdibitmap(void)
109 HDC hdc, hdcmem;
110 BITMAPINFOHEADER bmih;
111 BITMAPINFO bm;
112 HBITMAP hbm, hbm_colour, hbm_old;
113 INT screen_depth;
114 DWORD pixel;
116 hdc = GetDC(0);
117 screen_depth = GetDeviceCaps(hdc, BITSPIXEL);
118 memset(&bmih, 0, sizeof(bmih));
119 bmih.biSize = sizeof(bmih);
120 bmih.biWidth = 10;
121 bmih.biHeight = 10;
122 bmih.biPlanes = 1;
123 bmih.biBitCount = 32;
124 bmih.biCompression = BI_RGB;
126 hbm = CreateDIBitmap(hdc, NULL, CBM_INIT, NULL, NULL, 0);
127 ok(hbm == NULL, "CreateDIBitmap should fail\n");
128 hbm = CreateDIBitmap(hdc, NULL, 0, NULL, NULL, 0);
129 ok(hbm == NULL, "CreateDIBitmap should fail\n");
131 /* First create an un-initialised bitmap. The depth of the bitmap
132 should match that of the hdc and not that supplied in bmih.
135 /* First try 32 bits */
136 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
137 ok(hbm != NULL, "CreateDIBitmap failed\n");
138 test_bitmap_info(hbm, screen_depth, &bmih);
139 DeleteObject(hbm);
141 /* Then 16 */
142 bmih.biBitCount = 16;
143 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
144 ok(hbm != NULL, "CreateDIBitmap failed\n");
145 test_bitmap_info(hbm, screen_depth, &bmih);
146 DeleteObject(hbm);
148 /* Then 1 */
149 bmih.biBitCount = 1;
150 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
151 ok(hbm != NULL, "CreateDIBitmap failed\n");
152 test_bitmap_info(hbm, screen_depth, &bmih);
153 DeleteObject(hbm);
155 /* Now with a monochrome dc we expect a monochrome bitmap */
156 hdcmem = CreateCompatibleDC(hdc);
158 /* First try 32 bits */
159 bmih.biBitCount = 32;
160 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
161 ok(hbm != NULL, "CreateDIBitmap failed\n");
162 test_bitmap_info(hbm, 1, &bmih);
163 DeleteObject(hbm);
165 /* Then 16 */
166 bmih.biBitCount = 16;
167 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
168 ok(hbm != NULL, "CreateDIBitmap failed\n");
169 test_bitmap_info(hbm, 1, &bmih);
170 DeleteObject(hbm);
172 /* Then 1 */
173 bmih.biBitCount = 1;
174 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
175 ok(hbm != NULL, "CreateDIBitmap failed\n");
176 test_bitmap_info(hbm, 1, &bmih);
177 DeleteObject(hbm);
179 /* Now select a polychrome bitmap into the dc and we expect
180 screen_depth bitmaps again */
181 hbm_colour = CreateCompatibleBitmap(hdc, bmih.biWidth, bmih.biHeight);
182 test_bitmap_info(hbm_colour, screen_depth, &bmih);
183 hbm_old = SelectObject(hdcmem, hbm_colour);
185 /* First try 32 bits */
186 bmih.biBitCount = 32;
187 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
188 ok(hbm != NULL, "CreateDIBitmap failed\n");
189 test_bitmap_info(hbm, screen_depth, &bmih);
190 DeleteObject(hbm);
192 /* Then 16 */
193 bmih.biBitCount = 16;
194 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
195 ok(hbm != NULL, "CreateDIBitmap failed\n");
196 test_bitmap_info(hbm, screen_depth, &bmih);
197 DeleteObject(hbm);
199 /* Then 1 */
200 bmih.biBitCount = 1;
201 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
202 ok(hbm != NULL, "CreateDIBitmap failed\n");
203 test_bitmap_info(hbm, screen_depth, &bmih);
204 DeleteObject(hbm);
206 SelectObject(hdcmem, hbm_old);
207 DeleteObject(hbm_colour);
208 DeleteDC(hdcmem);
210 bmih.biBitCount = 32;
211 hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0);
212 ok(hbm != NULL, "CreateDIBitmap failed\n");
213 test_bitmap_info(hbm, 1, &bmih);
214 DeleteObject(hbm);
216 /* Test how formats are converted */
217 pixel = 0xffffffff;
218 bmih.biBitCount = 1;
219 bmih.biWidth = 1;
220 bmih.biHeight = 1;
222 memset(&bm, 0, sizeof(bm));
223 bm.bmiHeader.biSize = sizeof(bm.bmiHeader);
224 bm.bmiHeader.biWidth = 1;
225 bm.bmiHeader.biHeight = 1;
226 bm.bmiHeader.biPlanes = 1;
227 bm.bmiHeader.biBitCount= 24;
228 bm.bmiHeader.biCompression= BI_RGB;
229 bm.bmiHeader.biSizeImage = 0;
230 hbm = CreateDIBitmap(hdc, &bmih, CBM_INIT, &pixel, &bm, DIB_RGB_COLORS);
231 ok(hbm != NULL, "CreateDIBitmap failed\n");
233 pixel = 0xdeadbeef;
234 bm.bmiHeader.biBitCount= 32;
235 GetDIBits(hdc, hbm, 0, 1, &pixel, &bm, DIB_RGB_COLORS);
236 ok(pixel == 0x00ffffff, "Reading a 32 bit pixel from a DDB returned %08x\n", pixel);
237 DeleteObject(hbm);
239 ReleaseDC(0, hdc);
242 static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
244 BITMAP bm;
245 BITMAP bma[2];
246 DIBSECTION ds;
247 DIBSECTION dsa[2];
248 INT ret, bm_width_bytes, dib_width_bytes;
249 BYTE *buf;
251 ret = GetObject(hbm, sizeof(bm), &bm);
252 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
254 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
255 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
256 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
257 dib_width_bytes = get_dib_stride(bm.bmWidth, bm.bmBitsPixel);
258 bm_width_bytes = get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel);
259 if (bm.bmWidthBytes != dib_width_bytes) /* Win2k bug */
260 ok(bm.bmWidthBytes == bm_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, bm_width_bytes);
261 else
262 ok(bm.bmWidthBytes == dib_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, dib_width_bytes);
263 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
264 ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount);
265 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
267 buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);
269 /* GetBitmapBits returns not 32-bit aligned data */
270 SetLastError(0xdeadbeef);
271 ret = GetBitmapBits(hbm, 0, NULL);
272 ok(ret == bm_width_bytes * bm.bmHeight,
273 "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
275 memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
276 ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
277 ok(ret == bm_width_bytes * bm.bmHeight, "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
279 HeapFree(GetProcessHeap(), 0, buf);
281 /* test various buffer sizes for GetObject */
282 memset(&ds, 0xAA, sizeof(ds));
283 ret = GetObject(hbm, sizeof(*bma) * 2, bma);
284 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
285 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
286 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
287 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
289 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
290 ok(ret == 0, "%d != 0\n", ret);
292 ret = GetObject(hbm, 0, &bm);
293 ok(ret == 0, "%d != 0\n", ret);
295 ret = GetObject(hbm, 1, &bm);
296 ok(ret == 0, "%d != 0\n", ret);
298 /* test various buffer sizes for GetObject */
299 ret = GetObject(hbm, 0, NULL);
300 ok(ret == sizeof(bm), "wrong size %d\n", ret);
302 ret = GetObject(hbm, sizeof(*dsa) * 2, dsa);
303 ok(ret == sizeof(*dsa), "wrong size %d\n", ret);
305 memset(&ds, 0xAA, sizeof(ds));
306 ret = GetObject(hbm, sizeof(ds), &ds);
307 ok(ret == sizeof(ds), "wrong size %d\n", ret);
309 ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
310 if (ds.dsBm.bmWidthBytes != bm_width_bytes) /* Win2k bug */
311 ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%u != %u\n",
312 ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
313 ok(bmih->biSizeImage == 0, "%u != 0\n", bmih->biSizeImage);
314 ds.dsBmih.biSizeImage = 0;
316 ok(ds.dsBmih.biSize == bmih->biSize, "%u != %u\n", ds.dsBmih.biSize, bmih->biSize);
317 ok(ds.dsBmih.biWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
318 ok(ds.dsBmih.biHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
319 ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes);
320 ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount);
321 ok(ds.dsBmih.biCompression == bmih->biCompression ||
322 ((bmih->biBitCount == 32) && broken(ds.dsBmih.biCompression == BI_BITFIELDS)), /* nt4 sp1 and 2 */
323 "%u != %u\n", ds.dsBmih.biCompression, bmih->biCompression);
324 ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%u != %u\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
325 ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%d != %d\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
326 ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%d != %d\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);
328 memset(&ds, 0xAA, sizeof(ds));
329 ret = GetObject(hbm, sizeof(ds) - 4, &ds);
330 ok(ret == sizeof(ds.dsBm), "wrong size %d\n", ret);
331 ok(ds.dsBm.bmWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
332 ok(ds.dsBm.bmHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
333 ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);
335 ret = GetObject(hbm, 0, &ds);
336 ok(ret == 0, "%d != 0\n", ret);
338 ret = GetObject(hbm, 1, &ds);
339 ok(ret == 0, "%d != 0\n", ret);
342 #define test_color(hdc, color, exp) \
344 COLORREF c; \
345 c = SetPixel(hdc, 0, 0, color); \
346 ok(c == exp, "SetPixel failed: got 0x%06x expected 0x%06x\n", c, (UINT)exp); \
347 c = GetPixel(hdc, 0, 0); \
348 ok(c == exp, "GetPixel failed: got 0x%06x expected 0x%06x\n", c, (UINT)exp); \
349 c = GetNearestColor(hdc, color); \
350 ok(c == exp, "GetNearestColor failed: got 0x%06x expected 0x%06x\n", c, (UINT)exp); \
353 static void test_dib_bits_access( HBITMAP hdib, void *bits )
355 MEMORY_BASIC_INFORMATION info;
356 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
357 DWORD data[256];
358 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
359 HDC hdc;
360 char filename[MAX_PATH];
361 HANDLE file;
362 DWORD written;
363 INT ret;
365 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
366 "VirtualQuery failed\n");
367 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
368 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
369 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
370 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
371 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
372 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
374 memset( pbmi, 0, sizeof(bmibuf) );
375 memset( data, 0xcc, sizeof(data) );
376 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
377 pbmi->bmiHeader.biHeight = 16;
378 pbmi->bmiHeader.biWidth = 16;
379 pbmi->bmiHeader.biBitCount = 32;
380 pbmi->bmiHeader.biPlanes = 1;
381 pbmi->bmiHeader.biCompression = BI_RGB;
383 hdc = GetDC(0);
385 ret = SetDIBits( hdc, hdib, 0, 16, data, pbmi, DIB_RGB_COLORS );
386 ok(ret == 16, "SetDIBits failed: expected 16 got %d\n", ret);
388 ReleaseDC(0, hdc);
390 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
391 "VirtualQuery failed\n");
392 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
393 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
394 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
395 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
396 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
397 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
399 /* try writing protected bits to a file */
401 GetTempFileNameA( ".", "dib", 0, filename );
402 file = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
403 CREATE_ALWAYS, 0, 0 );
404 ok( file != INVALID_HANDLE_VALUE, "failed to open %s error %u\n", filename, GetLastError() );
405 ret = WriteFile( file, bits, 8192, &written, NULL );
406 ok( ret, "WriteFile failed error %u\n", GetLastError() );
407 if (ret) ok( written == 8192, "only wrote %u bytes\n", written );
408 CloseHandle( file );
409 DeleteFileA( filename );
412 static void test_dibsections(void)
414 HDC hdc, hdcmem, hdcmem2;
415 HBITMAP hdib, oldbm, hdib2, oldbm2;
416 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
417 char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
418 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
419 BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
420 RGBQUAD *colors = pbmi->bmiColors;
421 RGBTRIPLE *ccolors = pbci->bmciColors;
422 HBITMAP hcoredib;
423 char coreBits[256];
424 BYTE *bits;
425 RGBQUAD rgb[256];
426 int ret;
427 char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
428 LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
429 PALETTEENTRY *palent = plogpal->palPalEntry;
430 WORD *index;
431 DWORD *bits32;
432 HPALETTE hpal, oldpal;
433 DIBSECTION dibsec;
434 COLORREF c0, c1;
435 int i;
436 MEMORY_BASIC_INFORMATION info;
438 hdc = GetDC(0);
440 memset(pbmi, 0, sizeof(bmibuf));
441 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
442 pbmi->bmiHeader.biHeight = 100;
443 pbmi->bmiHeader.biWidth = 512;
444 pbmi->bmiHeader.biBitCount = 24;
445 pbmi->bmiHeader.biPlanes = 1;
446 pbmi->bmiHeader.biCompression = BI_RGB;
448 SetLastError(0xdeadbeef);
450 /* invalid pointer for BITMAPINFO
451 (*bits should be NULL on error) */
452 bits = (BYTE*)0xdeadbeef;
453 hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
454 ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n");
456 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
457 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
458 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
459 ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
461 /* test the DIB memory */
462 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
463 "VirtualQuery failed\n");
464 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
465 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
466 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
467 ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
468 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
469 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
470 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
472 test_dib_bits_access( hdib, bits );
474 test_dib_info(hdib, bits, &pbmi->bmiHeader);
475 DeleteObject(hdib);
477 /* Test a top-down DIB. */
478 pbmi->bmiHeader.biHeight = -100;
479 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
480 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
481 test_dib_info(hdib, bits, &pbmi->bmiHeader);
482 DeleteObject(hdib);
484 pbmi->bmiHeader.biHeight = 100;
485 pbmi->bmiHeader.biBitCount = 8;
486 pbmi->bmiHeader.biCompression = BI_RLE8;
487 SetLastError(0xdeadbeef);
488 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
489 ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
490 ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
492 pbmi->bmiHeader.biBitCount = 16;
493 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
494 ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
495 ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
496 ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
497 SetLastError(0xdeadbeef);
498 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
499 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
501 /* test the DIB memory */
502 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
503 "VirtualQuery failed\n");
504 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
505 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
506 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
507 ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
508 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
509 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
510 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
512 test_dib_info(hdib, bits, &pbmi->bmiHeader);
513 DeleteObject(hdib);
515 memset(pbmi, 0, sizeof(bmibuf));
516 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
517 pbmi->bmiHeader.biHeight = 16;
518 pbmi->bmiHeader.biWidth = 16;
519 pbmi->bmiHeader.biBitCount = 1;
520 pbmi->bmiHeader.biPlanes = 1;
521 pbmi->bmiHeader.biCompression = BI_RGB;
522 colors[0].rgbRed = 0xff;
523 colors[0].rgbGreen = 0;
524 colors[0].rgbBlue = 0;
525 colors[1].rgbRed = 0;
526 colors[1].rgbGreen = 0;
527 colors[1].rgbBlue = 0xff;
529 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
530 ok(hdib != NULL, "CreateDIBSection failed\n");
531 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
532 ok(dibsec.dsBmih.biClrUsed == 2,
533 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
535 /* Test if the old BITMAPCOREINFO structure is supported */
537 pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
538 pbci->bmciHeader.bcBitCount = 0;
540 ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
541 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
542 ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
543 && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
544 "GetDIBits didn't fill in the BITMAPCOREHEADER structure properly\n");
546 ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
547 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
548 ok((ccolors[0].rgbtRed == 0xff) && (ccolors[0].rgbtGreen == 0) &&
549 (ccolors[0].rgbtBlue == 0) && (ccolors[1].rgbtRed == 0) &&
550 (ccolors[1].rgbtGreen == 0) && (ccolors[1].rgbtBlue == 0xff),
551 "The color table has not been translated to the old BITMAPCOREINFO format\n");
553 hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
554 ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
556 ZeroMemory(ccolors, 256 * sizeof(RGBTRIPLE));
557 ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
558 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
559 ok((ccolors[0].rgbtRed == 0xff) && (ccolors[0].rgbtGreen == 0) &&
560 (ccolors[0].rgbtBlue == 0) && (ccolors[1].rgbtRed == 0) &&
561 (ccolors[1].rgbtGreen == 0) && (ccolors[1].rgbtBlue == 0xff),
562 "The color table has not been translated to the old BITMAPCOREINFO format\n");
564 DeleteObject(hcoredib);
566 hdcmem = CreateCompatibleDC(hdc);
567 oldbm = SelectObject(hdcmem, hdib);
569 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
570 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
571 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
572 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
573 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
574 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
576 c0 = RGB(colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue);
577 c1 = RGB(colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue);
579 test_color(hdcmem, DIBINDEX(0), c0);
580 test_color(hdcmem, DIBINDEX(1), c1);
581 test_color(hdcmem, DIBINDEX(2), c0);
582 test_color(hdcmem, PALETTEINDEX(0), c0);
583 test_color(hdcmem, PALETTEINDEX(1), c0);
584 test_color(hdcmem, PALETTEINDEX(2), c0);
585 test_color(hdcmem, PALETTERGB(colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue), c0);
586 test_color(hdcmem, PALETTERGB(colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue), c1);
587 test_color(hdcmem, PALETTERGB(0, 0, 0), c0);
588 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0);
589 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1);
591 SelectObject(hdcmem, oldbm);
592 DeleteObject(hdib);
594 colors[0].rgbRed = 0xff;
595 colors[0].rgbGreen = 0xff;
596 colors[0].rgbBlue = 0xff;
597 colors[1].rgbRed = 0;
598 colors[1].rgbGreen = 0;
599 colors[1].rgbBlue = 0;
601 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
602 ok(hdib != NULL, "CreateDIBSection failed\n");
604 test_dib_info(hdib, bits, &pbmi->bmiHeader);
606 oldbm = SelectObject(hdcmem, hdib);
608 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
609 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
610 ok(!memcmp(rgb, colors, 2 * sizeof(RGBQUAD)),
611 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
612 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
613 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
615 SelectObject(hdcmem, oldbm);
616 test_dib_info(hdib, bits, &pbmi->bmiHeader);
617 DeleteObject(hdib);
619 pbmi->bmiHeader.biBitCount = 4;
620 for (i = 0; i < 16; i++) {
621 colors[i].rgbRed = i;
622 colors[i].rgbGreen = 16-i;
623 colors[i].rgbBlue = 0;
625 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
626 ok(hdib != NULL, "CreateDIBSection failed\n");
627 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
628 ok(dibsec.dsBmih.biClrUsed == 16,
629 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
630 test_dib_info(hdib, bits, &pbmi->bmiHeader);
631 DeleteObject(hdib);
633 pbmi->bmiHeader.biBitCount = 8;
635 for (i = 0; i < 128; i++) {
636 colors[i].rgbRed = 255 - i * 2;
637 colors[i].rgbGreen = i * 2;
638 colors[i].rgbBlue = 0;
639 colors[255 - i].rgbRed = 0;
640 colors[255 - i].rgbGreen = i * 2;
641 colors[255 - i].rgbBlue = 255 - i * 2;
643 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
644 ok(hdib != NULL, "CreateDIBSection failed\n");
645 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
646 ok(dibsec.dsBmih.biClrUsed == 256,
647 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
649 oldbm = SelectObject(hdcmem, hdib);
651 for (i = 0; i < 256; i++) {
652 test_color(hdcmem, DIBINDEX(i), RGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue));
653 test_color(hdcmem, PALETTERGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue),
654 RGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue));
657 SelectObject(hdcmem, oldbm);
658 test_dib_info(hdib, bits, &pbmi->bmiHeader);
659 DeleteObject(hdib);
661 pbmi->bmiHeader.biBitCount = 1;
663 /* Now create a palette and a palette indexed dib section */
664 memset(plogpal, 0, sizeof(logpalbuf));
665 plogpal->palVersion = 0x300;
666 plogpal->palNumEntries = 2;
667 palent[0].peRed = 0xff;
668 palent[0].peBlue = 0xff;
669 palent[1].peGreen = 0xff;
671 index = (WORD*)pbmi->bmiColors;
672 *index++ = 0;
673 *index = 1;
674 hpal = CreatePalette(plogpal);
675 ok(hpal != NULL, "CreatePalette failed\n");
676 oldpal = SelectPalette(hdc, hpal, TRUE);
677 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
678 ok(hdib != NULL, "CreateDIBSection failed\n");
679 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
680 ok(dibsec.dsBmih.biClrUsed == 2, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
682 /* The colour table has already been grabbed from the dc, so we select back the
683 old palette */
685 SelectPalette(hdc, oldpal, TRUE);
686 oldbm = SelectObject(hdcmem, hdib);
687 oldpal = SelectPalette(hdcmem, hpal, TRUE);
689 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
690 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
691 ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
692 rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
693 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
694 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
695 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
697 c0 = RGB(palent[0].peRed, palent[0].peGreen, palent[0].peBlue);
698 c1 = RGB(palent[1].peRed, palent[1].peGreen, palent[1].peBlue);
700 test_color(hdcmem, DIBINDEX(0), c0);
701 test_color(hdcmem, DIBINDEX(1), c1);
702 test_color(hdcmem, DIBINDEX(2), c0);
703 test_color(hdcmem, PALETTEINDEX(0), c0);
704 test_color(hdcmem, PALETTEINDEX(1), c1);
705 test_color(hdcmem, PALETTEINDEX(2), c0);
706 test_color(hdcmem, PALETTERGB(palent[0].peRed, palent[0].peGreen, palent[0].peBlue), c0);
707 test_color(hdcmem, PALETTERGB(palent[1].peRed, palent[1].peGreen, palent[1].peBlue), c1);
708 test_color(hdcmem, PALETTERGB(0, 0, 0), c1);
709 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0);
710 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0);
711 test_color(hdcmem, PALETTERGB(0, 1, 0), c1);
712 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1);
713 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0);
715 /* Bottom and 2nd row from top green, everything else magenta */
716 bits[0] = bits[1] = 0xff;
717 bits[13 * 4] = bits[13*4 + 1] = 0xff;
719 test_dib_info(hdib, bits, &pbmi->bmiHeader);
721 pbmi->bmiHeader.biBitCount = 32;
723 hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
724 ok(hdib2 != NULL, "CreateDIBSection failed\n");
725 hdcmem2 = CreateCompatibleDC(hdc);
726 oldbm2 = SelectObject(hdcmem2, hdib2);
728 BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
730 ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
731 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
733 SelectObject(hdcmem2, oldbm2);
734 test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
735 DeleteObject(hdib2);
737 SelectObject(hdcmem, oldbm);
738 SelectPalette(hdcmem, oldpal, TRUE);
739 DeleteObject(hdib);
740 DeleteObject(hpal);
743 pbmi->bmiHeader.biBitCount = 8;
745 memset(plogpal, 0, sizeof(logpalbuf));
746 plogpal->palVersion = 0x300;
747 plogpal->palNumEntries = 256;
749 for (i = 0; i < 128; i++) {
750 palent[i].peRed = 255 - i * 2;
751 palent[i].peBlue = i * 2;
752 palent[i].peGreen = 0;
753 palent[255 - i].peRed = 0;
754 palent[255 - i].peGreen = i * 2;
755 palent[255 - i].peBlue = 255 - i * 2;
758 index = (WORD*)pbmi->bmiColors;
759 for (i = 0; i < 256; i++) {
760 *index++ = i;
763 hpal = CreatePalette(plogpal);
764 ok(hpal != NULL, "CreatePalette failed\n");
765 oldpal = SelectPalette(hdc, hpal, TRUE);
766 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
767 ok(hdib != NULL, "CreateDIBSection failed\n");
768 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
769 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
771 test_dib_info(hdib, bits, &pbmi->bmiHeader);
773 SelectPalette(hdc, oldpal, TRUE);
774 oldbm = SelectObject(hdcmem, hdib);
775 oldpal = SelectPalette(hdcmem, hpal, TRUE);
777 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
778 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
779 for (i = 0; i < 256; i++) {
780 ok(rgb[i].rgbRed == palent[i].peRed &&
781 rgb[i].rgbBlue == palent[i].peBlue &&
782 rgb[i].rgbGreen == palent[i].peGreen,
783 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
784 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
787 for (i = 0; i < 256; i++) {
788 test_color(hdcmem, DIBINDEX(i), RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
789 test_color(hdcmem, PALETTEINDEX(i), RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
790 test_color(hdcmem, PALETTERGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue),
791 RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
794 SelectPalette(hdcmem, oldpal, TRUE);
795 SelectObject(hdcmem, oldbm);
796 DeleteObject(hdib);
797 DeleteObject(hpal);
799 plogpal->palNumEntries = 37;
800 hpal = CreatePalette(plogpal);
801 ok(hpal != NULL, "CreatePalette failed\n");
802 oldpal = SelectPalette(hdc, hpal, TRUE);
803 pbmi->bmiHeader.biClrUsed = 142;
804 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
805 ok(hdib != NULL, "CreateDIBSection failed\n");
806 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
807 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
809 test_dib_info(hdib, bits, &pbmi->bmiHeader);
811 SelectPalette(hdc, oldpal, TRUE);
812 oldbm = SelectObject(hdcmem, hdib);
814 memset( rgb, 0xcc, sizeof(rgb) );
815 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
816 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
817 for (i = 0; i < 256; i++)
819 if (i < pbmi->bmiHeader.biClrUsed)
821 ok(rgb[i].rgbRed == palent[i % 37].peRed &&
822 rgb[i].rgbBlue == palent[i % 37].peBlue &&
823 rgb[i].rgbGreen == palent[i % 37].peGreen,
824 "GetDIBColorTable returns table %d: r %02x g %02x b %02x res%02x\n",
825 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
826 test_color(hdcmem, DIBINDEX(i),
827 RGB(palent[i % 37].peRed, palent[i % 37].peGreen, palent[i % 37].peBlue));
829 else
831 ok(rgb[i].rgbRed == 0 && rgb[i].rgbBlue == 0 && rgb[i].rgbGreen == 0,
832 "GetDIBColorTable returns table %d: r %02x g %02x b %02x res%02x\n",
833 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
834 test_color(hdcmem, DIBINDEX(i), 0 );
837 pbmi->bmiHeader.biClrUsed = 173;
838 memset( pbmi->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
839 GetDIBits( hdc, hdib, 0, 1, bits, pbmi, DIB_RGB_COLORS );
840 ok( pbmi->bmiHeader.biClrUsed == 0, "wrong colors %u\n", pbmi->bmiHeader.biClrUsed );
841 for (i = 0; i < 256; i++)
843 if (i < 142)
844 ok(colors[i].rgbRed == palent[i % 37].peRed &&
845 colors[i].rgbBlue == palent[i % 37].peBlue &&
846 colors[i].rgbGreen == palent[i % 37].peGreen,
847 "GetDIBits returns table %d: r %02x g %02x b %02x res%02x\n",
848 i, colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
849 else
850 ok(colors[i].rgbRed == 0 && colors[i].rgbBlue == 0 && colors[i].rgbGreen == 0,
851 "GetDIBits returns table %d: r %02x g %02x b %02x res%02x\n",
852 i, colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
855 SelectObject(hdcmem, oldbm);
856 DeleteObject(hdib);
857 DeleteObject(hpal);
859 /* ClrUsed ignored on > 8bpp */
860 pbmi->bmiHeader.biBitCount = 16;
861 pbmi->bmiHeader.biClrUsed = 37;
862 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
863 ok(hdib != NULL, "CreateDIBSection failed\n");
864 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
865 ok(dibsec.dsBmih.biClrUsed == 0, "created DIBSection: wrong biClrUsed field: %u\n", dibsec.dsBmih.biClrUsed);
866 oldbm = SelectObject(hdcmem, hdib);
867 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
868 ok(ret == 0, "GetDIBColorTable returned %d\n", ret);
869 SelectObject(hdcmem, oldbm);
870 DeleteObject(hdib);
872 DeleteDC(hdcmem);
873 DeleteDC(hdcmem2);
874 ReleaseDC(0, hdc);
877 static void test_dib_formats(void)
879 BITMAPINFO *bi;
880 char data[256];
881 void *bits;
882 int planes, bpp, compr, format;
883 HBITMAP hdib, hbmp;
884 HDC hdc, memdc;
885 UINT ret;
886 BOOL format_ok, expect_ok;
888 bi = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
889 hdc = GetDC( 0 );
890 memdc = CreateCompatibleDC( 0 );
891 hbmp = CreateCompatibleBitmap( hdc, 10, 10 );
893 memset( data, 0xaa, sizeof(data) );
895 for (bpp = 0; bpp <= 64; bpp++)
897 for (planes = 0; planes <= 64; planes++)
899 for (compr = 0; compr < 8; compr++)
901 for (format = DIB_RGB_COLORS; format <= DIB_PAL_COLORS; format++)
903 switch (bpp)
905 case 1:
906 case 4:
907 case 8:
908 case 24: expect_ok = (compr == BI_RGB); break;
909 case 16:
910 case 32: expect_ok = (compr == BI_RGB || compr == BI_BITFIELDS); break;
911 default: expect_ok = FALSE; break;
914 memset( bi, 0, sizeof(bi->bmiHeader) );
915 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
916 bi->bmiHeader.biWidth = 2;
917 bi->bmiHeader.biHeight = 2;
918 bi->bmiHeader.biPlanes = planes;
919 bi->bmiHeader.biBitCount = bpp;
920 bi->bmiHeader.biCompression = compr;
921 bi->bmiHeader.biSizeImage = 0;
922 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
923 ret = GetDIBits(hdc, hbmp, 0, 0, data, bi, format);
924 if (expect_ok || (!bpp && compr != BI_JPEG && compr != BI_PNG) ||
925 (bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8))
926 ok( ret, "GetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
927 else
928 ok( !ret || broken(!bpp && (compr == BI_JPEG || compr == BI_PNG)), /* nt4 */
929 "GetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
931 /* all functions check planes except GetDIBits with 0 lines */
932 format_ok = expect_ok;
933 if (!planes) expect_ok = FALSE;
934 memset( bi, 0, sizeof(bi->bmiHeader) );
935 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
936 bi->bmiHeader.biWidth = 2;
937 bi->bmiHeader.biHeight = 2;
938 bi->bmiHeader.biPlanes = planes;
939 bi->bmiHeader.biBitCount = bpp;
940 bi->bmiHeader.biCompression = compr;
941 bi->bmiHeader.biSizeImage = 0;
942 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
944 hdib = CreateDIBSection(hdc, bi, format, &bits, NULL, 0);
945 if (expect_ok && (planes == 1 || planes * bpp <= 16) &&
946 (compr != BI_BITFIELDS || format != DIB_PAL_COLORS))
947 ok( hdib != NULL, "CreateDIBSection failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
948 else
949 ok( hdib == NULL, "CreateDIBSection succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
950 if (hdib) DeleteObject( hdib );
952 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, data, bi, format );
953 /* no sanity checks in CreateDIBitmap except compression */
954 if (compr == BI_JPEG || compr == BI_PNG)
955 ok( hdib == NULL || broken(hdib != NULL), /* nt4 */
956 "CreateDIBitmap succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
957 else
958 ok( hdib != NULL, "CreateDIBitmap failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
959 if (hdib) DeleteObject( hdib );
961 /* RLE needs a size */
962 bi->bmiHeader.biSizeImage = 0;
963 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, format);
964 if (expect_ok)
965 ok( ret, "SetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
966 else
967 ok( !ret ||
968 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
969 "SetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
970 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, format );
971 if (expect_ok)
972 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
973 else
974 ok( !ret ||
975 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
976 "SetDIBitsToDevice succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
977 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, format, SRCCOPY );
978 if (expect_ok)
979 ok( ret, "StretchDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
980 else
981 ok( !ret ||
982 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
983 "StretchDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
985 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, format);
986 if (expect_ok)
987 ok( ret, "GetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
988 else
989 ok( !ret, "GetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
990 ok( bi->bmiHeader.biBitCount == bpp, "GetDIBits modified bpp %u/%u\n",
991 bpp, bi->bmiHeader.biBitCount );
993 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
994 bi->bmiHeader.biWidth = 2;
995 bi->bmiHeader.biHeight = 2;
996 bi->bmiHeader.biPlanes = planes;
997 bi->bmiHeader.biBitCount = bpp;
998 bi->bmiHeader.biCompression = compr;
999 bi->bmiHeader.biSizeImage = 1;
1000 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
1001 /* RLE allowed with valid biSizeImage */
1002 if ((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)) expect_ok = TRUE;
1004 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, format);
1005 if (expect_ok)
1006 ok( ret, "SetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1007 else
1008 ok( !ret, "SetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1009 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, format );
1010 if (expect_ok)
1011 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1012 else
1013 ok( !ret, "SetDIBitsToDevice succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1014 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, format, SRCCOPY );
1015 if (expect_ok)
1016 ok( ret, "StretchDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1017 else
1018 ok( !ret, "StretchDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1020 bi->bmiHeader.biSizeImage = 0;
1021 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, format);
1022 if (expect_ok || !bpp)
1023 ok( ret, "GetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1024 else
1025 ok( !ret || broken(format_ok && !planes), /* nt4 */
1026 "GetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1032 memset( bi, 0, sizeof(bi->bmiHeader) );
1033 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1034 bi->bmiHeader.biWidth = 2;
1035 bi->bmiHeader.biHeight = 2;
1036 bi->bmiHeader.biPlanes = 1;
1037 bi->bmiHeader.biBitCount = 16;
1038 bi->bmiHeader.biCompression = BI_BITFIELDS;
1039 bi->bmiHeader.biSizeImage = 0;
1040 *(DWORD *)&bi->bmiColors[0] = 0;
1041 *(DWORD *)&bi->bmiColors[1] = 0;
1042 *(DWORD *)&bi->bmiColors[2] = 0;
1044 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1045 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1046 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1047 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1048 /* other functions don't check */
1049 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1050 ok( hdib != NULL, "CreateDIBitmap failed with null bitfields\n" );
1051 DeleteObject( hdib );
1052 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1053 ok( ret, "SetDIBitsToDevice failed with null bitfields\n" );
1054 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1055 ok( ret, "StretchDIBits failed with null bitfields\n" );
1056 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1057 ok( ret, "GetDIBits failed with null bitfields\n" );
1058 bi->bmiHeader.biPlanes = 1;
1059 bi->bmiHeader.biBitCount = 16;
1060 bi->bmiHeader.biCompression = BI_BITFIELDS;
1061 bi->bmiHeader.biSizeImage = 0;
1062 *(DWORD *)&bi->bmiColors[0] = 0;
1063 *(DWORD *)&bi->bmiColors[1] = 0;
1064 *(DWORD *)&bi->bmiColors[2] = 0;
1065 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1066 ok( ret, "GetDIBits failed with null bitfields\n" );
1068 /* all fields must be non-zero */
1069 *(DWORD *)&bi->bmiColors[0] = 3;
1070 *(DWORD *)&bi->bmiColors[1] = 0;
1071 *(DWORD *)&bi->bmiColors[2] = 7;
1072 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1073 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1074 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1075 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1077 /* garbage is ok though */
1078 *(DWORD *)&bi->bmiColors[0] = 0x55;
1079 *(DWORD *)&bi->bmiColors[1] = 0x44;
1080 *(DWORD *)&bi->bmiColors[2] = 0x33;
1081 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1082 ok( hdib != NULL, "CreateDIBSection failed with bad bitfields\n" );
1083 if (hdib) DeleteObject( hdib );
1084 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1085 ok( ret, "SetDIBits failed with bad bitfields\n" );
1087 bi->bmiHeader.biWidth = -2;
1088 bi->bmiHeader.biHeight = 2;
1089 bi->bmiHeader.biBitCount = 32;
1090 bi->bmiHeader.biCompression = BI_RGB;
1091 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1092 ok( hdib == NULL, "CreateDIBSection succeeded with negative width\n" );
1093 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1094 ok( hdib == NULL, "CreateDIBitmap succeeded with negative width\n" );
1095 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1096 ok( !ret, "SetDIBits succeeded with negative width\n" );
1097 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1098 ok( !ret, "SetDIBitsToDevice succeeded with negative width\n" );
1099 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1100 ok( !ret, "StretchDIBits succeeded with negative width\n" );
1101 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1102 ok( !ret, "GetDIBits succeeded with negative width\n" );
1103 bi->bmiHeader.biWidth = -2;
1104 bi->bmiHeader.biHeight = 2;
1105 bi->bmiHeader.biBitCount = 32;
1106 bi->bmiHeader.biCompression = BI_RGB;
1107 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1108 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with negative width\n" );
1110 bi->bmiHeader.biWidth = 0;
1111 bi->bmiHeader.biHeight = 2;
1112 bi->bmiHeader.biBitCount = 32;
1113 bi->bmiHeader.biCompression = BI_RGB;
1114 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1115 ok( hdib == NULL, "CreateDIBSection succeeded with zero width\n" );
1116 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1117 ok( hdib != NULL, "CreateDIBitmap failed with zero width\n" );
1118 DeleteObject( hdib );
1119 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1120 ok( !ret || broken(ret), /* nt4 */ "SetDIBits succeeded with zero width\n" );
1121 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1122 ok( !ret || broken(ret), /* nt4 */ "SetDIBitsToDevice succeeded with zero width\n" );
1123 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1124 ok( !ret || broken(ret), /* nt4 */ "StretchDIBits succeeded with zero width\n" );
1125 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1126 ok( !ret, "GetDIBits succeeded with zero width\n" );
1127 bi->bmiHeader.biWidth = 0;
1128 bi->bmiHeader.biHeight = 2;
1129 bi->bmiHeader.biBitCount = 32;
1130 bi->bmiHeader.biCompression = BI_RGB;
1131 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1132 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero width\n" );
1134 bi->bmiHeader.biWidth = 2;
1135 bi->bmiHeader.biHeight = 0;
1136 bi->bmiHeader.biBitCount = 32;
1137 bi->bmiHeader.biCompression = BI_RGB;
1138 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1139 ok( hdib == NULL, "CreateDIBSection succeeded with zero height\n" );
1140 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1141 ok( hdib != NULL, "CreateDIBitmap failed with zero height\n" );
1142 DeleteObject( hdib );
1143 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1144 ok( !ret, "SetDIBits succeeded with zero height\n" );
1145 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1146 ok( !ret, "SetDIBitsToDevice succeeded with zero height\n" );
1147 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1148 ok( !ret, "StretchDIBits succeeded with zero height\n" );
1149 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1150 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1151 bi->bmiHeader.biWidth = 2;
1152 bi->bmiHeader.biHeight = 0;
1153 bi->bmiHeader.biBitCount = 32;
1154 bi->bmiHeader.biCompression = BI_RGB;
1155 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1156 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1158 DeleteDC( memdc );
1159 DeleteObject( hbmp );
1160 ReleaseDC( 0, hdc );
1161 HeapFree( GetProcessHeap(), 0, bi );
1164 static void test_mono_dibsection(void)
1166 HDC hdc, memdc;
1167 HBITMAP old_bm, mono_ds;
1168 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
1169 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
1170 RGBQUAD *colors = pbmi->bmiColors;
1171 BYTE bits[10 * 4];
1172 BYTE *ds_bits;
1173 int num;
1175 hdc = GetDC(0);
1177 memdc = CreateCompatibleDC(hdc);
1179 memset(pbmi, 0, sizeof(bmibuf));
1180 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
1181 pbmi->bmiHeader.biHeight = 10;
1182 pbmi->bmiHeader.biWidth = 10;
1183 pbmi->bmiHeader.biBitCount = 1;
1184 pbmi->bmiHeader.biPlanes = 1;
1185 pbmi->bmiHeader.biCompression = BI_RGB;
1186 colors[0].rgbRed = 0xff;
1187 colors[0].rgbGreen = 0xff;
1188 colors[0].rgbBlue = 0xff;
1189 colors[1].rgbRed = 0x0;
1190 colors[1].rgbGreen = 0x0;
1191 colors[1].rgbBlue = 0x0;
1194 * First dib section is 'inverted' ie color[0] is white, color[1] is black
1197 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1198 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1199 old_bm = SelectObject(memdc, mono_ds);
1201 /* black border, white interior */
1202 Rectangle(memdc, 0, 0, 10, 10);
1203 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1204 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1206 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1208 memset(bits, 0, sizeof(bits));
1209 bits[0] = 0xaa;
1211 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1212 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1214 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1216 colors[0].rgbRed = 0x0;
1217 colors[0].rgbGreen = 0x0;
1218 colors[0].rgbBlue = 0x0;
1219 colors[1].rgbRed = 0xff;
1220 colors[1].rgbGreen = 0xff;
1221 colors[1].rgbBlue = 0xff;
1223 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1224 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1226 SelectObject(memdc, old_bm);
1227 DeleteObject(mono_ds);
1230 * Next dib section is 'normal' ie color[0] is black, color[1] is white
1233 colors[0].rgbRed = 0x0;
1234 colors[0].rgbGreen = 0x0;
1235 colors[0].rgbBlue = 0x0;
1236 colors[1].rgbRed = 0xff;
1237 colors[1].rgbGreen = 0xff;
1238 colors[1].rgbBlue = 0xff;
1240 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1241 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1242 old_bm = SelectObject(memdc, mono_ds);
1244 /* black border, white interior */
1245 Rectangle(memdc, 0, 0, 10, 10);
1246 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
1247 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
1249 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
1251 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1252 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1254 /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
1256 colors[0].rgbRed = 0xff;
1257 colors[0].rgbGreen = 0xff;
1258 colors[0].rgbBlue = 0xff;
1259 colors[1].rgbRed = 0x0;
1260 colors[1].rgbGreen = 0x0;
1261 colors[1].rgbBlue = 0x0;
1263 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1264 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1267 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
1270 colors[0].rgbRed = 0xff;
1271 colors[0].rgbGreen = 0xff;
1272 colors[0].rgbBlue = 0xff;
1273 colors[1].rgbRed = 0x0;
1274 colors[1].rgbGreen = 0x0;
1275 colors[1].rgbBlue = 0x0;
1276 num = SetDIBColorTable(memdc, 0, 2, colors);
1277 ok(num == 2, "num = %d\n", num);
1279 /* black border, white interior */
1280 Rectangle(memdc, 0, 0, 10, 10);
1281 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1282 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1284 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1286 memset(bits, 0, sizeof(bits));
1287 bits[0] = 0xaa;
1289 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1290 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1292 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1294 colors[0].rgbRed = 0x0;
1295 colors[0].rgbGreen = 0x0;
1296 colors[0].rgbBlue = 0x0;
1297 colors[1].rgbRed = 0xff;
1298 colors[1].rgbGreen = 0xff;
1299 colors[1].rgbBlue = 0xff;
1301 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1302 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1304 SelectObject(memdc, old_bm);
1305 DeleteObject(mono_ds);
1308 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
1311 colors[0].rgbRed = 0xff;
1312 colors[0].rgbGreen = 0x0;
1313 colors[0].rgbBlue = 0x0;
1314 colors[1].rgbRed = 0xfe;
1315 colors[1].rgbGreen = 0x0;
1316 colors[1].rgbBlue = 0x0;
1318 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1319 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1320 old_bm = SelectObject(memdc, mono_ds);
1322 /* black border, white interior */
1323 Rectangle(memdc, 0, 0, 10, 10);
1324 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1325 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1327 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1329 colors[0].rgbRed = 0x0;
1330 colors[0].rgbGreen = 0x0;
1331 colors[0].rgbBlue = 0x0;
1332 colors[1].rgbRed = 0xff;
1333 colors[1].rgbGreen = 0xff;
1334 colors[1].rgbBlue = 0xff;
1336 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1337 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1339 /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
1341 colors[0].rgbRed = 0xff;
1342 colors[0].rgbGreen = 0xff;
1343 colors[0].rgbBlue = 0xff;
1344 colors[1].rgbRed = 0x0;
1345 colors[1].rgbGreen = 0x0;
1346 colors[1].rgbBlue = 0x0;
1348 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1349 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1351 SelectObject(memdc, old_bm);
1352 DeleteObject(mono_ds);
1354 DeleteDC(memdc);
1355 ReleaseDC(0, hdc);
1358 static void test_bitmap(void)
1360 char buf[256], buf_cmp[256];
1361 HBITMAP hbmp, hbmp_old;
1362 HDC hdc;
1363 BITMAP bm;
1364 BITMAP bma[2];
1365 INT ret;
1367 hdc = CreateCompatibleDC(0);
1368 assert(hdc != 0);
1370 SetLastError(0xdeadbeef);
1371 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1372 if (!hbmp)
1374 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1375 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1376 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1378 else
1379 DeleteObject(hbmp);
1381 SetLastError(0xdeadbeef);
1382 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1383 if (!hbmp)
1385 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1386 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1387 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1389 else
1390 DeleteObject(hbmp);
1392 SetLastError(0xdeadbeef);
1393 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1394 ok(!hbmp, "CreateBitmap should fail\n");
1395 if (!hbmp)
1396 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1397 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1398 else
1399 DeleteObject(hbmp);
1401 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1402 assert(hbmp != NULL);
1404 ret = GetObject(hbmp, sizeof(bm), &bm);
1405 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1407 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1408 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1409 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1410 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1411 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1412 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1413 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1415 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1416 assert(sizeof(buf) == sizeof(buf_cmp));
1418 ret = GetBitmapBits(hbmp, 0, NULL);
1419 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1421 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1422 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1424 memset(buf, 0xAA, sizeof(buf));
1425 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1426 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1427 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1429 hbmp_old = SelectObject(hdc, hbmp);
1431 ret = GetObject(hbmp, sizeof(bm), &bm);
1432 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1434 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1435 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1436 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1437 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1438 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1439 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1440 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1442 memset(buf, 0xAA, sizeof(buf));
1443 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1444 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1445 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1447 hbmp_old = SelectObject(hdc, hbmp_old);
1448 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1450 /* test various buffer sizes for GetObject */
1451 ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
1452 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1454 ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1455 ok(ret == 0, "%d != 0\n", ret);
1457 ret = GetObject(hbmp, 0, &bm);
1458 ok(ret == 0, "%d != 0\n", ret);
1460 ret = GetObject(hbmp, 1, &bm);
1461 ok(ret == 0, "%d != 0\n", ret);
1463 DeleteObject(hbmp);
1464 DeleteDC(hdc);
1467 static void test_bmBits(void)
1469 BYTE bits[4];
1470 HBITMAP hbmp;
1471 BITMAP bmp;
1473 memset(bits, 0, sizeof(bits));
1474 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1475 ok(hbmp != NULL, "CreateBitmap failed\n");
1477 memset(&bmp, 0xFF, sizeof(bmp));
1478 ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1479 "GetObject failed or returned a wrong structure size\n");
1480 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1482 DeleteObject(hbmp);
1485 static void test_GetDIBits_selected_DIB(UINT bpp)
1487 HBITMAP dib;
1488 BITMAPINFO *info;
1489 BITMAPINFO *info2;
1490 void * bits;
1491 void * bits2;
1492 UINT dib_size, dib32_size;
1493 DWORD pixel;
1494 HDC dib_dc, dc;
1495 HBITMAP old_bmp;
1496 UINT i;
1497 int res;
1499 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1500 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1502 /* Create a DIB section with a color table */
1504 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1505 info->bmiHeader.biWidth = 32;
1506 info->bmiHeader.biHeight = 32;
1507 info->bmiHeader.biPlanes = 1;
1508 info->bmiHeader.biBitCount = bpp;
1509 info->bmiHeader.biCompression = BI_RGB;
1510 info->bmiHeader.biXPelsPerMeter = 0;
1511 info->bmiHeader.biYPelsPerMeter = 0;
1512 info->bmiHeader.biClrUsed = 0;
1513 info->bmiHeader.biClrImportant = 0;
1515 for (i=0; i < (1u << bpp); i++)
1517 BYTE c = i * (1 << (8 - bpp));
1518 info->bmiColors[i].rgbRed = c;
1519 info->bmiColors[i].rgbGreen = c;
1520 info->bmiColors[i].rgbBlue = c;
1521 info->bmiColors[i].rgbReserved = 0;
1524 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1525 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1526 dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1528 /* Set the bits of the DIB section */
1529 for (i=0; i < dib_size; i++)
1531 ((BYTE *)bits)[i] = i % 256;
1534 /* Select the DIB into a DC */
1535 dib_dc = CreateCompatibleDC(NULL);
1536 old_bmp = SelectObject(dib_dc, dib);
1537 dc = CreateCompatibleDC(NULL);
1538 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
1540 /* Copy the DIB attributes but not the color table */
1541 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1543 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1544 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1546 /* Compare the color table and the bits */
1547 for (i=0; i < (1u << bpp); i++)
1548 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1549 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1550 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1551 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1552 "color table entry %d differs (bpp %d)\n", i, bpp );
1554 ok( !memcmp( bits, bits2, dib_size ), "bit mismatch (bpp %d)\n", bpp );
1556 /* Test various combinations of lines = 0 and bits2 = NULL */
1557 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1558 res = GetDIBits( dc, dib, 0, 0, bits2, info2, DIB_RGB_COLORS );
1559 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1560 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1561 "color table mismatch (bpp %d)\n", bpp );
1563 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1564 res = GetDIBits( dc, dib, 0, 0, NULL, info2, DIB_RGB_COLORS );
1565 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1566 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1567 "color table mismatch (bpp %d)\n", bpp );
1569 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1570 res = GetDIBits( dc, dib, 0, info->bmiHeader.biHeight, NULL, info2, DIB_RGB_COLORS );
1571 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1572 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1573 "color table mismatch (bpp %d)\n", bpp );
1575 /* Map into a 32bit-DIB */
1576 info2->bmiHeader.biBitCount = 32;
1577 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1578 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1580 /* Check if last pixel was set */
1581 pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
1582 ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
1584 HeapFree(GetProcessHeap(), 0, bits2);
1585 DeleteDC(dc);
1587 SelectObject(dib_dc, old_bmp);
1588 DeleteDC(dib_dc);
1589 DeleteObject(dib);
1590 HeapFree(GetProcessHeap(), 0, info2);
1591 HeapFree(GetProcessHeap(), 0, info);
1594 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1596 HBITMAP ddb;
1597 BITMAPINFO *info;
1598 BITMAPINFO *info2;
1599 void * bits;
1600 void * bits2;
1601 HDC ddb_dc, dc;
1602 HBITMAP old_bmp;
1603 UINT width, height;
1604 UINT bpp;
1605 UINT i, j;
1606 int res;
1608 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1609 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1611 width = height = 16;
1613 /* Create a DDB (device-dependent bitmap) */
1614 if (monochrome)
1616 bpp = 1;
1617 ddb = CreateBitmap(width, height, 1, 1, NULL);
1619 else
1621 HDC screen_dc = GetDC(NULL);
1622 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1623 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1624 ReleaseDC(NULL, screen_dc);
1627 /* Set the pixels */
1628 ddb_dc = CreateCompatibleDC(NULL);
1629 old_bmp = SelectObject(ddb_dc, ddb);
1630 for (i = 0; i < width; i++)
1632 for (j=0; j < height; j++)
1634 BYTE c = (i * width + j) % 256;
1635 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1638 SelectObject(ddb_dc, old_bmp);
1640 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1641 info->bmiHeader.biWidth = width;
1642 info->bmiHeader.biHeight = height;
1643 info->bmiHeader.biPlanes = 1;
1644 info->bmiHeader.biBitCount = bpp;
1645 info->bmiHeader.biCompression = BI_RGB;
1647 dc = CreateCompatibleDC(NULL);
1649 /* Fill in biSizeImage */
1650 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1651 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1653 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1654 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1656 /* Get the bits */
1657 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1658 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1660 /* Copy the DIB attributes but not the color table */
1661 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1663 /* Select the DDB into another DC */
1664 old_bmp = SelectObject(ddb_dc, ddb);
1666 /* Get the bits */
1667 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1668 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1670 /* Compare the color table and the bits */
1671 if (bpp <= 8)
1673 for (i=0; i < (1u << bpp); i++)
1674 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1675 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1676 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1677 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1678 "color table entry %d differs (bpp %d)\n", i, bpp );
1681 ok( !memcmp( bits, bits2, info->bmiHeader.biSizeImage ), "bit mismatch (bpp %d)\n", bpp );
1683 /* Test the palette */
1684 if (info2->bmiHeader.biBitCount <= 8)
1686 WORD *colors = (WORD*)info2->bmiColors;
1688 /* Get the palette indices */
1689 res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1690 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1692 for (i = 0; i < (1 << info->bmiHeader.biBitCount); i++)
1693 ok( colors[i] == i, "%d: got %d (bpp %d)\n", i, colors[i], bpp );
1696 HeapFree(GetProcessHeap(), 0, bits2);
1697 HeapFree(GetProcessHeap(), 0, bits);
1698 DeleteDC(dc);
1700 SelectObject(ddb_dc, old_bmp);
1701 DeleteDC(ddb_dc);
1702 DeleteObject(ddb);
1703 HeapFree(GetProcessHeap(), 0, info2);
1704 HeapFree(GetProcessHeap(), 0, info);
1707 static void test_GetDIBits(void)
1709 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1710 static const BYTE bmp_bits_1[16 * 2] =
1712 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1713 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1714 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1715 0xff,0xff, 0,0, 0xff,0xff, 0,0
1717 /* 4-bytes aligned 1-bit DIB data: 16x16 */
1718 static const BYTE dib_bits_1[16 * 4] =
1720 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1721 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1722 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1723 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1725 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1726 static const BYTE bmp_bits_24[16 * 16*3] =
1728 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1729 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1730 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1731 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1732 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1733 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1734 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1735 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1736 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1737 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1738 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1739 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1740 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1741 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1742 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1743 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1744 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1745 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1746 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1747 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1748 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1749 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1750 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1751 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1752 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1753 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1754 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1755 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1756 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1757 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1758 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1759 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1761 /* 4-bytes aligned 24-bit DIB data: 16x16 */
1762 static const BYTE dib_bits_24[16 * 16*3] =
1764 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1765 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1766 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1767 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1768 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1769 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1770 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1771 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1772 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1773 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1774 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1775 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1776 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1777 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1778 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1779 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1780 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1781 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1782 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1783 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1784 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1785 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1786 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1787 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1788 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1789 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1790 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1791 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1792 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1793 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1794 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1795 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1797 HBITMAP hbmp;
1798 BITMAP bm;
1799 HDC hdc;
1800 int i, bytes, lines;
1801 BYTE buf[1024];
1802 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1803 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1804 RGBQUAD *colors = bi->bmiColors;
1805 PALETTEENTRY pal_ents[20];
1807 hdc = GetDC(0);
1809 /* 1-bit source bitmap data */
1810 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1811 ok(hbmp != 0, "CreateBitmap failed\n");
1813 memset(&bm, 0xAA, sizeof(bm));
1814 bytes = GetObject(hbmp, sizeof(bm), &bm);
1815 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1816 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1817 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1818 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1819 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1820 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1821 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1822 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1824 bytes = GetBitmapBits(hbmp, 0, NULL);
1825 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1826 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1827 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1828 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1830 /* retrieve 1-bit DIB data */
1831 memset(bi, 0, sizeof(*bi));
1832 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1833 bi->bmiHeader.biWidth = bm.bmWidth;
1834 bi->bmiHeader.biHeight = bm.bmHeight;
1835 bi->bmiHeader.biPlanes = 1;
1836 bi->bmiHeader.biBitCount = 1;
1837 bi->bmiHeader.biCompression = BI_RGB;
1838 bi->bmiHeader.biClrUsed = 37;
1839 bi->bmiHeader.biSizeImage = 0;
1840 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1841 SetLastError(0xdeadbeef);
1842 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1843 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1844 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1845 broken(GetLastError() == 0xdeadbeef), /* winnt */
1846 "wrong error %u\n", GetLastError());
1847 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1848 ok(bi->bmiHeader.biClrUsed == 37 || broken(bi->bmiHeader.biClrUsed == 0),
1849 "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
1851 memset(buf, 0xAA, sizeof(buf));
1852 SetLastError(0xdeadbeef);
1853 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1854 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1855 lines, bm.bmHeight, GetLastError());
1856 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1857 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
1859 /* the color table consists of black and white */
1860 ok(colors[0].rgbRed == 0 && colors[0].rgbGreen == 0 &&
1861 colors[0].rgbBlue == 0 && colors[0].rgbReserved == 0,
1862 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1863 colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue, colors[0].rgbReserved);
1864 ok(colors[1].rgbRed == 0xff && colors[1].rgbGreen == 0xff &&
1865 colors[1].rgbBlue == 0xff && colors[1].rgbReserved == 0,
1866 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1867 colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue, colors[1].rgbReserved);
1868 for (i = 2; i < 256; i++)
1870 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
1871 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
1872 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1873 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
1876 /* returned bits are DWORD aligned and upside down */
1877 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1879 /* Test the palette indices */
1880 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1881 SetLastError(0xdeadbeef);
1882 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1883 ok(((WORD*)colors)[0] == 0, "Color 0 is %d\n", ((WORD*)colors)[0]);
1884 ok(((WORD*)colors)[1] == 1, "Color 1 is %d\n", ((WORD*)colors)[1]);
1885 for (i = 2; i < 256; i++)
1886 ok(((WORD*)colors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)colors)[1]);
1888 /* retrieve 24-bit DIB data */
1889 memset(bi, 0, sizeof(*bi));
1890 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1891 bi->bmiHeader.biWidth = bm.bmWidth;
1892 bi->bmiHeader.biHeight = bm.bmHeight;
1893 bi->bmiHeader.biPlanes = 1;
1894 bi->bmiHeader.biBitCount = 24;
1895 bi->bmiHeader.biCompression = BI_RGB;
1896 bi->bmiHeader.biClrUsed = 37;
1897 bi->bmiHeader.biSizeImage = 0;
1898 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1899 memset(buf, 0xAA, sizeof(buf));
1900 SetLastError(0xdeadbeef);
1901 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1902 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1903 lines, bm.bmHeight, GetLastError());
1904 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1905 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
1907 /* the color table doesn't exist for 24-bit images */
1908 for (i = 0; i < 256; i++)
1910 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
1911 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
1912 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1913 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
1916 /* returned bits are DWORD aligned and upside down */
1917 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1918 DeleteObject(hbmp);
1920 /* 24-bit source bitmap data */
1921 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1922 ok(hbmp != 0, "CreateBitmap failed\n");
1923 SetLastError(0xdeadbeef);
1924 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1925 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1926 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1927 lines, bm.bmHeight, GetLastError());
1929 memset(&bm, 0xAA, sizeof(bm));
1930 bytes = GetObject(hbmp, sizeof(bm), &bm);
1931 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1932 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1933 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1934 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1935 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1936 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1937 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1938 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1940 bytes = GetBitmapBits(hbmp, 0, NULL);
1941 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
1942 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1943 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1944 bm.bmWidthBytes * bm.bmHeight, bytes);
1946 /* retrieve 1-bit DIB data */
1947 memset(bi, 0, sizeof(*bi));
1948 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1949 bi->bmiHeader.biWidth = bm.bmWidth;
1950 bi->bmiHeader.biHeight = bm.bmHeight;
1951 bi->bmiHeader.biPlanes = 1;
1952 bi->bmiHeader.biBitCount = 1;
1953 bi->bmiHeader.biCompression = BI_RGB;
1954 bi->bmiHeader.biClrUsed = 37;
1955 bi->bmiHeader.biSizeImage = 0;
1956 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1957 memset(buf, 0xAA, sizeof(buf));
1958 SetLastError(0xdeadbeef);
1959 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1960 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1961 lines, bm.bmHeight, GetLastError());
1962 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1963 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
1965 /* the color table consists of black and white */
1966 ok(colors[0].rgbRed == 0 && colors[0].rgbGreen == 0 &&
1967 colors[0].rgbBlue == 0 && colors[0].rgbReserved == 0,
1968 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1969 colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue, colors[0].rgbReserved);
1970 ok(colors[1].rgbRed == 0xff && colors[1].rgbGreen == 0xff &&
1971 colors[1].rgbBlue == 0xff && colors[1].rgbReserved == 0,
1972 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1973 colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue, colors[1].rgbReserved);
1974 for (i = 2; i < 256; i++)
1976 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
1977 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
1978 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1979 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
1982 /* returned bits are DWORD aligned and upside down */
1983 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1985 /* Test the palette indices */
1986 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1987 SetLastError(0xdeadbeef);
1988 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1989 ok(((WORD*)colors)[0] == 0, "Color 0 is %d\n", ((WORD*)colors)[0]);
1990 ok(((WORD*)colors)[1] == 1, "Color 1 is %d\n", ((WORD*)colors)[1]);
1991 for (i = 2; i < 256; i++)
1992 ok(((WORD*)colors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)colors)[i]);
1994 /* retrieve 4-bit DIB data */
1995 memset(bi, 0, sizeof(*bi));
1996 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1997 bi->bmiHeader.biWidth = bm.bmWidth;
1998 bi->bmiHeader.biHeight = bm.bmHeight;
1999 bi->bmiHeader.biPlanes = 1;
2000 bi->bmiHeader.biBitCount = 4;
2001 bi->bmiHeader.biCompression = BI_RGB;
2002 bi->bmiHeader.biClrUsed = 37;
2003 bi->bmiHeader.biSizeImage = 0;
2004 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2005 memset(buf, 0xAA, sizeof(buf));
2006 SetLastError(0xdeadbeef);
2007 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2008 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2009 lines, bm.bmHeight, GetLastError());
2010 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2012 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2014 for (i = 0; i < 16; i++)
2016 RGBQUAD expect;
2017 int entry = i < 8 ? i : i + 4;
2019 if(entry == 7) entry = 12;
2020 else if(entry == 12) entry = 7;
2022 expect.rgbRed = pal_ents[entry].peRed;
2023 expect.rgbGreen = pal_ents[entry].peGreen;
2024 expect.rgbBlue = pal_ents[entry].peBlue;
2025 expect.rgbReserved = 0;
2027 ok(!memcmp(colors + i, &expect, sizeof(expect)),
2028 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2029 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2030 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2033 /* retrieve 8-bit DIB data */
2034 memset(bi, 0, sizeof(*bi));
2035 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2036 bi->bmiHeader.biWidth = bm.bmWidth;
2037 bi->bmiHeader.biHeight = bm.bmHeight;
2038 bi->bmiHeader.biPlanes = 1;
2039 bi->bmiHeader.biBitCount = 8;
2040 bi->bmiHeader.biCompression = BI_RGB;
2041 bi->bmiHeader.biClrUsed = 37;
2042 bi->bmiHeader.biSizeImage = 0;
2043 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2044 memset(buf, 0xAA, sizeof(buf));
2045 SetLastError(0xdeadbeef);
2046 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2047 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2048 lines, bm.bmHeight, GetLastError());
2049 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2051 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2053 for (i = 0; i < 256; i++)
2055 RGBQUAD expect;
2057 if (i < 10 || i >= 246)
2059 int entry = i < 10 ? i : i - 236;
2060 expect.rgbRed = pal_ents[entry].peRed;
2061 expect.rgbGreen = pal_ents[entry].peGreen;
2062 expect.rgbBlue = pal_ents[entry].peBlue;
2064 else
2066 expect.rgbRed = (i & 0x07) << 5;
2067 expect.rgbGreen = (i & 0x38) << 2;
2068 expect.rgbBlue = i & 0xc0;
2070 expect.rgbReserved = 0;
2072 ok(!memcmp(colors + i, &expect, sizeof(expect)),
2073 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2074 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2075 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2078 /* retrieve 24-bit DIB data */
2079 memset(bi, 0, sizeof(*bi));
2080 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2081 bi->bmiHeader.biWidth = bm.bmWidth;
2082 bi->bmiHeader.biHeight = bm.bmHeight;
2083 bi->bmiHeader.biPlanes = 1;
2084 bi->bmiHeader.biBitCount = 24;
2085 bi->bmiHeader.biCompression = BI_RGB;
2086 bi->bmiHeader.biClrUsed = 37;
2087 bi->bmiHeader.biSizeImage = 0;
2088 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2089 memset(buf, 0xAA, sizeof(buf));
2090 SetLastError(0xdeadbeef);
2091 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2092 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2093 lines, bm.bmHeight, GetLastError());
2094 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2095 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2097 /* the color table doesn't exist for 24-bit images */
2098 for (i = 0; i < 256; i++)
2100 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2101 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2102 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2103 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2106 /* returned bits are DWORD aligned and upside down */
2107 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2108 DeleteObject(hbmp);
2110 ReleaseDC(0, hdc);
2113 static void test_GetDIBits_BI_BITFIELDS(void)
2115 /* Try a screen resolution detection technique
2116 * from the September 1999 issue of Windows Developer's Journal
2117 * which seems to be in widespread use.
2118 * http://www.lesher.ws/highcolor.html
2119 * http://www.lesher.ws/vidfmt.c
2120 * It hinges on being able to retrieve the bitmaps
2121 * for the three primary colors in non-paletted 16 bit mode.
2123 char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
2124 DWORD bits[32];
2125 LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
2126 DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
2127 HDC hdc;
2128 HBITMAP hbm;
2129 int ret;
2130 void *ptr;
2132 memset(dibinfo, 0, sizeof(dibinfo_buf));
2133 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2135 hdc = GetDC(NULL);
2136 ok(hdc != NULL, "GetDC failed?\n");
2137 hbm = CreateCompatibleBitmap(hdc, 1, 1);
2138 ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
2140 /* Call GetDIBits to fill in bmiHeader. */
2141 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2142 ok(ret == 1, "GetDIBits failed\n");
2143 if (dibinfo->bmiHeader.biBitCount > 8)
2145 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2146 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2147 "compression is %u (%d bpp)\n", dibinfo->bmiHeader.biCompression, dibinfo->bmiHeader.biBitCount );
2149 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2151 ok( !bitmasks[0], "red mask is set\n" );
2152 ok( !bitmasks[1], "green mask is set\n" );
2153 ok( !bitmasks[2], "blue mask is set\n" );
2155 /* test with NULL bits pointer and correct bpp */
2156 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2157 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2158 ok(ret == 1, "GetDIBits failed\n");
2160 ok( bitmasks[0] != 0, "red mask is not set\n" );
2161 ok( bitmasks[1] != 0, "green mask is not set\n" );
2162 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2163 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2165 /* test with valid bits pointer */
2166 memset(dibinfo, 0, sizeof(dibinfo_buf));
2167 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2168 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2169 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2170 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2171 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2172 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2174 ok( bitmasks[0] != 0, "red mask is not set\n" );
2175 ok( bitmasks[1] != 0, "green mask is not set\n" );
2176 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2177 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2179 /* now with bits and 0 lines */
2180 memset(dibinfo, 0, sizeof(dibinfo_buf));
2181 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2182 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2183 SetLastError(0xdeadbeef);
2184 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2185 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2187 ok( !bitmasks[0], "red mask is set\n" );
2188 ok( !bitmasks[1], "green mask is set\n" );
2189 ok( !bitmasks[2], "blue mask is set\n" );
2190 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2192 memset(bitmasks, 0, 3*sizeof(DWORD));
2193 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2194 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2195 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2197 ok( bitmasks[0] != 0, "red mask is not set\n" );
2198 ok( bitmasks[1] != 0, "green mask is not set\n" );
2199 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2200 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2203 else skip("bitmap in colortable mode, skipping BI_BITFIELDS tests\n");
2205 DeleteObject(hbm);
2207 /* same thing now with a 32-bpp DIB section */
2209 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2210 dibinfo->bmiHeader.biWidth = 1;
2211 dibinfo->bmiHeader.biHeight = 1;
2212 dibinfo->bmiHeader.biPlanes = 1;
2213 dibinfo->bmiHeader.biBitCount = 32;
2214 dibinfo->bmiHeader.biCompression = BI_RGB;
2215 dibinfo->bmiHeader.biSizeImage = 0;
2216 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2217 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2218 dibinfo->bmiHeader.biClrUsed = 0;
2219 dibinfo->bmiHeader.biClrImportant = 0;
2220 bitmasks[0] = 0x0000ff;
2221 bitmasks[1] = 0x00ff00;
2222 bitmasks[2] = 0xff0000;
2223 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2224 ok( hbm != 0, "failed to create bitmap\n" );
2226 memset(dibinfo, 0, sizeof(dibinfo_buf));
2227 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2228 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2229 ok(ret == 1, "GetDIBits failed\n");
2230 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2232 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2233 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2234 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2235 ok( !bitmasks[0], "red mask is set\n" );
2236 ok( !bitmasks[1], "green mask is set\n" );
2237 ok( !bitmasks[2], "blue mask is set\n" );
2239 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2240 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2241 ok(ret == 1, "GetDIBits failed\n");
2242 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2243 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2244 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2245 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2246 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2248 ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
2249 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2250 ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
2252 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2254 DeleteObject(hbm);
2256 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2257 dibinfo->bmiHeader.biWidth = 1;
2258 dibinfo->bmiHeader.biHeight = 1;
2259 dibinfo->bmiHeader.biPlanes = 1;
2260 dibinfo->bmiHeader.biBitCount = 32;
2261 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2262 dibinfo->bmiHeader.biSizeImage = 0;
2263 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2264 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2265 dibinfo->bmiHeader.biClrUsed = 0;
2266 dibinfo->bmiHeader.biClrImportant = 0;
2267 bitmasks[0] = 0x0000ff;
2268 bitmasks[1] = 0x00ff00;
2269 bitmasks[2] = 0xff0000;
2270 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2271 ok( hbm != 0, "failed to create bitmap\n" );
2273 if (hbm)
2275 memset(dibinfo, 0, sizeof(dibinfo_buf));
2276 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2277 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2278 ok(ret == 1, "GetDIBits failed\n");
2280 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
2281 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2282 ok( !bitmasks[0], "red mask is set\n" );
2283 ok( !bitmasks[1], "green mask is set\n" );
2284 ok( !bitmasks[2], "blue mask is set\n" );
2286 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2287 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2288 ok(ret == 1, "GetDIBits failed\n");
2289 ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
2290 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2291 ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
2292 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2294 DeleteObject(hbm);
2297 /* 24-bpp DIB sections don't have bitfields */
2299 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2300 dibinfo->bmiHeader.biWidth = 1;
2301 dibinfo->bmiHeader.biHeight = 1;
2302 dibinfo->bmiHeader.biPlanes = 1;
2303 dibinfo->bmiHeader.biBitCount = 24;
2304 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2305 dibinfo->bmiHeader.biSizeImage = 0;
2306 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2307 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2308 dibinfo->bmiHeader.biClrUsed = 0;
2309 dibinfo->bmiHeader.biClrImportant = 0;
2310 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2311 ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
2312 dibinfo->bmiHeader.biCompression = BI_RGB;
2313 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2314 ok( hbm != 0, "failed to create bitmap\n" );
2316 memset(dibinfo, 0, sizeof(dibinfo_buf));
2317 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2318 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2319 ok(ret == 1, "GetDIBits failed\n");
2320 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2322 ok( dibinfo->bmiHeader.biCompression == BI_RGB,
2323 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2324 ok( !bitmasks[0], "red mask is set\n" );
2325 ok( !bitmasks[1], "green mask is set\n" );
2326 ok( !bitmasks[2], "blue mask is set\n" );
2328 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2329 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2330 ok(ret == 1, "GetDIBits failed\n");
2331 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2332 ok( !bitmasks[0], "red mask is set\n" );
2333 ok( !bitmasks[1], "green mask is set\n" );
2334 ok( !bitmasks[2], "blue mask is set\n" );
2335 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2337 DeleteObject(hbm);
2338 ReleaseDC(NULL, hdc);
2341 static void test_select_object(void)
2343 HDC hdc;
2344 HBITMAP hbm, hbm_old;
2345 INT planes, bpp, i;
2346 DWORD depths[] = {8, 15, 16, 24, 32};
2347 BITMAP bm;
2348 DWORD bytes;
2350 hdc = GetDC(0);
2351 ok(hdc != 0, "GetDC(0) failed\n");
2352 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2353 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2355 hbm_old = SelectObject(hdc, hbm);
2356 ok(hbm_old == 0, "SelectObject should fail\n");
2358 DeleteObject(hbm);
2359 ReleaseDC(0, hdc);
2361 hdc = CreateCompatibleDC(0);
2362 ok(hdc != 0, "GetDC(0) failed\n");
2363 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2364 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2366 hbm_old = SelectObject(hdc, hbm);
2367 ok(hbm_old != 0, "SelectObject failed\n");
2368 hbm_old = SelectObject(hdc, hbm_old);
2369 ok(hbm_old == hbm, "SelectObject failed\n");
2371 DeleteObject(hbm);
2373 /* test an 1-bpp bitmap */
2374 planes = GetDeviceCaps(hdc, PLANES);
2375 bpp = 1;
2377 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
2378 ok(hbm != 0, "CreateBitmap failed\n");
2380 hbm_old = SelectObject(hdc, hbm);
2381 ok(hbm_old != 0, "SelectObject failed\n");
2382 hbm_old = SelectObject(hdc, hbm_old);
2383 ok(hbm_old == hbm, "SelectObject failed\n");
2385 DeleteObject(hbm);
2387 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
2388 /* test a color bitmap to dc bpp matching */
2389 planes = GetDeviceCaps(hdc, PLANES);
2390 bpp = GetDeviceCaps(hdc, BITSPIXEL);
2392 hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
2393 ok(hbm != 0, "CreateBitmap failed\n");
2395 hbm_old = SelectObject(hdc, hbm);
2396 if(depths[i] == bpp ||
2397 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
2399 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
2400 SelectObject(hdc, hbm_old);
2401 } else {
2402 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
2405 memset(&bm, 0xAA, sizeof(bm));
2406 bytes = GetObject(hbm, sizeof(bm), &bm);
2407 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2408 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2409 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
2410 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
2411 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2412 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
2413 if(depths[i] == 15) {
2414 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
2415 } else {
2416 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2418 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2420 DeleteObject(hbm);
2423 DeleteDC(hdc);
2426 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
2428 INT ret;
2429 BITMAP bm;
2431 ret = GetObjectType(hbmp);
2432 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
2434 ret = GetObject(hbmp, 0, 0);
2435 ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
2437 memset(&bm, 0xDA, sizeof(bm));
2438 SetLastError(0xdeadbeef);
2439 ret = GetObject(hbmp, sizeof(bm), &bm);
2440 if (!ret) /* XP, only for curObj2 */ return;
2441 ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
2442 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2443 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2444 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2445 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2446 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2447 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2448 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2451 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2453 static void test_CreateBitmap(void)
2455 BITMAP bmp;
2456 HDC screenDC = GetDC(0);
2457 HDC hdc = CreateCompatibleDC(screenDC);
2458 UINT i, expect = 0;
2460 /* all of these are the stock monochrome bitmap */
2461 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2462 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2463 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2464 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2465 HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2466 HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2468 /* these 2 are not the stock monochrome bitmap */
2469 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2470 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2472 HBITMAP old1 = SelectObject(hdc, bm2);
2473 HBITMAP old2 = SelectObject(screenDC, bm3);
2474 SelectObject(hdc, old1);
2475 SelectObject(screenDC, old2);
2477 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2478 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2479 bm, bm1, bm4, bm5, curObj1, old1);
2480 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2481 todo_wine
2482 ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
2483 ok(old2 == 0, "old2 %p\n", old2);
2485 test_mono_1x1_bmp(bm);
2486 test_mono_1x1_bmp(bm1);
2487 test_mono_1x1_bmp(bm2);
2488 test_mono_1x1_bmp(bm3);
2489 test_mono_1x1_bmp(bm4);
2490 test_mono_1x1_bmp(bm5);
2491 test_mono_1x1_bmp(old1);
2492 test_mono_1x1_bmp(curObj1);
2494 DeleteObject(bm);
2495 DeleteObject(bm1);
2496 DeleteObject(bm2);
2497 DeleteObject(bm3);
2498 DeleteObject(bm4);
2499 DeleteObject(bm5);
2501 DeleteDC(hdc);
2502 ReleaseDC(0, screenDC);
2504 /* show that Windows ignores the provided bm.bmWidthBytes */
2505 bmp.bmType = 0;
2506 bmp.bmWidth = 1;
2507 bmp.bmHeight = 1;
2508 bmp.bmWidthBytes = 28;
2509 bmp.bmPlanes = 1;
2510 bmp.bmBitsPixel = 1;
2511 bmp.bmBits = NULL;
2512 bm = CreateBitmapIndirect(&bmp);
2513 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2514 test_mono_1x1_bmp(bm);
2515 DeleteObject(bm);
2517 /* Test how the bmBitsPixel field is treated */
2518 for(i = 1; i <= 33; i++) {
2519 bmp.bmType = 0;
2520 bmp.bmWidth = 1;
2521 bmp.bmHeight = 1;
2522 bmp.bmWidthBytes = 28;
2523 bmp.bmPlanes = 1;
2524 bmp.bmBitsPixel = i;
2525 bmp.bmBits = NULL;
2526 SetLastError(0xdeadbeef);
2527 bm = CreateBitmapIndirect(&bmp);
2528 if(i > 32) {
2529 DWORD error = GetLastError();
2530 ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
2531 ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2532 DeleteObject(bm);
2533 continue;
2535 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2536 GetObject(bm, sizeof(bmp), &bmp);
2537 if(i == 1) {
2538 expect = 1;
2539 } else if(i <= 4) {
2540 expect = 4;
2541 } else if(i <= 8) {
2542 expect = 8;
2543 } else if(i <= 16) {
2544 expect = 16;
2545 } else if(i <= 24) {
2546 expect = 24;
2547 } else if(i <= 32) {
2548 expect = 32;
2550 ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2551 i, bmp.bmBitsPixel, expect);
2552 DeleteObject(bm);
2556 static void test_bitmapinfoheadersize(void)
2558 HBITMAP hdib;
2559 BITMAPINFO bmi;
2560 BITMAPCOREINFO bci;
2561 HDC hdc = GetDC(0);
2563 memset(&bmi, 0, sizeof(BITMAPINFO));
2564 bmi.bmiHeader.biHeight = 100;
2565 bmi.bmiHeader.biWidth = 512;
2566 bmi.bmiHeader.biBitCount = 24;
2567 bmi.bmiHeader.biPlanes = 1;
2569 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2571 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2572 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2574 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2576 SetLastError(0xdeadbeef);
2577 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2578 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2579 DeleteObject(hdib);
2581 bmi.bmiHeader.biSize++;
2583 SetLastError(0xdeadbeef);
2584 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2585 ok(hdib != NULL ||
2586 broken(!hdib), /* Win98, WinMe */
2587 "CreateDIBSection error %d\n", GetLastError());
2588 DeleteObject(hdib);
2590 bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2592 SetLastError(0xdeadbeef);
2593 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2594 ok(hdib != NULL ||
2595 broken(!hdib), /* Win98, WinMe */
2596 "CreateDIBSection error %d\n", GetLastError());
2597 DeleteObject(hdib);
2599 bmi.bmiHeader.biSize++;
2601 SetLastError(0xdeadbeef);
2602 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2603 ok(hdib != NULL ||
2604 broken(!hdib), /* Win98, WinMe */
2605 "CreateDIBSection error %d\n", GetLastError());
2606 DeleteObject(hdib);
2608 bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2610 SetLastError(0xdeadbeef);
2611 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2612 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2613 DeleteObject(hdib);
2615 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2617 SetLastError(0xdeadbeef);
2618 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2619 ok(hdib != NULL ||
2620 broken(!hdib), /* Win95 */
2621 "CreateDIBSection error %d\n", GetLastError());
2622 DeleteObject(hdib);
2624 memset(&bci, 0, sizeof(BITMAPCOREINFO));
2625 bci.bmciHeader.bcHeight = 100;
2626 bci.bmciHeader.bcWidth = 512;
2627 bci.bmciHeader.bcBitCount = 24;
2628 bci.bmciHeader.bcPlanes = 1;
2630 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2632 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2633 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2635 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2637 SetLastError(0xdeadbeef);
2638 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2639 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2640 DeleteObject(hdib);
2642 bci.bmciHeader.bcSize++;
2644 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2645 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2647 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2649 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2650 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2652 ReleaseDC(0, hdc);
2655 static void test_get16dibits(void)
2657 BYTE bits[4 * (16 / sizeof(BYTE))];
2658 HBITMAP hbmp;
2659 HDC screen_dc = GetDC(NULL);
2660 int ret;
2661 BITMAPINFO * info;
2662 int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2663 BYTE *p;
2664 int overwritten_bytes = 0;
2666 memset(bits, 0, sizeof(bits));
2667 hbmp = CreateBitmap(2, 2, 1, 16, bits);
2668 ok(hbmp != NULL, "CreateBitmap failed\n");
2670 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2671 assert(info);
2673 memset(info, '!', info_len);
2674 memset(info, 0, sizeof(info->bmiHeader));
2676 info->bmiHeader.biSize = sizeof(info->bmiHeader);
2677 info->bmiHeader.biWidth = 2;
2678 info->bmiHeader.biHeight = 2;
2679 info->bmiHeader.biPlanes = 1;
2680 info->bmiHeader.biCompression = BI_RGB;
2682 ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2683 ok(ret != 0, "GetDIBits failed got %d\n", ret);
2685 for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2686 if (*p != '!')
2687 overwritten_bytes++;
2688 ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2690 HeapFree(GetProcessHeap(), 0, info);
2691 DeleteObject(hbmp);
2692 ReleaseDC(NULL, screen_dc);
2695 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2696 DWORD dwRop, UINT32 expected, int line)
2698 *srcBuffer = 0xFEDCBA98;
2699 *dstBuffer = 0x89ABCDEF;
2700 Rectangle(hdcSrc, 0, 0, 1, 1); /* A null operation to ensure dibs are coerced to X11 */
2701 BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
2702 ok(expected == *dstBuffer,
2703 "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2704 dwRop, expected, *dstBuffer, line);
2707 static void test_BitBlt(void)
2709 HBITMAP bmpDst, bmpSrc;
2710 HBITMAP oldDst, oldSrc;
2711 HDC hdcScreen, hdcDst, hdcSrc;
2712 UINT32 *dstBuffer, *srcBuffer;
2713 HBRUSH hBrush, hOldBrush;
2714 BITMAPINFO bitmapInfo;
2716 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2717 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2718 bitmapInfo.bmiHeader.biWidth = 1;
2719 bitmapInfo.bmiHeader.biHeight = 1;
2720 bitmapInfo.bmiHeader.biPlanes = 1;
2721 bitmapInfo.bmiHeader.biBitCount = 32;
2722 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2723 bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2725 hdcScreen = CreateCompatibleDC(0);
2726 hdcDst = CreateCompatibleDC(hdcScreen);
2727 hdcSrc = CreateCompatibleDC(hdcDst);
2729 /* Setup the destination dib section */
2730 bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
2731 NULL, 0);
2732 oldDst = SelectObject(hdcDst, bmpDst);
2734 hBrush = CreateSolidBrush(0x012345678);
2735 hOldBrush = SelectObject(hdcDst, hBrush);
2737 /* Setup the source dib section */
2738 bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
2739 NULL, 0);
2740 oldSrc = SelectObject(hdcSrc, bmpSrc);
2742 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2743 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2744 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2745 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2746 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2747 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2748 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2749 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2750 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2751 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2752 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2753 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2754 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2755 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2756 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2758 /* Tidy up */
2759 SelectObject(hdcSrc, oldSrc);
2760 DeleteObject(bmpSrc);
2761 DeleteDC(hdcSrc);
2763 SelectObject(hdcDst, hOldBrush);
2764 DeleteObject(hBrush);
2765 SelectObject(hdcDst, oldDst);
2766 DeleteObject(bmpDst);
2767 DeleteDC(hdcDst);
2770 DeleteDC(hdcScreen);
2773 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2774 DWORD dwRop, UINT32 expected, int line)
2776 *srcBuffer = 0xFEDCBA98;
2777 *dstBuffer = 0x89ABCDEF;
2778 StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
2779 ok(expected == *dstBuffer,
2780 "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2781 dwRop, expected, *dstBuffer, line);
2784 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, BITMAPINFO *dst_info, UINT32 *dstBuffer, UINT32 *srcBuffer,
2785 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2786 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2787 UINT32 *expected, int line)
2789 int dst_size = get_dib_image_size( dst_info );
2791 memset(dstBuffer, 0, dst_size);
2792 StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2793 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
2794 ok(memcmp(dstBuffer, expected, dst_size) == 0,
2795 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2796 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2797 expected[0], expected[1], expected[2], expected[3],
2798 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2799 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2800 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2803 static void test_StretchBlt(void)
2805 HBITMAP bmpDst, bmpSrc;
2806 HBITMAP oldDst, oldSrc;
2807 HDC hdcScreen, hdcDst, hdcSrc;
2808 UINT32 *dstBuffer, *srcBuffer;
2809 HBRUSH hBrush, hOldBrush;
2810 BITMAPINFO biDst, biSrc;
2811 UINT32 expected[256];
2812 RGBQUAD colors[2];
2814 memset(&biDst, 0, sizeof(BITMAPINFO));
2815 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2816 biDst.bmiHeader.biWidth = 16;
2817 biDst.bmiHeader.biHeight = -16;
2818 biDst.bmiHeader.biPlanes = 1;
2819 biDst.bmiHeader.biBitCount = 32;
2820 biDst.bmiHeader.biCompression = BI_RGB;
2821 memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
2823 hdcScreen = CreateCompatibleDC(0);
2824 hdcDst = CreateCompatibleDC(hdcScreen);
2825 hdcSrc = CreateCompatibleDC(hdcDst);
2827 /* Pixel Tests */
2828 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2829 NULL, 0);
2830 oldDst = SelectObject(hdcDst, bmpDst);
2832 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2833 NULL, 0);
2834 oldSrc = SelectObject(hdcSrc, bmpSrc);
2836 hBrush = CreateSolidBrush(0x012345678);
2837 hOldBrush = SelectObject(hdcDst, hBrush);
2839 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2840 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2841 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2842 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2843 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2844 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2845 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2846 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2847 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2848 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2849 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2850 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2851 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2852 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2853 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2855 SelectObject(hdcDst, hOldBrush);
2856 DeleteObject(hBrush);
2858 /* Top-down to top-down tests */
2859 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2860 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2862 memset( expected, 0, get_dib_image_size( &biDst ) );
2863 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2864 expected[16] = 0xFEDCBA98, expected[17] = 0x76543210;
2865 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2866 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2868 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2869 expected[16] = 0x00000000, expected[17] = 0x00000000;
2870 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2871 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
2873 expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
2874 expected[16] = 0xCAFED00D, expected[17] = 0xCAFED00D;
2875 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2876 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
2878 /* This is an example of the dst width (height) == 1 exception, explored below */
2879 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2880 expected[16] = 0x00000000, expected[17] = 0x00000000;
2881 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2882 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
2884 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2885 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
2886 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2887 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2889 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2890 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
2891 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2892 1, 1, -2, -2, 0, 0, 2, 2, expected, __LINE__);
2894 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2895 expected[16] = 0x00000000, expected[17] = 0x00000000;
2896 todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2897 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
2899 expected[0] = 0x00000000, expected[1] = 0x00000000;
2900 expected[16] = 0x00000000, expected[17] = 0xCAFED00D, expected[18] = 0xFEEDFACE;
2901 expected[32] = 0x00000000, expected[33] = 0xFEDCBA98, expected[34] = 0x76543210;
2903 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2904 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2906 /* when dst width is 1 merge src width - 1 pixels */
2907 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
2908 srcBuffer[0] = 0x0000ff00, srcBuffer[1] = 0x0000f0f0, srcBuffer[2] = 0x0000cccc, srcBuffer[3] = 0x0000aaaa;
2909 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2911 memset( expected, 0, get_dib_image_size( &biDst ) );
2912 expected[0] = srcBuffer[0];
2913 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2914 0, 0, 1, 1, 0, 0, 2, 1, expected, __LINE__);
2916 expected[0] = srcBuffer[0] & srcBuffer[1];
2917 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2918 0, 0, 1, 1, 0, 0, 3, 1, expected, __LINE__);
2920 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
2921 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2922 0, 0, 1, 1, 0, 0, 4, 1, expected, __LINE__);
2924 /* this doesn't happen if the src width is -ve */
2925 expected[0] = srcBuffer[1] & srcBuffer[2];
2926 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2927 0, 0, 1, 1, 2, 0, -2, 1, expected, __LINE__);
2929 /* when dst width > 1 behaviour reverts to what one would expect */
2930 expected[0] = srcBuffer[0] & srcBuffer[1], expected[1] = srcBuffer[2] & srcBuffer[3];
2931 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2932 0, 0, 2, 1, 0, 0, 4, 1, expected, __LINE__);
2934 /* similarly in the vertical direction */
2935 memset( expected, 0, get_dib_image_size( &biDst ) );
2936 expected[0] = srcBuffer[0];
2937 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2938 0, 0, 1, 1, 0, 0, 1, 2, expected, __LINE__);
2940 /* check that it's the dst size in device units that needs to be 1 */
2941 SetMapMode( hdcDst, MM_ISOTROPIC );
2942 SetWindowExtEx( hdcDst, 200, 200, NULL );
2943 SetViewportExtEx( hdcDst, 100, 100, NULL );
2945 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
2946 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2947 0, 0, 2, 2, 0, 0, 4, 1, expected, __LINE__);
2948 SetMapMode( hdcDst, MM_TEXT );
2950 SelectObject(hdcDst, oldDst);
2951 DeleteObject(bmpDst);
2953 /* Top-down to bottom-up tests */
2954 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
2955 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2956 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2958 biDst.bmiHeader.biHeight = 16;
2959 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2960 NULL, 0);
2961 oldDst = SelectObject(hdcDst, bmpDst);
2963 memset( expected, 0, get_dib_image_size( &biDst ) );
2965 expected[224] = 0xFEDCBA98, expected[225] = 0x76543210;
2966 expected[240] = 0xCAFED00D, expected[241] = 0xFEEDFACE;
2967 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2968 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2970 expected[224] = 0xFEEDFACE, expected[225] = 0xCAFED00D;
2971 expected[240] = 0x76543210, expected[241] = 0xFEDCBA98;
2972 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2973 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2975 SelectObject(hdcSrc, oldSrc);
2976 DeleteObject(bmpSrc);
2978 /* Bottom-up to bottom-up tests */
2979 biSrc.bmiHeader.biHeight = 16;
2980 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2981 NULL, 0);
2982 srcBuffer[224] = 0xCAFED00D, srcBuffer[225] = 0xFEEDFACE;
2983 srcBuffer[240] = 0xFEDCBA98, srcBuffer[241] = 0x76543210;
2984 oldSrc = SelectObject(hdcSrc, bmpSrc);
2986 memset( expected, 0, get_dib_image_size( &biDst ) );
2988 expected[224] = 0xCAFED00D, expected[225] = 0xFEEDFACE;
2989 expected[240] = 0xFEDCBA98, expected[241] = 0x76543210;
2990 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2991 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2993 expected[224] = 0x76543210, expected[225] = 0xFEDCBA98;
2994 expected[240] = 0xFEEDFACE, expected[241] = 0xCAFED00D;
2995 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2996 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2998 SelectObject(hdcDst, oldDst);
2999 DeleteObject(bmpDst);
3001 /* Bottom-up to top-down tests */
3002 biDst.bmiHeader.biHeight = -16;
3003 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3004 NULL, 0);
3005 oldDst = SelectObject(hdcDst, bmpDst);
3007 memset( expected, 0, get_dib_image_size( &biDst ) );
3008 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3009 expected[16] = 0xCAFED00D, expected[17] = 0xFEEDFACE;
3010 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3011 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3013 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3014 expected[16] = 0x76543210, expected[17] = 0xFEDCBA98;
3015 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3016 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3018 SelectObject(hdcSrc, oldSrc);
3019 DeleteObject(bmpSrc);
3021 biSrc.bmiHeader.biHeight = -2;
3022 biSrc.bmiHeader.biBitCount = 24;
3023 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
3024 oldSrc = SelectObject(hdcSrc, bmpSrc);
3026 memset( expected, 0, get_dib_image_size( &biDst ) );
3027 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3028 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
3029 memcpy(dstBuffer, expected, 4 * sizeof(*dstBuffer));
3030 StretchBlt(hdcSrc, 0, 0, 4, 1, hdcDst, 0, 0, 4, 1, SRCCOPY );
3031 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
3032 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3033 expected[0] = 0x00EDFACE, expected[1] = 0x00FED00D;
3034 expected[2] = 0x00543210, expected[3] = 0x00DCBA98;
3035 ok(!memcmp(dstBuffer, expected, 16),
3036 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3037 expected[0], expected[1], expected[2], expected[3],
3038 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3040 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3041 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
3042 memcpy(srcBuffer, expected, 4 * sizeof(*dstBuffer));
3043 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
3044 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3045 expected[0] = 0x00EDFACE, expected[1] = 0x00D00DFE;
3046 expected[2] = 0x0010CAFE, expected[3] = 0x00765432;
3047 ok(!memcmp(dstBuffer, expected, 16),
3048 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3049 expected[0], expected[1], expected[2], expected[3],
3050 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3052 SelectObject(hdcSrc, oldSrc);
3053 DeleteObject(bmpSrc);
3055 biSrc.bmiHeader.biBitCount = 1;
3056 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
3057 oldSrc = SelectObject(hdcSrc, bmpSrc);
3058 *((DWORD *)colors + 0) = 0x123456;
3059 *((DWORD *)colors + 1) = 0x335577;
3060 SetDIBColorTable( hdcSrc, 0, 2, colors );
3061 srcBuffer[0] = 0x55555555;
3062 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
3063 SetTextColor( hdcDst, 0 );
3064 SetBkColor( hdcDst, 0 );
3065 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3066 expected[0] = expected[2] = 0x00123456;
3067 expected[1] = expected[3] = 0x00335577;
3068 ok(!memcmp(dstBuffer, expected, 16),
3069 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3070 expected[0], expected[1], expected[2], expected[3],
3071 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3073 SelectObject(hdcSrc, oldSrc);
3074 DeleteObject(bmpSrc);
3076 bmpSrc = CreateBitmap( 16, 16, 1, 1, 0 );
3077 oldSrc = SelectObject(hdcSrc, bmpSrc);
3078 SetPixel( hdcSrc, 0, 0, 0 );
3079 SetPixel( hdcSrc, 1, 0, 0xffffff );
3080 SetPixel( hdcSrc, 2, 0, 0xffffff );
3081 SetPixel( hdcSrc, 3, 0, 0 );
3082 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
3083 SetTextColor( hdcDst, RGB(0x22,0x44,0x66) );
3084 SetBkColor( hdcDst, RGB(0x65,0x43,0x21) );
3085 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3086 expected[0] = expected[3] = 0x00224466;
3087 expected[1] = expected[2] = 0x00654321;
3088 ok(!memcmp(dstBuffer, expected, 16),
3089 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3090 expected[0], expected[1], expected[2], expected[3],
3091 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3093 SelectObject(hdcSrc, oldSrc);
3094 DeleteObject(bmpSrc);
3096 DeleteDC(hdcSrc);
3098 SelectObject(hdcDst, oldDst);
3099 DeleteObject(bmpDst);
3100 DeleteDC(hdcDst);
3102 DeleteDC(hdcScreen);
3105 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3106 DWORD dwRop, UINT32 expected, int line)
3108 const UINT32 buffer[2] = { 0xFEDCBA98, 0 };
3109 BITMAPINFO bitmapInfo;
3111 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3112 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3113 bitmapInfo.bmiHeader.biWidth = 2;
3114 bitmapInfo.bmiHeader.biHeight = 1;
3115 bitmapInfo.bmiHeader.biPlanes = 1;
3116 bitmapInfo.bmiHeader.biBitCount = 32;
3117 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3118 bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer);
3120 *dstBuffer = 0x89ABCDEF;
3122 StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop);
3123 ok(expected == *dstBuffer,
3124 "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
3125 dwRop, expected, *dstBuffer, line);
3128 static void check_StretchDIBits_stretch(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3129 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
3130 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
3131 UINT32 expected[4], int line)
3133 BITMAPINFO bitmapInfo;
3135 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3136 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3137 bitmapInfo.bmiHeader.biWidth = 2;
3138 bitmapInfo.bmiHeader.biHeight = -2;
3139 bitmapInfo.bmiHeader.biPlanes = 1;
3140 bitmapInfo.bmiHeader.biBitCount = 32;
3141 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3143 memset(dstBuffer, 0, 16);
3144 StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
3145 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3146 srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
3147 ok(memcmp(dstBuffer, expected, 16) == 0,
3148 "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
3149 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
3150 expected[0], expected[1], expected[2], expected[3],
3151 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
3152 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3153 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
3156 static void test_StretchDIBits(void)
3158 HBITMAP bmpDst;
3159 HBITMAP oldDst;
3160 HDC hdcScreen, hdcDst;
3161 UINT32 *dstBuffer, srcBuffer[4];
3162 HBRUSH hBrush, hOldBrush;
3163 BITMAPINFO biDst;
3164 UINT32 expected[4];
3166 memset(&biDst, 0, sizeof(BITMAPINFO));
3167 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3168 biDst.bmiHeader.biWidth = 2;
3169 biDst.bmiHeader.biHeight = -2;
3170 biDst.bmiHeader.biPlanes = 1;
3171 biDst.bmiHeader.biBitCount = 32;
3172 biDst.bmiHeader.biCompression = BI_RGB;
3174 hdcScreen = CreateCompatibleDC(0);
3175 hdcDst = CreateCompatibleDC(hdcScreen);
3177 /* Pixel Tests */
3178 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3179 NULL, 0);
3180 oldDst = SelectObject(hdcDst, bmpDst);
3182 hBrush = CreateSolidBrush(0x012345678);
3183 hOldBrush = SelectObject(hdcDst, hBrush);
3185 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3186 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3187 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3188 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3189 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3190 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3191 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3192 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3193 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3194 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3195 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3196 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3197 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3198 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3199 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3201 SelectObject(hdcDst, hOldBrush);
3202 DeleteObject(hBrush);
3204 /* Top-down destination tests */
3205 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3206 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
3208 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
3209 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
3210 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3211 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3213 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3214 expected[2] = 0x00000000, expected[3] = 0x00000000;
3215 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3216 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
3218 expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
3219 expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
3220 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3221 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
3223 expected[0] = 0x42441000, expected[1] = 0x00000000;
3224 expected[2] = 0x00000000, expected[3] = 0x00000000;
3225 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3226 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
3228 expected[0] = 0x00000000, expected[1] = 0x00000000;
3229 expected[2] = 0x00000000, expected[3] = 0x00000000;
3230 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3231 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3233 expected[0] = 0x00000000, expected[1] = 0x00000000;
3234 expected[2] = 0x00000000, expected[3] = 0x00000000;
3235 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3236 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3238 expected[0] = 0x00000000, expected[1] = 0x00000000;
3239 expected[2] = 0x00000000, expected[3] = 0x00000000;
3240 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3241 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
3243 expected[0] = 0x00000000, expected[1] = 0x00000000;
3244 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
3245 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3246 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3248 SelectObject(hdcDst, oldDst);
3249 DeleteObject(bmpDst);
3251 /* Bottom up destination tests */
3252 biDst.bmiHeader.biHeight = 2;
3253 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3254 NULL, 0);
3255 oldDst = SelectObject(hdcDst, bmpDst);
3257 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3258 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
3259 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3260 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3262 /* Tidy up */
3263 SelectObject(hdcDst, oldDst);
3264 DeleteObject(bmpDst);
3265 DeleteDC(hdcDst);
3267 DeleteDC(hdcScreen);
3270 static void test_GdiAlphaBlend(void)
3272 HDC hdcNull;
3273 HDC hdcDst;
3274 HBITMAP bmpDst;
3275 HBITMAP oldDst;
3276 BITMAPINFO *bmi;
3277 HDC hdcSrc;
3278 HBITMAP bmpSrc;
3279 HBITMAP oldSrc;
3280 LPVOID bits;
3281 BOOL ret;
3282 BLENDFUNCTION blend;
3284 if (!pGdiAlphaBlend)
3286 win_skip("GdiAlphaBlend() is not implemented\n");
3287 return;
3290 hdcNull = GetDC(NULL);
3291 hdcDst = CreateCompatibleDC(hdcNull);
3292 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
3293 hdcSrc = CreateCompatibleDC(hdcNull);
3295 bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3296 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3297 bmi->bmiHeader.biHeight = 20;
3298 bmi->bmiHeader.biWidth = 20;
3299 bmi->bmiHeader.biBitCount = 32;
3300 bmi->bmiHeader.biPlanes = 1;
3301 bmi->bmiHeader.biCompression = BI_RGB;
3302 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3303 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3305 oldDst = SelectObject(hdcDst, bmpDst);
3306 oldSrc = SelectObject(hdcSrc, bmpSrc);
3308 blend.BlendOp = AC_SRC_OVER;
3309 blend.BlendFlags = 0;
3310 blend.SourceConstantAlpha = 128;
3311 blend.AlphaFormat = 0;
3313 SetLastError(0xdeadbeef);
3314 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3315 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3317 SetLastError(0xdeadbeef);
3318 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3319 ok( !ret, "GdiAlphaBlend succeeded\n" );
3320 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3322 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3323 ok( !ret, "GdiAlphaBlend succeeded\n" );
3324 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend);
3325 ok( !ret, "GdiAlphaBlend succeeded\n" );
3326 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3327 ok( !ret, "GdiAlphaBlend succeeded\n" );
3328 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3329 ok( !ret, "GdiAlphaBlend succeeded\n" );
3331 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
3332 SetLastError(0xdeadbeef);
3333 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3334 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3335 SetLastError(0xdeadbeef);
3336 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3337 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3338 SetMapMode(hdcSrc, MM_ANISOTROPIC);
3339 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
3340 SetLastError(0xdeadbeef);
3341 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend);
3342 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3343 SetLastError(0xdeadbeef);
3344 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend);
3345 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3347 SetLastError(0xdeadbeef);
3348 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend);
3349 ok( !ret, "GdiAlphaBlend succeeded\n" );
3350 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3352 /* overlapping source and dest not allowed */
3354 SetLastError(0xdeadbeef);
3355 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 19, 19, 20, 20, blend);
3356 ok( !ret, "GdiAlphaBlend succeeded\n" );
3357 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3359 SetLastError(0xdeadbeef);
3360 ret = pGdiAlphaBlend(hdcDst, 20, 20, 20, 20, hdcDst, 1, 1, 20, 20, blend);
3361 ok( !ret, "GdiAlphaBlend succeeded\n" );
3362 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3364 SetLastError(0xdeadbeef);
3365 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 20, 10, 20, 20, blend);
3366 ok( ret, "GdiAlphaBlend succeeded\n" );
3367 SetLastError(0xdeadbeef);
3368 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 10, 20, 20, 20, blend);
3369 ok( ret, "GdiAlphaBlend succeeded\n" );
3371 /* AC_SRC_ALPHA requires 32-bpp BI_RGB format */
3373 blend.AlphaFormat = AC_SRC_ALPHA;
3374 SetLastError(0xdeadbeef);
3375 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3376 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3378 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3379 ((DWORD *)bmi->bmiColors)[0] = 0xff0000;
3380 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3381 ((DWORD *)bmi->bmiColors)[2] = 0x0000ff;
3382 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3383 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3384 oldSrc = SelectObject(hdcSrc, bmpSrc);
3385 DeleteObject( oldSrc );
3387 SetLastError(0xdeadbeef);
3388 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3389 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3391 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3392 ((DWORD *)bmi->bmiColors)[0] = 0x0000ff;
3393 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3394 ((DWORD *)bmi->bmiColors)[2] = 0xff0000;
3395 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3396 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3397 oldSrc = SelectObject(hdcSrc, bmpSrc);
3398 DeleteObject( oldSrc );
3400 SetLastError(0xdeadbeef);
3401 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3402 ok( !ret, "GdiAlphaBlend succeeded\n" );
3403 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3405 bmi->bmiHeader.biBitCount = 24;
3406 bmi->bmiHeader.biCompression = BI_RGB;
3407 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3408 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3409 oldSrc = SelectObject(hdcSrc, bmpSrc);
3410 DeleteObject( oldSrc );
3412 SetLastError(0xdeadbeef);
3413 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3414 ok( !ret, "GdiAlphaBlend succeeded\n" );
3415 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3417 bmi->bmiHeader.biBitCount = 1;
3418 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3419 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3420 oldSrc = SelectObject(hdcSrc, bmpSrc);
3421 DeleteObject( oldSrc );
3423 SetLastError(0xdeadbeef);
3424 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3425 ok( !ret, "GdiAlphaBlend succeeded\n" );
3426 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3428 bmpSrc = CreateBitmap( 100, 100, 1, 1, NULL );
3429 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3430 oldSrc = SelectObject(hdcSrc, bmpSrc);
3431 DeleteObject( oldSrc );
3433 SetLastError(0xdeadbeef);
3434 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3435 ok( !ret, "GdiAlphaBlend succeeded\n" );
3436 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3438 SelectObject(hdcDst, oldDst);
3439 SelectObject(hdcSrc, oldSrc);
3440 DeleteObject(bmpSrc);
3441 DeleteObject(bmpDst);
3442 DeleteDC(hdcDst);
3443 DeleteDC(hdcSrc);
3445 ReleaseDC(NULL, hdcNull);
3449 static void test_GdiGradientFill(void)
3451 HDC hdc;
3452 BOOL ret;
3453 HBITMAP bmp;
3454 BITMAPINFO *bmi;
3455 void *bits;
3456 GRADIENT_RECT rect[] = { { 0, 0 }, { 0, 1 }, { 2, 3 } };
3457 GRADIENT_TRIANGLE tri[] = { { 0, 0, 0 }, { 0, 1, 2 }, { 0, 2, 1 }, { 0, 1, 3 } };
3458 TRIVERTEX vt[3] = { { 2, 2, 0xff00, 0x0000, 0x0000, 0x8000 },
3459 { 10, 10, 0x0000, 0xff00, 0x0000, 0x8000 },
3460 { 20, 10, 0x0000, 0x0000, 0xff00, 0xff00 } };
3462 if (!pGdiGradientFill)
3464 win_skip( "GdiGradientFill is not implemented\n" );
3465 return;
3468 hdc = CreateCompatibleDC( NULL );
3469 bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3470 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3471 bmi->bmiHeader.biHeight = 20;
3472 bmi->bmiHeader.biWidth = 20;
3473 bmi->bmiHeader.biBitCount = 32;
3474 bmi->bmiHeader.biPlanes = 1;
3475 bmi->bmiHeader.biCompression = BI_RGB;
3476 bmp = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3477 ok( bmp != NULL, "couldn't create bitmap\n" );
3478 SelectObject( hdc, bmp );
3480 SetLastError( 0xdeadbeef );
3481 ret = pGdiGradientFill( hdc, vt, 3, rect, 1, GRADIENT_FILL_RECT_H );
3482 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3483 SetLastError( 0xdeadbeef );
3484 ret = pGdiGradientFill( hdc, vt, 3, rect, 1, 3 );
3485 ok( !ret, "GdiGradientFill succeeded\n" );
3486 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3487 SetLastError( 0xdeadbeef );
3488 ret = pGdiGradientFill( (HDC)0xdead, vt, 3, rect, 1, GRADIENT_FILL_RECT_H );
3489 ok( !ret, "GdiGradientFill succeeded\n" );
3490 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3491 SetLastError( 0xdeadbeef );
3492 ret = pGdiGradientFill( NULL, NULL, 0, rect, 1, GRADIENT_FILL_RECT_H );
3493 ok( !ret, "GdiGradientFill succeeded\n" );
3494 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3495 ret = pGdiGradientFill( hdc, NULL, 0, rect, 1, GRADIENT_FILL_RECT_H );
3496 ok( !ret, "GdiGradientFill succeeded\n" );
3497 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3498 SetLastError( 0xdeadbeef );
3499 ret = pGdiGradientFill( hdc, NULL, 3, rect, 1, GRADIENT_FILL_RECT_H );
3500 ok( !ret, "GdiGradientFill succeeded\n" );
3501 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3502 SetLastError( 0xdeadbeef );
3503 ret = pGdiGradientFill( hdc, vt, 3, NULL, 0, GRADIENT_FILL_RECT_H );
3504 ok( !ret, "GdiGradientFill succeeded\n" );
3505 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3506 SetLastError( 0xdeadbeef );
3507 ret = pGdiGradientFill( hdc, vt, 3, NULL, 1, GRADIENT_FILL_RECT_H );
3508 ok( !ret, "GdiGradientFill succeeded\n" );
3509 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3510 SetLastError( 0xdeadbeef );
3511 ret = pGdiGradientFill( hdc, vt, 3, rect, 0, GRADIENT_FILL_RECT_H );
3512 ok( !ret, "GdiGradientFill succeeded\n" );
3513 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3514 SetLastError( 0xdeadbeef );
3515 ret = pGdiGradientFill( hdc, vt, 3, rect, 3, GRADIENT_FILL_RECT_H );
3516 ok( !ret, "GdiGradientFill succeeded\n" );
3517 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3518 rect[2].UpperLeft = rect[2].LowerRight = 1;
3519 SetLastError( 0xdeadbeef );
3520 ret = pGdiGradientFill( hdc, vt, 3, rect, 3, GRADIENT_FILL_RECT_H );
3521 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3522 SetLastError( 0xdeadbeef );
3523 ret = pGdiGradientFill( hdc, vt, 1, rect, 1, GRADIENT_FILL_RECT_H );
3524 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3525 SetLastError( 0xdeadbeef );
3526 ret = pGdiGradientFill( hdc, vt, 1, tri, 0, GRADIENT_FILL_TRIANGLE );
3527 ok( !ret, "GdiGradientFill succeeded\n" );
3528 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3529 SetLastError( 0xdeadbeef );
3530 ret = pGdiGradientFill( hdc, vt, 1, tri, 1, GRADIENT_FILL_TRIANGLE );
3531 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3532 SetLastError( 0xdeadbeef );
3533 ret = pGdiGradientFill( hdc, vt, 3, tri, 2, GRADIENT_FILL_TRIANGLE );
3534 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3535 SetLastError( 0xdeadbeef );
3536 ret = pGdiGradientFill( hdc, vt, 3, tri, 3, GRADIENT_FILL_TRIANGLE );
3537 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3538 SetLastError( 0xdeadbeef );
3539 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3540 ok( !ret, "GdiGradientFill succeeded\n" );
3541 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3542 tri[3].Vertex3 = 1;
3543 SetLastError( 0xdeadbeef );
3544 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3545 ok( !ret, "GdiGradientFill succeeded\n" );
3546 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3547 tri[3].Vertex3 = 0;
3548 SetLastError( 0xdeadbeef );
3549 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3550 ok( !ret, "GdiGradientFill succeeded\n" );
3551 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3552 tri[3].Vertex1 = tri[3].Vertex2 = tri[3].Vertex3 = 1;
3553 SetLastError( 0xdeadbeef );
3554 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3555 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3557 DeleteDC( hdc );
3558 DeleteObject( bmp );
3561 static void test_clipping(void)
3563 HBITMAP bmpDst;
3564 HBITMAP bmpSrc;
3565 HRGN hRgn;
3566 LPVOID bits;
3567 BOOL result;
3569 HDC hdcDst = CreateCompatibleDC( NULL );
3570 HDC hdcSrc = CreateCompatibleDC( NULL );
3572 BITMAPINFO bmpinfo={{0}};
3573 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3574 bmpinfo.bmiHeader.biWidth = 100;
3575 bmpinfo.bmiHeader.biHeight = 100;
3576 bmpinfo.bmiHeader.biPlanes = 1;
3577 bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3578 bmpinfo.bmiHeader.biCompression = BI_RGB;
3580 bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3581 ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3582 SelectObject( hdcDst, bmpDst );
3584 bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3585 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3586 SelectObject( hdcSrc, bmpSrc );
3588 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3589 ok(result, "BitBlt failed\n");
3591 hRgn = CreateRectRgn( 0,0,0,0 );
3592 SelectClipRgn( hdcDst, hRgn );
3594 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3595 ok(result, "BitBlt failed\n");
3597 DeleteObject( bmpDst );
3598 DeleteObject( bmpSrc );
3599 DeleteObject( hRgn );
3600 DeleteDC( hdcDst );
3601 DeleteDC( hdcSrc );
3604 static void test_32bit_ddb(void)
3606 char buffer[sizeof(BITMAPINFOHEADER) + sizeof(DWORD)];
3607 BITMAPINFO *biDst = (BITMAPINFO *)buffer;
3608 HBITMAP bmpSrc, bmpDst;
3609 HBITMAP oldSrc, oldDst;
3610 HDC hdcSrc, hdcDst, hdcScreen;
3611 HBRUSH brush;
3612 DWORD *dstBuffer, *data;
3613 DWORD colorSrc = 0x40201008;
3615 memset(biDst, 0, sizeof(BITMAPINFOHEADER));
3616 biDst->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3617 biDst->bmiHeader.biWidth = 1;
3618 biDst->bmiHeader.biHeight = -1;
3619 biDst->bmiHeader.biPlanes = 1;
3620 biDst->bmiHeader.biBitCount = 32;
3621 biDst->bmiHeader.biCompression = BI_RGB;
3623 hdcScreen = CreateCompatibleDC(0);
3624 if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3626 DeleteDC(hdcScreen);
3627 trace("Skipping 32-bit DDB test\n");
3628 return;
3631 hdcSrc = CreateCompatibleDC(hdcScreen);
3632 bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3633 oldSrc = SelectObject(hdcSrc, bmpSrc);
3635 hdcDst = CreateCompatibleDC(hdcScreen);
3636 bmpDst = CreateDIBSection(hdcDst, biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3637 oldDst = SelectObject(hdcDst, bmpDst);
3639 StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3640 ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3642 if (pGdiAlphaBlend)
3644 BLENDFUNCTION blend;
3645 BOOL ret;
3647 blend.BlendOp = AC_SRC_OVER;
3648 blend.BlendFlags = 0;
3649 blend.SourceConstantAlpha = 128;
3650 blend.AlphaFormat = 0;
3651 dstBuffer[0] = 0x80808080;
3652 ret = pGdiAlphaBlend( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, blend );
3653 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3654 ok(dstBuffer[0] == 0x60504844, "wrong color %x\n", dstBuffer[0]);
3655 blend.AlphaFormat = AC_SRC_ALPHA;
3656 dstBuffer[0] = 0x80808080;
3657 ret = pGdiAlphaBlend( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, blend );
3658 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3659 ok(dstBuffer[0] == 0x90807874, "wrong color %x\n", dstBuffer[0]);
3662 data = (DWORD *)biDst->bmiColors;
3663 data[0] = 0x20304050;
3664 brush = CreateDIBPatternBrushPt( biDst, DIB_RGB_COLORS );
3665 ok( brush != 0, "brush creation failed\n" );
3666 SelectObject( hdcSrc, brush );
3667 PatBlt( hdcSrc, 0, 0, 1, 1, PATCOPY );
3668 BitBlt( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, SRCCOPY );
3669 ok(dstBuffer[0] == data[0], "Expected color=%x, received color=%x\n", data[0], dstBuffer[0]);
3670 SelectObject( hdcSrc, GetStockObject(BLACK_BRUSH) );
3671 DeleteObject( brush );
3673 biDst->bmiHeader.biBitCount = 24;
3674 brush = CreateDIBPatternBrushPt( biDst, DIB_RGB_COLORS );
3675 ok( brush != 0, "brush creation failed\n" );
3676 SelectObject( hdcSrc, brush );
3677 PatBlt( hdcSrc, 0, 0, 1, 1, PATCOPY );
3678 BitBlt( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, SRCCOPY );
3679 ok(dstBuffer[0] == (data[0] & ~0xff000000),
3680 "Expected color=%x, received color=%x\n", data[0] & 0xff000000, dstBuffer[0]);
3681 SelectObject( hdcSrc, GetStockObject(BLACK_BRUSH) );
3682 DeleteObject( brush );
3684 /* Tidy up */
3685 SelectObject(hdcDst, oldDst);
3686 DeleteObject(bmpDst);
3687 DeleteDC(hdcDst);
3689 SelectObject(hdcSrc, oldSrc);
3690 DeleteObject(bmpSrc);
3691 DeleteDC(hdcSrc);
3693 DeleteDC(hdcScreen);
3697 * Used by test_GetDIBits_top_down to create the bitmap to test against.
3699 static void setup_picture(char *picture, int bpp)
3701 int i;
3703 switch(bpp)
3705 case 16:
3706 case 32:
3707 /*Set the first byte in each pixel to the index of that pixel.*/
3708 for (i = 0; i < 4; i++)
3709 picture[i * (bpp / 8)] = i;
3710 break;
3711 case 24:
3712 picture[0] = 0;
3713 picture[3] = 1;
3714 /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
3715 picture[8] = 2;
3716 picture[11] = 3;
3717 break;
3721 static void test_GetDIBits_top_down(int bpp)
3723 BITMAPINFO bi;
3724 HBITMAP bmptb, bmpbt;
3725 HDC hdc;
3726 int pictureOut[4];
3727 int *picture;
3728 int statusCode;
3730 memset( &bi, 0, sizeof(bi) );
3731 bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
3732 bi.bmiHeader.biWidth=2;
3733 bi.bmiHeader.biHeight=2;
3734 bi.bmiHeader.biPlanes=1;
3735 bi.bmiHeader.biBitCount=bpp;
3736 bi.bmiHeader.biCompression=BI_RGB;
3738 /*Get the device context for the screen.*/
3739 hdc = GetDC(NULL);
3740 ok(hdc != NULL, "Could not get a handle to a device context.\n");
3742 /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
3743 bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3744 ok(bmpbt != NULL, "Could not create a DIB section.\n");
3745 /*Now that we have a pointer to the pixels, we write to them.*/
3746 setup_picture((char*)picture, bpp);
3747 /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
3748 bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
3749 bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3750 ok(bmptb != NULL, "Could not create a DIB section.\n");
3751 /*Write to this top to bottom bitmap.*/
3752 setup_picture((char*)picture, bpp);
3754 bi.bmiHeader.biWidth = 1;
3756 bi.bmiHeader.biHeight = 2;
3757 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3758 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3759 /*Check the first byte of the pixel.*/
3760 ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3761 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3762 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3763 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3764 /*Check second scanline.*/
3765 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3766 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3767 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3768 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3769 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3770 ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3771 /*Check both scanlines.*/
3772 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3773 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3774 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3775 ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3776 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3777 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3778 ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3779 ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3781 /*Make destination bitmap top-down.*/
3782 bi.bmiHeader.biHeight = -2;
3783 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3784 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3785 ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3786 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3787 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3788 ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3789 /*Check second scanline.*/
3790 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3791 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3792 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3793 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3794 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3795 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3796 /*Check both scanlines.*/
3797 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3798 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3799 ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3800 ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3801 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3802 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3803 ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3804 ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3806 DeleteObject(bmpbt);
3807 DeleteObject(bmptb);
3810 static void test_GetSetDIBits_rtl(void)
3812 HDC hdc, hdc_mem;
3813 HBITMAP bitmap, orig_bitmap;
3814 BITMAPINFO info;
3815 int ret;
3816 DWORD bits_1[8 * 8], bits_2[8 * 8];
3818 if(!pSetLayout)
3820 win_skip("Don't have SetLayout\n");
3821 return;
3824 hdc = GetDC( NULL );
3825 hdc_mem = CreateCompatibleDC( hdc );
3826 pSetLayout( hdc_mem, LAYOUT_LTR );
3828 bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
3829 orig_bitmap = SelectObject( hdc_mem, bitmap );
3830 SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
3831 SelectObject( hdc_mem, orig_bitmap );
3833 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3834 info.bmiHeader.biWidth = 8;
3835 info.bmiHeader.biHeight = 8;
3836 info.bmiHeader.biPlanes = 1;
3837 info.bmiHeader.biBitCount = 32;
3838 info.bmiHeader.biCompression = BI_RGB;
3840 /* First show that GetDIBits ignores the layout mode. */
3842 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3843 ok(ret == 8, "got %d\n", ret);
3844 ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
3846 pSetLayout( hdc_mem, LAYOUT_RTL );
3848 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3849 ok(ret == 8, "got %d\n", ret);
3851 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3853 /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
3854 followed by a GetDIBits and show that the bits remain unchanged. */
3856 pSetLayout( hdc_mem, LAYOUT_LTR );
3858 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3859 ok(ret == 8, "got %d\n", ret);
3860 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3861 ok(ret == 8, "got %d\n", ret);
3862 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3864 pSetLayout( hdc_mem, LAYOUT_RTL );
3866 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3867 ok(ret == 8, "got %d\n", ret);
3868 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3869 ok(ret == 8, "got %d\n", ret);
3870 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3872 DeleteObject( bitmap );
3873 DeleteDC( hdc_mem );
3874 ReleaseDC( NULL, hdc );
3877 static void test_GetDIBits_scanlines(void)
3879 BITMAPINFO *info;
3880 DWORD *dib_bits;
3881 HDC hdc = GetDC( NULL );
3882 HBITMAP dib;
3883 DWORD data[128], inverted_bits[64];
3884 int i, ret;
3886 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
3888 info->bmiHeader.biSize = sizeof(info->bmiHeader);
3889 info->bmiHeader.biWidth = 8;
3890 info->bmiHeader.biHeight = 8;
3891 info->bmiHeader.biPlanes = 1;
3892 info->bmiHeader.biBitCount = 32;
3893 info->bmiHeader.biCompression = BI_RGB;
3895 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3897 for (i = 0; i < 64; i++)
3899 dib_bits[i] = i;
3900 inverted_bits[56 - (i & ~7) + (i & 7)] = i;
3903 /* b-u -> b-u */
3905 memset( data, 0xaa, sizeof(data) );
3907 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3908 ok( ret == 8, "got %d\n", ret );
3909 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3910 memset( data, 0xaa, sizeof(data) );
3912 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3913 ok( ret == 5, "got %d\n", ret );
3914 ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
3915 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3916 memset( data, 0xaa, sizeof(data) );
3918 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3919 ok( ret == 7, "got %d\n", ret );
3920 ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
3921 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3922 memset( data, 0xaa, sizeof(data) );
3924 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3925 ok( ret == 1, "got %d\n", ret );
3926 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3927 memset( data, 0xaa, sizeof(data) );
3929 info->bmiHeader.biHeight = 16;
3930 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3931 ok( ret == 5, "got %d\n", ret );
3932 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3933 ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
3934 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3935 memset( data, 0xaa, sizeof(data) );
3937 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3938 ok( ret == 6, "got %d\n", ret );
3939 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3940 ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
3941 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3942 memset( data, 0xaa, sizeof(data) );
3944 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3945 ok( ret == 0, "got %d\n", ret );
3946 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3947 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3948 memset( data, 0xaa, sizeof(data) );
3950 info->bmiHeader.biHeight = 5;
3951 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3952 ok( ret == 2, "got %d\n", ret );
3953 ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
3954 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3955 memset( data, 0xaa, sizeof(data) );
3957 /* b-u -> t-d */
3959 info->bmiHeader.biHeight = -8;
3960 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3961 ok( ret == 8, "got %d\n", ret );
3962 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3963 memset( data, 0xaa, sizeof(data) );
3965 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3966 ok( ret == 5, "got %d\n", ret );
3967 ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
3968 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3969 memset( data, 0xaa, sizeof(data) );
3971 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3972 ok( ret == 7, "got %d\n", ret );
3973 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3974 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3975 memset( data, 0xaa, sizeof(data) );
3977 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3978 ok( ret == 4, "got %d\n", ret );
3979 ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
3980 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3981 memset( data, 0xaa, sizeof(data) );
3983 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3984 ok( ret == 5, "got %d\n", ret );
3985 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3986 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3987 memset( data, 0xaa, sizeof(data) );
3989 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3990 ok( ret == 5, "got %d\n", ret );
3991 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3992 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3993 memset( data, 0xaa, sizeof(data) );
3995 info->bmiHeader.biHeight = -16;
3996 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3997 ok( ret == 8, "got %d\n", ret );
3998 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3999 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4000 memset( data, 0xaa, sizeof(data) );
4002 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4003 ok( ret == 5, "got %d\n", ret );
4004 ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
4005 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4006 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4007 memset( data, 0xaa, sizeof(data) );
4009 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4010 ok( ret == 8, "got %d\n", ret );
4011 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4012 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4013 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4014 memset( data, 0xaa, sizeof(data) );
4016 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4017 ok( ret == 8, "got %d\n", ret );
4018 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4019 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4020 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4021 memset( data, 0xaa, sizeof(data) );
4023 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4024 ok( ret == 7, "got %d\n", ret );
4025 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
4026 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4027 memset( data, 0xaa, sizeof(data) );
4029 ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
4030 ok( ret == 1, "got %d\n", ret );
4031 for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4032 memset( data, 0xaa, sizeof(data) );
4034 info->bmiHeader.biHeight = -5;
4035 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4036 ok( ret == 2, "got %d\n", ret );
4037 ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
4038 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4039 memset( data, 0xaa, sizeof(data) );
4041 DeleteObject( dib );
4043 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4044 info->bmiHeader.biWidth = 8;
4045 info->bmiHeader.biHeight = -8;
4046 info->bmiHeader.biPlanes = 1;
4047 info->bmiHeader.biBitCount = 32;
4048 info->bmiHeader.biCompression = BI_RGB;
4050 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4052 for (i = 0; i < 64; i++) dib_bits[i] = i;
4054 /* t-d -> t-d */
4056 info->bmiHeader.biHeight = -8;
4057 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4058 ok( ret == 8, "got %d\n", ret );
4059 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4060 memset( data, 0xaa, sizeof(data) );
4062 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4063 ok( ret == 5, "got %d\n", ret );
4064 ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
4065 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4066 memset( data, 0xaa, sizeof(data) );
4068 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4069 ok( ret == 7, "got %d\n", ret );
4070 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
4071 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4072 memset( data, 0xaa, sizeof(data) );
4074 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4075 ok( ret == 4, "got %d\n", ret );
4076 ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
4077 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4078 memset( data, 0xaa, sizeof(data) );
4080 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
4081 ok( ret == 5, "got %d\n", ret );
4082 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
4083 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4084 memset( data, 0xaa, sizeof(data) );
4086 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
4087 ok( ret == 5, "got %d\n", ret );
4088 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
4089 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4090 memset( data, 0xaa, sizeof(data) );
4092 info->bmiHeader.biHeight = -16;
4093 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
4094 ok( ret == 8, "got %d\n", ret );
4095 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4096 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4097 memset( data, 0xaa, sizeof(data) );
4099 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4100 ok( ret == 5, "got %d\n", ret );
4101 ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
4102 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4103 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4104 memset( data, 0xaa, sizeof(data) );
4106 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4107 ok( ret == 8, "got %d\n", ret );
4108 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4109 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4110 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4111 memset( data, 0xaa, sizeof(data) );
4113 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4114 ok( ret == 8, "got %d\n", ret );
4115 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4116 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4117 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4118 memset( data, 0xaa, sizeof(data) );
4120 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4121 ok( ret == 7, "got %d\n", ret );
4122 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
4123 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4124 memset( data, 0xaa, sizeof(data) );
4126 info->bmiHeader.biHeight = -5;
4127 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4128 ok( ret == 2, "got %d\n", ret );
4129 ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
4130 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4131 memset( data, 0xaa, sizeof(data) );
4134 /* t-d -> b-u */
4136 info->bmiHeader.biHeight = 8;
4138 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4139 ok( ret == 8, "got %d\n", ret );
4140 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4141 memset( data, 0xaa, sizeof(data) );
4143 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4144 ok( ret == 5, "got %d\n", ret );
4145 ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
4146 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4147 memset( data, 0xaa, sizeof(data) );
4149 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4150 ok( ret == 7, "got %d\n", ret );
4151 ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
4152 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4153 memset( data, 0xaa, sizeof(data) );
4155 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4156 ok( ret == 1, "got %d\n", ret );
4157 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4158 memset( data, 0xaa, sizeof(data) );
4160 info->bmiHeader.biHeight = 16;
4161 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4162 ok( ret == 5, "got %d\n", ret );
4163 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4164 ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
4165 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4166 memset( data, 0xaa, sizeof(data) );
4168 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
4169 ok( ret == 6, "got %d\n", ret );
4170 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4171 ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
4172 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4173 memset( data, 0xaa, sizeof(data) );
4175 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
4176 ok( ret == 0, "got %d\n", ret );
4177 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4178 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4179 memset( data, 0xaa, sizeof(data) );
4181 info->bmiHeader.biHeight = 5;
4182 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4183 ok( ret == 2, "got %d\n", ret );
4184 ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
4185 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4186 memset( data, 0xaa, sizeof(data) );
4188 DeleteObject( dib );
4190 ReleaseDC( NULL, hdc );
4191 HeapFree( GetProcessHeap(), 0, info );
4195 static void test_SetDIBits(void)
4197 char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
4198 LOGPALETTE *pal = (LOGPALETTE *)palbuf;
4199 PALETTEENTRY *palent = pal->palPalEntry;
4200 HPALETTE palette;
4201 BITMAPINFO *info;
4202 DWORD *dib_bits;
4203 HDC hdc = GetDC( NULL );
4204 DWORD data[128], inverted_data[128];
4205 HBITMAP dib;
4206 int i, ret;
4208 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4210 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4211 info->bmiHeader.biWidth = 8;
4212 info->bmiHeader.biHeight = 8;
4213 info->bmiHeader.biPlanes = 1;
4214 info->bmiHeader.biBitCount = 32;
4215 info->bmiHeader.biCompression = BI_RGB;
4217 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4218 memset( dib_bits, 0xaa, 64 * 4 );
4220 for (i = 0; i < 128; i++)
4222 data[i] = i;
4223 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4226 /* b-u -> b-u */
4228 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4229 ok( ret == 8, "got %d\n", ret );
4230 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4231 memset( dib_bits, 0xaa, 64 * 4 );
4233 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4234 ok( ret == 5, "got %d\n", ret );
4235 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4236 ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
4237 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4238 memset( dib_bits, 0xaa, 64 * 4 );
4240 /* top of dst is aligned with startscans down for the top of the src.
4241 Then starting from the bottom of src, lines rows are copied across. */
4243 info->bmiHeader.biHeight = 16;
4244 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4245 ok( ret == 12, "got %d\n", ret );
4246 ok( !memcmp( dib_bits, data + 56, 40 * 4 ), "bits differ\n");
4247 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4248 memset( dib_bits, 0xaa, 64 * 4 );
4250 info->bmiHeader.biHeight = 5;
4251 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4252 ok( ret == 2, "got %d\n", ret );
4253 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4254 ok( !memcmp( dib_bits + 32, data, 16 * 4 ), "bits differ\n");
4255 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4256 memset( dib_bits, 0xaa, 64 * 4 );
4258 /* t-d -> b-u */
4259 info->bmiHeader.biHeight = -8;
4260 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4261 ok( ret == 8, "got %d\n", ret );
4262 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4263 memset( dib_bits, 0xaa, 64 * 4 );
4265 /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
4266 we copy lines rows from the top of the src */
4268 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4269 ok( ret == 5, "got %d\n", ret );
4270 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4271 ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
4272 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4273 memset( dib_bits, 0xaa, 64 * 4 );
4275 info->bmiHeader.biHeight = -16;
4276 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4277 ok( ret == 12, "got %d\n", ret );
4278 ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
4279 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4280 memset( dib_bits, 0xaa, 64 * 4 );
4282 ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4283 ok( ret == 12, "got %d\n", ret );
4284 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4285 memset( dib_bits, 0xaa, 64 * 4 );
4287 ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4288 ok( ret == 12, "got %d\n", ret );
4289 ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
4290 memset( dib_bits, 0xaa, 64 * 4 );
4292 info->bmiHeader.biHeight = -5;
4293 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4294 ok( ret == 2, "got %d\n", ret );
4295 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4296 ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
4297 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4298 memset( dib_bits, 0xaa, 64 * 4 );
4300 DeleteObject( dib );
4302 info->bmiHeader.biHeight = -8;
4304 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4305 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4307 /* t-d -> t-d */
4309 /* like the t-d -> b-u case. */
4311 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4312 ok( ret == 8, "got %d\n", ret );
4313 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4314 memset( dib_bits, 0xaa, 64 * 4 );
4316 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4317 ok( ret == 5, "got %d\n", ret );
4318 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4319 ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
4320 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4321 memset( dib_bits, 0xaa, 64 * 4 );
4323 info->bmiHeader.biHeight = -16;
4324 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4325 ok( ret == 12, "got %d\n", ret );
4326 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4327 ok( !memcmp( dib_bits + 24, data, 40 * 4 ), "bits differ\n");
4328 memset( dib_bits, 0xaa, 64 * 4 );
4330 info->bmiHeader.biHeight = -5;
4331 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4332 ok( ret == 2, "got %d\n", ret );
4333 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4334 ok( !memcmp( dib_bits + 16, data, 16 * 4 ), "bits differ\n");
4335 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4336 memset( dib_bits, 0xaa, 64 * 4 );
4338 /* b-u -> t-d */
4339 /* like the b-u -> b-u case */
4341 info->bmiHeader.biHeight = 8;
4342 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4343 ok( ret == 8, "got %d\n", ret );
4344 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4345 memset( dib_bits, 0xaa, 64 * 4 );
4347 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4348 ok( ret == 5, "got %d\n", ret );
4349 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4350 ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
4351 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4352 memset( dib_bits, 0xaa, 64 * 4 );
4354 info->bmiHeader.biHeight = 16;
4355 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4356 ok( ret == 12, "got %d\n", ret );
4357 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4358 ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
4359 memset( dib_bits, 0xaa, 64 * 4 );
4361 info->bmiHeader.biHeight = 5;
4362 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4363 ok( ret == 2, "got %d\n", ret );
4364 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4365 ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
4366 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4367 memset( dib_bits, 0xaa, 64 * 4 );
4369 /* handling of partial color table */
4371 info->bmiHeader.biHeight = -8;
4372 info->bmiHeader.biBitCount = 8;
4373 info->bmiHeader.biClrUsed = 137;
4374 for (i = 0; i < 256; i++)
4376 info->bmiColors[i].rgbRed = 255 - i;
4377 info->bmiColors[i].rgbGreen = i * 2;
4378 info->bmiColors[i].rgbBlue = i;
4379 info->bmiColors[i].rgbReserved = 0;
4381 for (i = 0; i < 64; i++) ((BYTE *)data)[i] = i * 4 + 1;
4382 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4383 ok( ret == 8, "got %d\n", ret );
4384 for (i = 0; i < 64; i++)
4386 int idx = i * 4 + 1;
4387 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : (info->bmiColors[idx].rgbRed << 16 |
4388 info->bmiColors[idx].rgbGreen << 8 |
4389 info->bmiColors[idx].rgbBlue);
4390 ok( dib_bits[i] == expect, "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
4392 memset( dib_bits, 0xaa, 64 * 4 );
4394 /* handling of DIB_PAL_COLORS */
4396 pal->palVersion = 0x300;
4397 pal->palNumEntries = 137;
4398 info->bmiHeader.biClrUsed = 221;
4399 for (i = 0; i < 256; i++)
4401 palent[i].peRed = i * 2;
4402 palent[i].peGreen = 255 - i;
4403 palent[i].peBlue = i;
4405 palette = CreatePalette( pal );
4406 ok( palette != 0, "palette creation failed\n" );
4407 SelectPalette( hdc, palette, FALSE );
4408 for (i = 0; i < 256; i++) ((WORD *)info->bmiColors)[i] = 255 - i;
4409 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_PAL_COLORS );
4410 ok( ret == 8, "got %d\n", ret );
4411 for (i = 0; i < 64; i++)
4413 int idx = i * 4 + 1;
4414 int ent = (255 - idx) % pal->palNumEntries;
4415 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 :
4416 (palent[ent].peRed << 16 | palent[ent].peGreen << 8 | palent[ent].peBlue);
4417 ok( dib_bits[i] == expect || broken(dib_bits[i] == 0), /* various Windows versions get some values wrong */
4418 "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
4420 memset( dib_bits, 0xaa, 64 * 4 );
4422 ReleaseDC( NULL, hdc );
4423 DeleteObject( dib );
4424 DeleteObject( palette );
4425 HeapFree( GetProcessHeap(), 0, info );
4428 static void test_SetDIBits_RLE4(void)
4430 BITMAPINFO *info;
4431 DWORD *dib_bits;
4432 HDC hdc = GetDC( NULL );
4433 BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00, /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
4434 0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
4435 0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00, /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
4436 0x00, 0x02, 0x01, 0x02, 0x05, 0x87, /* dx=1, dy=2, 8, 7, 8, 7, 8 */
4437 0x00, 0x01 }; /* <eod> */
4438 HBITMAP dib;
4439 int i, ret;
4440 DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
4441 0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
4442 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4443 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4444 0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
4445 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4446 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4447 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4449 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4451 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4452 info->bmiHeader.biWidth = 8;
4453 info->bmiHeader.biHeight = 8;
4454 info->bmiHeader.biPlanes = 1;
4455 info->bmiHeader.biBitCount = 32;
4456 info->bmiHeader.biCompression = BI_RGB;
4458 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4459 memset( dib_bits, 0xaa, 64 * 4 );
4461 info->bmiHeader.biBitCount = 4;
4462 info->bmiHeader.biCompression = BI_RLE4;
4463 info->bmiHeader.biSizeImage = sizeof(rle4_data);
4465 for (i = 0; i < 16; i++)
4467 info->bmiColors[i].rgbRed = i;
4468 info->bmiColors[i].rgbGreen = i;
4469 info->bmiColors[i].rgbBlue = i;
4470 info->bmiColors[i].rgbReserved = 0;
4473 ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
4474 ok( ret == 8, "got %d\n", ret );
4475 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
4476 memset( dib_bits, 0xaa, 64 * 4 );
4478 DeleteObject( dib );
4479 ReleaseDC( NULL, hdc );
4480 HeapFree( GetProcessHeap(), 0, info );
4483 static void test_SetDIBits_RLE8(void)
4485 BITMAPINFO *info;
4486 DWORD *dib_bits;
4487 HDC hdc = GetDC( NULL );
4488 BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00, /* 2, 2, 2, f0, f0, f0, f0, <eol> */
4489 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4490 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4491 0x00, 0x01 }; /* <eod> */
4492 HBITMAP dib;
4493 int i, ret;
4494 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4495 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4496 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4497 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4498 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4499 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4500 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4501 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4502 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4503 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4504 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4505 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4506 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4507 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4508 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4509 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4511 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4513 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4514 info->bmiHeader.biWidth = 8;
4515 info->bmiHeader.biHeight = 8;
4516 info->bmiHeader.biPlanes = 1;
4517 info->bmiHeader.biBitCount = 32;
4518 info->bmiHeader.biCompression = BI_RGB;
4520 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4521 memset( dib_bits, 0xaa, 64 * 4 );
4523 info->bmiHeader.biBitCount = 8;
4524 info->bmiHeader.biCompression = BI_RLE8;
4525 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4527 for (i = 0; i < 256; i++)
4529 info->bmiColors[i].rgbRed = i;
4530 info->bmiColors[i].rgbGreen = i;
4531 info->bmiColors[i].rgbBlue = i;
4532 info->bmiColors[i].rgbReserved = 0;
4535 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4536 ok( ret == 8, "got %d\n", ret );
4537 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4538 memset( dib_bits, 0xaa, 64 * 4 );
4540 /* startscan and lines are ignored, unless lines == 0 */
4541 ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4542 ok( ret == 8, "got %d\n", ret );
4543 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4544 memset( dib_bits, 0xaa, 64 * 4 );
4546 ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4547 ok( ret == 8, "got %d\n", ret );
4548 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4549 memset( dib_bits, 0xaa, 64 * 4 );
4551 ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4552 ok( ret == 0, "got %d\n", ret );
4553 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4554 memset( dib_bits, 0xaa, 64 * 4 );
4556 /* reduce width to 4, left-hand side of dst is touched. */
4557 info->bmiHeader.biWidth = 4;
4558 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4559 ok( ret == 8, "got %d\n", ret );
4560 for (i = 0; i < 64; i++)
4562 DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4563 ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4565 memset( dib_bits, 0xaa, 64 * 4 );
4567 /* Show that the top lines are aligned by adjusting the height of the src */
4569 /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4570 info->bmiHeader.biWidth = 8;
4571 info->bmiHeader.biHeight = 4;
4572 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4573 ok( ret == 4, "got %d\n", ret );
4574 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4575 ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4576 memset( dib_bits, 0xaa, 64 * 4 );
4578 /* increase the height to 9 -> everything moves down one row. */
4579 info->bmiHeader.biHeight = 9;
4580 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4581 ok( ret == 9, "got %d\n", ret );
4582 ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4583 for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4584 memset( dib_bits, 0xaa, 64 * 4 );
4586 /* top-down compressed dibs are invalid */
4587 info->bmiHeader.biHeight = -8;
4588 SetLastError( 0xdeadbeef );
4589 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4590 ok( ret == 0, "got %d\n", ret );
4591 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4592 DeleteObject( dib );
4594 /* top-down dst */
4596 info->bmiHeader.biHeight = -8;
4597 info->bmiHeader.biBitCount = 32;
4598 info->bmiHeader.biCompression = BI_RGB;
4599 info->bmiHeader.biSizeImage = 0;
4601 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4602 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4604 info->bmiHeader.biHeight = 8;
4605 info->bmiHeader.biBitCount = 8;
4606 info->bmiHeader.biCompression = BI_RLE8;
4607 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4609 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4610 ok( ret == 8, "got %d\n", ret );
4611 ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4612 memset( dib_bits, 0xaa, 64 * 4 );
4614 info->bmiHeader.biHeight = 4;
4615 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4616 ok( ret == 4, "got %d\n", ret );
4617 ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4618 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4619 memset( dib_bits, 0xaa, 64 * 4 );
4621 info->bmiHeader.biHeight = 9;
4622 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4623 ok( ret == 9, "got %d\n", ret );
4624 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4625 ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4626 memset( dib_bits, 0xaa, 64 * 4 );
4628 DeleteObject( dib );
4629 ReleaseDC( NULL, hdc );
4630 HeapFree( GetProcessHeap(), 0, info );
4633 static void test_SetDIBitsToDevice(void)
4635 char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
4636 LOGPALETTE *pal = (LOGPALETTE *)palbuf;
4637 PALETTEENTRY *palent = pal->palPalEntry;
4638 HPALETTE palette;
4639 BITMAPINFO *info;
4640 DWORD *dib_bits;
4641 HDC hdc = CreateCompatibleDC( 0 );
4642 DWORD data[128], inverted_data[128];
4643 HBITMAP dib;
4644 int i, ret;
4646 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4648 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4649 info->bmiHeader.biWidth = 8;
4650 info->bmiHeader.biHeight = 8;
4651 info->bmiHeader.biPlanes = 1;
4652 info->bmiHeader.biBitCount = 32;
4653 info->bmiHeader.biCompression = BI_RGB;
4655 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4656 memset( dib_bits, 0xaa, 64 * 4 );
4657 SelectObject( hdc, dib );
4659 for (i = 0; i < 128; i++)
4661 data[i] = i;
4662 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4665 /* b-u -> b-u */
4667 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4668 ok( ret == 8, "got %d\n", ret );
4669 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4670 memset( dib_bits, 0xaa, 64 * 4 );
4672 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4673 ok( ret == 5, "got %d\n", ret );
4674 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4675 for (i = 8; i < 48; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4676 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4677 memset( dib_bits, 0xaa, 64 * 4 );
4679 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 3, 1, 5, data, info, DIB_RGB_COLORS );
4680 ok( ret == 5, "got %d\n", ret );
4681 for (i = 0; i < 24; i++) ok( dib_bits[i] == data[i + 16], "%d: got %08x\n", i, dib_bits[i] );
4682 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4683 memset( dib_bits, 0xaa, 64 * 4 );
4685 info->bmiHeader.biHeight = 16;
4686 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4687 ok( ret == 7, "got %d\n", ret );
4688 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4689 for (i = 8; i < 64; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4690 memset( dib_bits, 0xaa, 64 * 4 );
4692 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 8, 0, 6, 1, 12, data, info, DIB_RGB_COLORS );
4693 ok( ret == 12, "got %d\n", ret );
4694 for (i = 0; i < 40; i++) ok( dib_bits[i] == data[i + 56], "%d: got %08x\n", i, dib_bits[i] );
4695 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4696 memset( dib_bits, 0xaa, 64 * 4 );
4698 ret = SetDIBitsToDevice( hdc, 0, -4, 8, 8, 0, 3, 1, 12, data, info, DIB_RGB_COLORS );
4699 ok( ret == 10, "got %d\n", ret );
4700 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4701 for (i = 32; i < 64; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4702 memset( dib_bits, 0xaa, 64 * 4 );
4704 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, -3, 1, 12, data, info, DIB_RGB_COLORS );
4705 ok( ret == 4, "got %d\n", ret );
4706 for (i = 0; i < 32; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4707 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4708 memset( dib_bits, 0xaa, 64 * 4 );
4710 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 5, 0, -2, 1, 12, data, info, DIB_RGB_COLORS );
4711 ok( ret == 2, "got %d\n", ret );
4712 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4713 for (i = 32; i < 48; i++) ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4714 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4715 memset( dib_bits, 0xaa, 64 * 4 );
4717 info->bmiHeader.biHeight = 5;
4718 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 2, 2, data, info, DIB_RGB_COLORS );
4719 ok( ret == 2, "got %d\n", ret );
4720 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4721 for (i = 16; i < 32; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4722 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4723 memset( dib_bits, 0xaa, 64 * 4 );
4725 ret = SetDIBitsToDevice( hdc, 3, 3, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4726 ok( ret == 3, "got %d\n", ret );
4727 for (i = 0; i < 64; i++)
4728 if (i == 27 || i == 28 || i == 35 || i == 36)
4729 ok( dib_bits[i] == data[i - 18], "%d: got %08x\n", i, dib_bits[i] );
4730 else
4731 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4732 memset( dib_bits, 0xaa, 64 * 4 );
4734 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4735 ok( ret == 5, "got %d\n", ret );
4736 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4737 memset( dib_bits, 0xaa, 64 * 4 );
4739 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4740 ok( ret == 0, "got %d\n", ret );
4741 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4742 memset( dib_bits, 0xaa, 64 * 4 );
4744 SetMapMode( hdc, MM_ANISOTROPIC );
4745 SetWindowExtEx( hdc, 3, 3, NULL );
4746 ret = SetDIBitsToDevice( hdc, 2, 2, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4747 ok( ret == 3, "got %d\n", ret );
4748 for (i = 0; i < 64; i++)
4749 if (i == 41 || i == 42 || i == 49 || i == 50)
4750 ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4751 else
4752 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4753 memset( dib_bits, 0xaa, 64 * 4 );
4755 SetWindowExtEx( hdc, -1, -1, NULL );
4756 ret = SetDIBitsToDevice( hdc, 2, 2, 4, 4, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4757 ok( ret == 4, "got %d\n", ret );
4758 for (i = 0; i < 64; i++)
4759 if (i == 48 || i == 49 || i == 56 || i == 57)
4760 ok( dib_bits[i] == data[i - 37], "%d: got %08x\n", i, dib_bits[i] );
4761 else
4762 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4763 memset( dib_bits, 0xaa, 64 * 4 );
4764 SetMapMode( hdc, MM_TEXT );
4766 if (pSetLayout)
4768 pSetLayout( hdc, LAYOUT_RTL );
4769 ret = SetDIBitsToDevice( hdc, 1, 2, 3, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4770 ok( ret == 3, "got %d\n", ret );
4771 for (i = 0; i < 64; i++)
4772 if (i == 36 || i == 37 || i == 38 || i == 44 || i == 45 || i == 46)
4773 ok( dib_bits[i] == data[i - 27], "%d: got %08x\n", i, dib_bits[i] );
4774 else
4775 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4776 memset( dib_bits, 0xaa, 64 * 4 );
4777 pSetLayout( hdc, LAYOUT_LTR );
4780 /* t-d -> b-u */
4781 info->bmiHeader.biHeight = -8;
4782 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4783 ok( ret == 8, "got %d\n", ret );
4784 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4785 memset( dib_bits, 0xaa, 64 * 4 );
4787 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4788 ok( ret == 5, "got %d\n", ret );
4789 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4790 for (i = 8; i < 48; i++) ok( dib_bits[i] == inverted_data[i + 80], "%d: got %08x\n", i, dib_bits[i] );
4791 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4792 memset( dib_bits, 0xaa, 64 * 4 );
4794 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 4, 1, 5, data, info, DIB_RGB_COLORS );
4795 ok( ret == 5, "got %d\n", ret );
4796 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4797 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4798 memset( dib_bits, 0xaa, 64 * 4 );
4800 info->bmiHeader.biHeight = -16;
4801 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4802 ok( ret == 12, "got %d\n", ret );
4803 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4804 for (i = 8; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4805 memset( dib_bits, 0xaa, 64 * 4 );
4807 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, 7, 1, 12, data, info, DIB_RGB_COLORS );
4808 ok( ret == 12, "got %d\n", ret );
4809 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4810 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4811 memset( dib_bits, 0xaa, 64 * 4 );
4813 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 4, 12, data, info, DIB_RGB_COLORS );
4814 ok( ret == 12, "got %d\n", ret );
4815 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4816 for (i = 32; i < 64; i++) ok( dib_bits[i] == inverted_data[i], "%d: got %08x\n", i, dib_bits[i] );
4817 memset( dib_bits, 0xaa, 64 * 4 );
4819 ret = SetDIBitsToDevice( hdc, 0, -3, 8, 8, 0, 2, 4, 12, data, info, DIB_RGB_COLORS );
4820 ok( ret == 12, "got %d\n", ret );
4821 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4822 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4823 memset( dib_bits, 0xaa, 64 * 4 );
4825 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, -2, 4, 12, data, info, DIB_RGB_COLORS );
4826 ok( ret == 12, "got %d\n", ret );
4827 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4828 for (i = 24; i < 40; i++) ok( dib_bits[i] == inverted_data[i + 8], "%d: got %08x\n", i, dib_bits[i] );
4829 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4830 memset( dib_bits, 0xaa, 64 * 4 );
4832 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 5, 12, data, info, DIB_RGB_COLORS );
4833 ok( ret == 12, "got %d\n", ret );
4834 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4835 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4836 memset( dib_bits, 0xaa, 64 * 4 );
4838 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4839 ok( ret == 12, "got %d\n", ret );
4840 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4841 memset( dib_bits, 0xaa, 64 * 4 );
4843 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -2, -4, 0, 12, data, info, DIB_RGB_COLORS );
4844 ok( ret == 12, "got %d\n", ret );
4845 for (i = 0; i < 64; i++)
4846 if (i == 31 || i == 39 || i == 47 || i == 55 || i == 63)
4847 ok( dib_bits[i] == inverted_data[i + 1], "%d: got %08x\n", i, dib_bits[i] );
4848 else
4849 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4850 memset( dib_bits, 0xaa, 64 * 4 );
4852 info->bmiHeader.biHeight = -5;
4853 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4854 ok( ret == 2, "got %d\n", ret );
4855 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4856 for (i = 8; i < 24; i++) ok( dib_bits[i] == inverted_data[i + 104], "%d: got %08x\n", i, dib_bits[i] );
4857 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4858 memset( dib_bits, 0xaa, 64 * 4 );
4860 ret = SetDIBitsToDevice( hdc, 5, 4, 2, 2, 6, 3, 1, 5, data, info, DIB_RGB_COLORS );
4861 ok( ret == 5, "got %d\n", ret );
4862 for (i = 0; i < 64; i++)
4863 if (i == 21 || i == 22 || i == 29 || i == 30)
4864 ok( dib_bits[i] == inverted_data[i + 89], "%d: got %08x\n", i, dib_bits[i] );
4865 else
4866 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4867 memset( dib_bits, 0xaa, 64 * 4 );
4869 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4870 ok( ret == 5, "got %d\n", ret );
4871 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4872 memset( dib_bits, 0xaa, 64 * 4 );
4874 info->bmiHeader.biHeight = -8;
4876 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4877 DeleteObject( SelectObject( hdc, dib ));
4878 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4880 /* t-d -> t-d */
4882 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4883 ok( ret == 8, "got %d\n", ret );
4884 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4885 memset( dib_bits, 0xaa, 64 * 4 );
4887 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4888 ok( ret == 5, "got %d\n", ret );
4889 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4890 for (i = 16; i < 56; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4891 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4892 memset( dib_bits, 0xaa, 64 * 4 );
4894 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 3, 0, 2, 1, 5, data, info, DIB_RGB_COLORS );
4895 ok( ret == 5, "got %d\n", ret );
4896 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4897 for (i = 24; i < 48; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4898 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4899 memset( dib_bits, 0xaa, 64 * 4 );
4901 info->bmiHeader.biHeight = -16;
4902 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4903 ok( ret == 12, "got %d\n", ret );
4904 for (i = 0; i < 56; i++) ok( dib_bits[i] == data[i + 40], "%d: got %08x\n", i, dib_bits[i] );
4905 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4906 memset( dib_bits, 0xaa, 64 * 4 );
4908 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -1, -8, 0, 12, data, info, DIB_RGB_COLORS );
4909 ok( ret == 12, "got %d\n", ret );
4910 for (i = 0; i < 64; i++)
4911 if (i == 6 || i == 7)
4912 ok( dib_bits[i] == data[i + 82], "%d: got %08x\n", i, dib_bits[i] );
4913 else
4914 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4915 memset( dib_bits, 0xaa, 64 * 4 );
4917 info->bmiHeader.biHeight = -5;
4918 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4919 ok( ret == 2, "got %d\n", ret );
4920 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4921 for (i = 40; i < 56; i++) ok( dib_bits[i] == data[i - 40], "%d: got %08x\n", i, dib_bits[i] );
4922 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4923 memset( dib_bits, 0xaa, 64 * 4 );
4925 ret = SetDIBitsToDevice( hdc, 7, 2, 8, 8, 1, 0, 0, 5, data, info, DIB_RGB_COLORS );
4926 ok( ret == 5, "got %d\n", ret );
4927 for (i = 0; i < 64; i++)
4928 if (i == 47 || i == 55 || i == 63)
4929 ok( dib_bits[i] == data[i - 46], "%d: got %08x\n", i, dib_bits[i] );
4930 else
4931 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4932 memset( dib_bits, 0xaa, 64 * 4 );
4934 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4935 ok( ret == 5, "got %d\n", ret );
4936 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4937 memset( dib_bits, 0xaa, 64 * 4 );
4939 /* b-u -> t-d */
4941 info->bmiHeader.biHeight = 8;
4942 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4943 ok( ret == 8, "got %d\n", ret );
4944 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4945 memset( dib_bits, 0xaa, 64 * 4 );
4947 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4948 ok( ret == 5, "got %d\n", ret );
4949 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4950 for (i = 16; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4951 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4952 memset( dib_bits, 0xaa, 64 * 4 );
4954 info->bmiHeader.biHeight = 16;
4955 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4956 ok( ret == 7, "got %d\n", ret );
4957 for (i = 0; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4958 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4959 memset( dib_bits, 0xaa, 64 * 4 );
4961 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, 0, -4, 1, 12, data, info, DIB_RGB_COLORS );
4962 ok( ret == 3, "got %d\n", ret );
4963 for (i = 0; i < 64; i++)
4964 if ((i >= 36 && i <= 39) || (i >= 44 && i <= 47) || (i >= 52 && i <= 55))
4965 ok( dib_bits[i] == inverted_data[i + 68], "%d: got %08x\n", i, dib_bits[i] );
4966 else
4967 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4968 memset( dib_bits, 0xaa, 64 * 4 );
4970 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, -30, -30, 1, 12, data, info, DIB_RGB_COLORS );
4971 ok( ret == 0, "got %d\n", ret );
4972 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4973 memset( dib_bits, 0xaa, 64 * 4 );
4975 ret = SetDIBitsToDevice( hdc, 5, -5, 8, 16, -2, -4, 4, 12, data, info, DIB_RGB_COLORS );
4976 ok( ret == 8, "got %d\n", ret );
4977 for (i = 0; i < 64; i++)
4978 if (i == 7 || i == 15 || i == 23)
4979 ok( dib_bits[i] == inverted_data[i + 97], "%d: got %08x\n", i, dib_bits[i] );
4980 else
4981 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4982 memset( dib_bits, 0xaa, 64 * 4 );
4984 info->bmiHeader.biHeight = 5;
4985 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4986 ok( ret == 2, "got %d\n", ret );
4987 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4988 for (i = 40; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4989 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4990 memset( dib_bits, 0xaa, 64 * 4 );
4992 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4993 ok( ret == 5, "got %d\n", ret );
4994 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4995 memset( dib_bits, 0xaa, 64 * 4 );
4997 /* handling of partial color table */
4999 info->bmiHeader.biHeight = -8;
5000 info->bmiHeader.biBitCount = 8;
5001 info->bmiHeader.biClrUsed = 137;
5002 for (i = 0; i < 256; i++)
5004 info->bmiColors[i].rgbRed = 255 - i;
5005 info->bmiColors[i].rgbGreen = i * 2;
5006 info->bmiColors[i].rgbBlue = i;
5007 info->bmiColors[i].rgbReserved = 0;
5009 for (i = 0; i < 64; i++) ((BYTE *)data)[i] = i * 4 + 1;
5010 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5011 ok( ret == 8, "got %d\n", ret );
5012 for (i = 0; i < 64; i++)
5014 int idx = i * 4 + 1;
5015 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : (info->bmiColors[idx].rgbRed << 16 |
5016 info->bmiColors[idx].rgbGreen << 8 |
5017 info->bmiColors[idx].rgbBlue);
5018 ok( dib_bits[i] == expect, "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
5020 memset( dib_bits, 0xaa, 64 * 4 );
5022 /* handling of DIB_PAL_COLORS */
5024 pal->palVersion = 0x300;
5025 pal->palNumEntries = 137;
5026 info->bmiHeader.biClrUsed = 221;
5027 for (i = 0; i < 256; i++)
5029 palent[i].peRed = i * 2;
5030 palent[i].peGreen = 255 - i;
5031 palent[i].peBlue = i;
5033 palette = CreatePalette( pal );
5034 ok( palette != 0, "palette creation failed\n" );
5035 SelectPalette( hdc, palette, FALSE );
5036 for (i = 0; i < 256; i++) ((WORD *)info->bmiColors)[i] = 255 - i;
5037 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_PAL_COLORS );
5038 ok( ret == 8, "got %d\n", ret );
5039 for (i = 0; i < 64; i++)
5041 int idx = i * 4 + 1;
5042 int ent = (255 - idx) % pal->palNumEntries;
5043 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 :
5044 (palent[ent].peRed << 16 | palent[ent].peGreen << 8 | palent[ent].peBlue);
5045 ok( dib_bits[i] == expect || broken(dib_bits[i] == 0),
5046 "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
5048 memset( dib_bits, 0xaa, 64 * 4 );
5050 DeleteDC( hdc );
5051 DeleteObject( dib );
5052 DeleteObject( palette );
5053 HeapFree( GetProcessHeap(), 0, info );
5056 static void test_SetDIBitsToDevice_RLE8(void)
5058 BITMAPINFO *info;
5059 DWORD *dib_bits;
5060 HDC hdc = CreateCompatibleDC( 0 );
5061 BYTE rle8_data[20] = { 0x04, 0x02, 0x03, 0xf0, 0x00, 0x00, /* 2, 2, 2, 2, f0, f0, f0, <eol> */
5062 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
5063 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
5064 0x00, 0x01 }; /* <eod> */
5065 HBITMAP dib;
5066 int i, ret;
5067 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
5068 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5069 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5070 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
5071 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5072 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5073 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5074 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
5075 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5076 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5077 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5078 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5079 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
5080 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5081 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5082 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
5084 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
5086 info->bmiHeader.biSize = sizeof(info->bmiHeader);
5087 info->bmiHeader.biWidth = 8;
5088 info->bmiHeader.biHeight = 8;
5089 info->bmiHeader.biPlanes = 1;
5090 info->bmiHeader.biBitCount = 32;
5091 info->bmiHeader.biCompression = BI_RGB;
5093 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5094 memset( dib_bits, 0xaa, 64 * 4 );
5095 SelectObject( hdc, dib );
5097 info->bmiHeader.biBitCount = 8;
5098 info->bmiHeader.biCompression = BI_RLE8;
5099 info->bmiHeader.biSizeImage = sizeof(rle8_data);
5101 for (i = 0; i < 256; i++)
5103 info->bmiColors[i].rgbRed = i;
5104 info->bmiColors[i].rgbGreen = i;
5105 info->bmiColors[i].rgbBlue = i;
5106 info->bmiColors[i].rgbReserved = 0;
5109 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5110 ok( ret == 8, "got %d\n", ret );
5111 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5112 memset( dib_bits, 0xaa, 64 * 4 );
5114 /* startscan and lines are ignored, unless lines == 0 */
5115 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 8, rle8_data, info, DIB_RGB_COLORS );
5116 ok( ret == 8, "got %d\n", ret );
5117 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5118 memset( dib_bits, 0xaa, 64 * 4 );
5120 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 1, rle8_data, info, DIB_RGB_COLORS );
5121 ok( ret == 8, "got %d\n", ret );
5122 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5123 memset( dib_bits, 0xaa, 64 * 4 );
5125 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 0, rle8_data, info, DIB_RGB_COLORS );
5126 ok( ret == 0, "got %d\n", ret );
5127 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5128 memset( dib_bits, 0xaa, 64 * 4 );
5130 info->bmiHeader.biWidth = 2;
5131 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5132 ok( ret == 8, "got %d\n", ret );
5133 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5134 memset( dib_bits, 0xaa, 64 * 4 );
5136 info->bmiHeader.biWidth = 8;
5137 info->bmiHeader.biHeight = 2;
5138 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5139 ok( ret == 2, "got %d\n", ret );
5140 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5141 memset( dib_bits, 0xaa, 64 * 4 );
5143 info->bmiHeader.biHeight = 9;
5144 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5145 ok( ret == 9, "got %d\n", ret );
5146 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5147 memset( dib_bits, 0xaa, 64 * 4 );
5149 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5150 ok( ret == 9, "got %d\n", ret );
5151 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5152 memset( dib_bits, 0xaa, 64 * 4 );
5154 info->bmiHeader.biHeight = 8;
5155 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 9, rle8_data, info, DIB_RGB_COLORS );
5156 ok( ret == 8, "got %d\n", ret );
5157 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5158 memset( dib_bits, 0xaa, 64 * 4 );
5160 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5161 ok( ret == 8, "got %d\n", ret );
5162 for (i = 0; i < 40; i++) ok( dib_bits[i] == bottom_up[i + 24], "%d: got %08x\n", i, dib_bits[i] );
5163 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5164 memset( dib_bits, 0xaa, 64 * 4 );
5166 ret = SetDIBitsToDevice( hdc, 0, 3, 4, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5167 ok( ret == 8, "got %d\n", ret );
5168 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5169 for (i = 8; i < 40; i++)
5170 if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5171 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5172 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5173 memset( dib_bits, 0xaa, 64 * 4 );
5175 ret = SetDIBitsToDevice( hdc, 3, 3, 8, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5176 ok( ret == 8, "got %d\n", ret );
5177 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5178 for (i = 8; i < 40; i++)
5179 if ((i & 7) < 3) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5180 else ok( dib_bits[i] == bottom_up[i - 11], "%d: got %08x\n", i, dib_bits[i] );
5181 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5182 memset( dib_bits, 0xaa, 64 * 4 );
5184 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 4, 2, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5185 ok( ret == 8, "got %d\n", ret );
5186 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5187 for (i = 8; i < 40; i++)
5188 if ((i & 7) < 2) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5189 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5190 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5191 memset( dib_bits, 0xaa, 64 * 4 );
5193 info->bmiHeader.biWidth = 37;
5194 info->bmiHeader.biHeight = 37;
5195 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
5196 ok( ret == 37, "got %d\n", ret );
5197 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5198 for (i = 24; i < 64; i++)
5199 if (i == 52) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
5200 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5201 else ok( dib_bits[i] == bottom_up[i - 20], "%d: got %08x\n", i, dib_bits[i] );
5202 memset( dib_bits, 0xaa, 64 * 4 );
5204 /* top-down compressed dibs are invalid */
5205 info->bmiHeader.biWidth = 8;
5206 info->bmiHeader.biHeight = -8;
5207 SetLastError( 0xdeadbeef );
5208 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5209 ok( ret == 0, "got %d\n", ret );
5210 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
5212 /* top-down dst */
5214 info->bmiHeader.biHeight = -8;
5215 info->bmiHeader.biBitCount = 32;
5216 info->bmiHeader.biCompression = BI_RGB;
5217 info->bmiHeader.biSizeImage = 0;
5219 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5220 memset( dib_bits, 0xaa, 16 * 16 * 4 );
5221 DeleteObject( SelectObject( hdc, dib ));
5223 info->bmiHeader.biHeight = 8;
5224 info->bmiHeader.biBitCount = 8;
5225 info->bmiHeader.biCompression = BI_RLE8;
5226 info->bmiHeader.biSizeImage = sizeof(rle8_data);
5228 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5229 ok( ret == 8, "got %d\n", ret );
5230 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5231 memset( dib_bits, 0xaa, 64 * 4 );
5233 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5234 ok( ret == 8, "got %d\n", ret );
5235 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5236 memset( dib_bits, 0xaa, 64 * 4 );
5238 info->bmiHeader.biHeight = 4;
5239 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5240 ok( ret == 4, "got %d\n", ret );
5241 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5242 memset( dib_bits, 0xaa, 64 * 4 );
5244 info->bmiHeader.biHeight = 9;
5245 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5246 ok( ret == 9, "got %d\n", ret );
5247 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5248 memset( dib_bits, 0xaa, 64 * 4 );
5250 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5251 ok( ret == 9, "got %d\n", ret );
5252 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5253 memset( dib_bits, 0xaa, 64 * 4 );
5255 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 6, 2, 2, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5256 ok( ret == 9, "got %d\n", ret );
5257 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5258 for (i = 24; i < 64; i++) ok( dib_bits[i] == top_down[i - 24], "%d: got %08x\n", i, dib_bits[i] );
5259 memset( dib_bits, 0xaa, 64 * 4 );
5261 info->bmiHeader.biWidth = 37;
5262 info->bmiHeader.biHeight = 37;
5263 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
5264 ok( ret == 37, "got %d\n", ret );
5265 for (i = 0; i < 40; i++)
5266 if (i == 12) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
5267 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5268 else ok( dib_bits[i] == top_down[i + 28], "%d: got %08x\n", i, dib_bits[i] );
5269 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5270 memset( dib_bits, 0xaa, 64 * 4 );
5272 DeleteDC( hdc );
5273 DeleteObject( dib );
5274 HeapFree( GetProcessHeap(), 0, info );
5277 START_TEST(bitmap)
5279 HMODULE hdll;
5281 hdll = GetModuleHandle("gdi32.dll");
5282 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
5283 pGdiGradientFill = (void*)GetProcAddress(hdll, "GdiGradientFill");
5284 pSetLayout = (void*)GetProcAddress(hdll, "SetLayout");
5286 test_createdibitmap();
5287 test_dibsections();
5288 test_dib_formats();
5289 test_mono_dibsection();
5290 test_bitmap();
5291 test_bmBits();
5292 test_GetDIBits_selected_DIB(1);
5293 test_GetDIBits_selected_DIB(4);
5294 test_GetDIBits_selected_DIB(8);
5295 test_GetDIBits_selected_DDB(TRUE);
5296 test_GetDIBits_selected_DDB(FALSE);
5297 test_GetDIBits();
5298 test_GetDIBits_BI_BITFIELDS();
5299 test_select_object();
5300 test_CreateBitmap();
5301 test_BitBlt();
5302 test_StretchBlt();
5303 test_StretchDIBits();
5304 test_GdiAlphaBlend();
5305 test_GdiGradientFill();
5306 test_32bit_ddb();
5307 test_bitmapinfoheadersize();
5308 test_get16dibits();
5309 test_clipping();
5310 test_GetDIBits_top_down(16);
5311 test_GetDIBits_top_down(24);
5312 test_GetDIBits_top_down(32);
5313 test_GetSetDIBits_rtl();
5314 test_GetDIBits_scanlines();
5315 test_SetDIBits();
5316 test_SetDIBits_RLE4();
5317 test_SetDIBits_RLE8();
5318 test_SetDIBitsToDevice();
5319 test_SetDIBitsToDevice_RLE8();