winex11: Create contexts at initialization time to avoid the need for locks.
[wine/multimedia.git] / dlls / gdi32 / tests / bitmap.c
bloba62036184a96bbeb613b90af3efb5f5b246c8a65
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 static void _test_color( int line, HDC hdc, COLORREF color, COLORREF exp )
344 COLORREF c;
345 c = SetPixel(hdc, 0, 0, color);
346 ok_(__FILE__, line)(c == exp, "SetPixel failed: got 0x%06x expected 0x%06x\n", c, exp);
347 c = GetPixel(hdc, 0, 0);
348 ok_(__FILE__, line)(c == exp, "GetPixel failed: got 0x%06x expected 0x%06x\n", c, exp);
349 c = GetNearestColor(hdc, color);
350 ok_(__FILE__, line)(c == exp, "GetNearestColor failed: got 0x%06x expected 0x%06x\n", c, exp);
352 #define test_color(hdc, color, exp) _test_color( __LINE__, hdc, color, exp )
355 static void test_dib_bits_access( HBITMAP hdib, void *bits )
357 MEMORY_BASIC_INFORMATION info;
358 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
359 DWORD data[256];
360 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
361 HDC hdc;
362 char filename[MAX_PATH];
363 HANDLE file;
364 DWORD written;
365 INT ret;
367 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
368 "VirtualQuery failed\n");
369 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
370 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
371 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
372 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
373 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
374 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
376 memset( pbmi, 0, sizeof(bmibuf) );
377 memset( data, 0xcc, sizeof(data) );
378 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
379 pbmi->bmiHeader.biHeight = 16;
380 pbmi->bmiHeader.biWidth = 16;
381 pbmi->bmiHeader.biBitCount = 32;
382 pbmi->bmiHeader.biPlanes = 1;
383 pbmi->bmiHeader.biCompression = BI_RGB;
385 hdc = GetDC(0);
387 ret = SetDIBits( hdc, hdib, 0, 16, data, pbmi, DIB_RGB_COLORS );
388 ok(ret == 16, "SetDIBits failed: expected 16 got %d\n", ret);
390 ReleaseDC(0, hdc);
392 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
393 "VirtualQuery failed\n");
394 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
395 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
396 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
397 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
398 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
399 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
401 /* try writing protected bits to a file */
403 GetTempFileNameA( ".", "dib", 0, filename );
404 file = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
405 CREATE_ALWAYS, 0, 0 );
406 ok( file != INVALID_HANDLE_VALUE, "failed to open %s error %u\n", filename, GetLastError() );
407 ret = WriteFile( file, bits, 8192, &written, NULL );
408 ok( ret, "WriteFile failed error %u\n", GetLastError() );
409 if (ret) ok( written == 8192, "only wrote %u bytes\n", written );
410 CloseHandle( file );
411 DeleteFileA( filename );
414 static void test_dibsections(void)
416 HDC hdc, hdcmem, hdcmem2;
417 HBITMAP hdib, oldbm, hdib2, oldbm2;
418 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
419 char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
420 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
421 BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
422 RGBQUAD *colors = pbmi->bmiColors;
423 RGBTRIPLE *ccolors = pbci->bmciColors;
424 HBITMAP hcoredib;
425 char coreBits[256];
426 BYTE *bits;
427 RGBQUAD rgb[256];
428 int ret;
429 char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
430 LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
431 PALETTEENTRY *palent = plogpal->palPalEntry;
432 WORD *index;
433 DWORD *bits32;
434 HPALETTE hpal, oldpal;
435 DIBSECTION dibsec;
436 COLORREF c0, c1;
437 int i;
438 MEMORY_BASIC_INFORMATION info;
440 hdc = GetDC(0);
442 memset(pbmi, 0, sizeof(bmibuf));
443 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
444 pbmi->bmiHeader.biHeight = 100;
445 pbmi->bmiHeader.biWidth = 512;
446 pbmi->bmiHeader.biBitCount = 24;
447 pbmi->bmiHeader.biPlanes = 1;
448 pbmi->bmiHeader.biCompression = BI_RGB;
450 SetLastError(0xdeadbeef);
452 /* invalid pointer for BITMAPINFO
453 (*bits should be NULL on error) */
454 bits = (BYTE*)0xdeadbeef;
455 hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
456 ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n");
458 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
459 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
460 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
461 ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
463 /* test the DIB memory */
464 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
465 "VirtualQuery failed\n");
466 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
467 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
468 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
469 ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
470 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
471 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
472 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
474 test_dib_bits_access( hdib, bits );
476 test_dib_info(hdib, bits, &pbmi->bmiHeader);
477 DeleteObject(hdib);
479 /* Test a top-down DIB. */
480 pbmi->bmiHeader.biHeight = -100;
481 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
482 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
483 test_dib_info(hdib, bits, &pbmi->bmiHeader);
484 DeleteObject(hdib);
486 pbmi->bmiHeader.biHeight = 100;
487 pbmi->bmiHeader.biBitCount = 8;
488 pbmi->bmiHeader.biCompression = BI_RLE8;
489 SetLastError(0xdeadbeef);
490 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
491 ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
492 ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
494 pbmi->bmiHeader.biBitCount = 16;
495 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
496 ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
497 ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
498 ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
499 SetLastError(0xdeadbeef);
500 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
501 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
503 /* test the DIB memory */
504 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
505 "VirtualQuery failed\n");
506 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
507 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
508 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
509 ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
510 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
511 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
512 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
514 test_dib_info(hdib, bits, &pbmi->bmiHeader);
515 DeleteObject(hdib);
517 memset(pbmi, 0, sizeof(bmibuf));
518 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
519 pbmi->bmiHeader.biHeight = 16;
520 pbmi->bmiHeader.biWidth = 16;
521 pbmi->bmiHeader.biBitCount = 1;
522 pbmi->bmiHeader.biPlanes = 1;
523 pbmi->bmiHeader.biCompression = BI_RGB;
524 colors[0].rgbRed = 0xff;
525 colors[0].rgbGreen = 0;
526 colors[0].rgbBlue = 0;
527 colors[1].rgbRed = 0;
528 colors[1].rgbGreen = 0;
529 colors[1].rgbBlue = 0xff;
531 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
532 ok(hdib != NULL, "CreateDIBSection failed\n");
533 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
534 ok(dibsec.dsBmih.biClrUsed == 2,
535 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
537 /* Test if the old BITMAPCOREINFO structure is supported */
539 pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
540 pbci->bmciHeader.bcBitCount = 0;
542 ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
543 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
544 ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
545 && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
546 "GetDIBits didn't fill in the BITMAPCOREHEADER structure properly\n");
548 ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
549 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
550 ok((ccolors[0].rgbtRed == 0xff) && (ccolors[0].rgbtGreen == 0) &&
551 (ccolors[0].rgbtBlue == 0) && (ccolors[1].rgbtRed == 0) &&
552 (ccolors[1].rgbtGreen == 0) && (ccolors[1].rgbtBlue == 0xff),
553 "The color table has not been translated to the old BITMAPCOREINFO format\n");
555 hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
556 ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
558 ZeroMemory(ccolors, 256 * sizeof(RGBTRIPLE));
559 ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
560 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
561 ok((ccolors[0].rgbtRed == 0xff) && (ccolors[0].rgbtGreen == 0) &&
562 (ccolors[0].rgbtBlue == 0) && (ccolors[1].rgbtRed == 0) &&
563 (ccolors[1].rgbtGreen == 0) && (ccolors[1].rgbtBlue == 0xff),
564 "The color table has not been translated to the old BITMAPCOREINFO format\n");
566 DeleteObject(hcoredib);
568 hdcmem = CreateCompatibleDC(hdc);
569 oldbm = SelectObject(hdcmem, hdib);
571 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
572 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
573 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
574 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
575 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
576 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
578 c0 = RGB(colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue);
579 c1 = RGB(colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue);
581 test_color(hdcmem, DIBINDEX(0), c0);
582 test_color(hdcmem, DIBINDEX(1), c1);
583 test_color(hdcmem, DIBINDEX(2), c0);
584 test_color(hdcmem, PALETTEINDEX(0), c0);
585 test_color(hdcmem, PALETTEINDEX(1), c0);
586 test_color(hdcmem, PALETTEINDEX(2), c0);
587 test_color(hdcmem, PALETTERGB(colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue), c0);
588 test_color(hdcmem, PALETTERGB(colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue), c1);
589 test_color(hdcmem, PALETTERGB(0, 0, 0), c0);
590 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0);
591 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1);
593 SelectObject(hdcmem, oldbm);
594 DeleteObject(hdib);
596 colors[0].rgbRed = 0xff;
597 colors[0].rgbGreen = 0xff;
598 colors[0].rgbBlue = 0xff;
599 colors[1].rgbRed = 0;
600 colors[1].rgbGreen = 0;
601 colors[1].rgbBlue = 0;
603 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
604 ok(hdib != NULL, "CreateDIBSection failed\n");
606 test_dib_info(hdib, bits, &pbmi->bmiHeader);
608 oldbm = SelectObject(hdcmem, hdib);
610 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
611 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
612 ok(!memcmp(rgb, colors, 2 * sizeof(RGBQUAD)),
613 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
614 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
615 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
617 SelectObject(hdcmem, oldbm);
618 test_dib_info(hdib, bits, &pbmi->bmiHeader);
619 DeleteObject(hdib);
621 pbmi->bmiHeader.biBitCount = 4;
622 for (i = 0; i < 16; i++) {
623 colors[i].rgbRed = i;
624 colors[i].rgbGreen = 16-i;
625 colors[i].rgbBlue = 0;
627 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
628 ok(hdib != NULL, "CreateDIBSection failed\n");
629 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
630 ok(dibsec.dsBmih.biClrUsed == 16,
631 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
632 test_dib_info(hdib, bits, &pbmi->bmiHeader);
633 DeleteObject(hdib);
635 pbmi->bmiHeader.biBitCount = 8;
637 for (i = 0; i < 128; i++) {
638 colors[i].rgbRed = 255 - i * 2;
639 colors[i].rgbGreen = i * 2;
640 colors[i].rgbBlue = 0;
641 colors[255 - i].rgbRed = 0;
642 colors[255 - i].rgbGreen = i * 2;
643 colors[255 - i].rgbBlue = 255 - i * 2;
645 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
646 ok(hdib != NULL, "CreateDIBSection failed\n");
647 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
648 ok(dibsec.dsBmih.biClrUsed == 256,
649 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
651 oldbm = SelectObject(hdcmem, hdib);
653 for (i = 0; i < 256; i++) {
654 test_color(hdcmem, DIBINDEX(i), RGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue));
655 test_color(hdcmem, PALETTERGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue),
656 RGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue));
659 SelectObject(hdcmem, oldbm);
660 test_dib_info(hdib, bits, &pbmi->bmiHeader);
661 DeleteObject(hdib);
663 pbmi->bmiHeader.biBitCount = 1;
665 /* Now create a palette and a palette indexed dib section */
666 memset(plogpal, 0, sizeof(logpalbuf));
667 plogpal->palVersion = 0x300;
668 plogpal->palNumEntries = 2;
669 palent[0].peRed = 0xff;
670 palent[0].peBlue = 0xff;
671 palent[1].peGreen = 0xff;
673 index = (WORD*)pbmi->bmiColors;
674 *index++ = 0;
675 *index = 1;
676 hpal = CreatePalette(plogpal);
677 ok(hpal != NULL, "CreatePalette failed\n");
678 oldpal = SelectPalette(hdc, hpal, TRUE);
679 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
680 ok(hdib != NULL, "CreateDIBSection failed\n");
681 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
682 ok(dibsec.dsBmih.biClrUsed == 2, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
684 /* The colour table has already been grabbed from the dc, so we select back the
685 old palette */
687 SelectPalette(hdc, oldpal, TRUE);
688 oldbm = SelectObject(hdcmem, hdib);
689 oldpal = SelectPalette(hdcmem, hpal, TRUE);
691 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
692 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
693 ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
694 rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
695 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
696 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
697 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
699 c0 = RGB(palent[0].peRed, palent[0].peGreen, palent[0].peBlue);
700 c1 = RGB(palent[1].peRed, palent[1].peGreen, palent[1].peBlue);
702 test_color(hdcmem, DIBINDEX(0), c0);
703 test_color(hdcmem, DIBINDEX(1), c1);
704 test_color(hdcmem, DIBINDEX(2), c0);
705 test_color(hdcmem, PALETTEINDEX(0), c0);
706 test_color(hdcmem, PALETTEINDEX(1), c1);
707 test_color(hdcmem, PALETTEINDEX(2), c0);
708 test_color(hdcmem, PALETTERGB(palent[0].peRed, palent[0].peGreen, palent[0].peBlue), c0);
709 test_color(hdcmem, PALETTERGB(palent[1].peRed, palent[1].peGreen, palent[1].peBlue), c1);
710 test_color(hdcmem, PALETTERGB(0, 0, 0), c1);
711 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0);
712 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0);
713 test_color(hdcmem, PALETTERGB(0, 1, 0), c1);
714 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1);
715 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0);
717 /* Bottom and 2nd row from top green, everything else magenta */
718 bits[0] = bits[1] = 0xff;
719 bits[13 * 4] = bits[13*4 + 1] = 0xff;
721 test_dib_info(hdib, bits, &pbmi->bmiHeader);
723 pbmi->bmiHeader.biBitCount = 32;
725 hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
726 ok(hdib2 != NULL, "CreateDIBSection failed\n");
727 hdcmem2 = CreateCompatibleDC(hdc);
728 oldbm2 = SelectObject(hdcmem2, hdib2);
730 BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
732 ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
733 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
735 SelectObject(hdcmem2, oldbm2);
736 test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
737 DeleteObject(hdib2);
739 SelectObject(hdcmem, oldbm);
740 SelectPalette(hdcmem, oldpal, TRUE);
741 DeleteObject(hdib);
742 DeleteObject(hpal);
745 pbmi->bmiHeader.biBitCount = 8;
747 memset(plogpal, 0, sizeof(logpalbuf));
748 plogpal->palVersion = 0x300;
749 plogpal->palNumEntries = 256;
751 for (i = 0; i < 128; i++) {
752 palent[i].peRed = 255 - i * 2;
753 palent[i].peBlue = i * 2;
754 palent[i].peGreen = 0;
755 palent[255 - i].peRed = 0;
756 palent[255 - i].peGreen = i * 2;
757 palent[255 - i].peBlue = 255 - i * 2;
760 index = (WORD*)pbmi->bmiColors;
761 for (i = 0; i < 256; i++) {
762 *index++ = i;
765 hpal = CreatePalette(plogpal);
766 ok(hpal != NULL, "CreatePalette failed\n");
767 oldpal = SelectPalette(hdc, hpal, TRUE);
768 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
769 ok(hdib != NULL, "CreateDIBSection failed\n");
770 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
771 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
773 test_dib_info(hdib, bits, &pbmi->bmiHeader);
775 SelectPalette(hdc, oldpal, TRUE);
776 oldbm = SelectObject(hdcmem, hdib);
777 oldpal = SelectPalette(hdcmem, hpal, TRUE);
779 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
780 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
781 for (i = 0; i < 256; i++) {
782 ok(rgb[i].rgbRed == palent[i].peRed &&
783 rgb[i].rgbBlue == palent[i].peBlue &&
784 rgb[i].rgbGreen == palent[i].peGreen,
785 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
786 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
789 for (i = 0; i < 256; i++) {
790 test_color(hdcmem, DIBINDEX(i), RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
791 test_color(hdcmem, PALETTEINDEX(i), RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
792 test_color(hdcmem, PALETTERGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue),
793 RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
796 SelectPalette(hdcmem, oldpal, TRUE);
797 SelectObject(hdcmem, oldbm);
798 DeleteObject(hdib);
799 DeleteObject(hpal);
801 plogpal->palNumEntries = 37;
802 hpal = CreatePalette(plogpal);
803 ok(hpal != NULL, "CreatePalette failed\n");
804 oldpal = SelectPalette(hdc, hpal, TRUE);
805 pbmi->bmiHeader.biClrUsed = 142;
806 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
807 ok(hdib != NULL, "CreateDIBSection failed\n");
808 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
809 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
811 test_dib_info(hdib, bits, &pbmi->bmiHeader);
813 SelectPalette(hdc, oldpal, TRUE);
814 oldbm = SelectObject(hdcmem, hdib);
816 memset( rgb, 0xcc, sizeof(rgb) );
817 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
818 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
819 for (i = 0; i < 256; i++)
821 if (i < pbmi->bmiHeader.biClrUsed)
823 ok(rgb[i].rgbRed == palent[i % 37].peRed &&
824 rgb[i].rgbBlue == palent[i % 37].peBlue &&
825 rgb[i].rgbGreen == palent[i % 37].peGreen,
826 "GetDIBColorTable returns table %d: r %02x g %02x b %02x res%02x\n",
827 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
828 test_color(hdcmem, DIBINDEX(i),
829 RGB(palent[i % 37].peRed, palent[i % 37].peGreen, palent[i % 37].peBlue));
831 else
833 ok(rgb[i].rgbRed == 0 && rgb[i].rgbBlue == 0 && rgb[i].rgbGreen == 0,
834 "GetDIBColorTable returns table %d: r %02x g %02x b %02x res%02x\n",
835 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
836 test_color(hdcmem, DIBINDEX(i), 0 );
839 pbmi->bmiHeader.biClrUsed = 173;
840 memset( pbmi->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
841 GetDIBits( hdc, hdib, 0, 1, bits, pbmi, DIB_RGB_COLORS );
842 ok( pbmi->bmiHeader.biClrUsed == 0, "wrong colors %u\n", pbmi->bmiHeader.biClrUsed );
843 for (i = 0; i < 256; i++)
845 if (i < 142)
846 ok(colors[i].rgbRed == palent[i % 37].peRed &&
847 colors[i].rgbBlue == palent[i % 37].peBlue &&
848 colors[i].rgbGreen == palent[i % 37].peGreen,
849 "GetDIBits returns table %d: r %02x g %02x b %02x res%02x\n",
850 i, colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
851 else
852 ok(colors[i].rgbRed == 0 && colors[i].rgbBlue == 0 && colors[i].rgbGreen == 0,
853 "GetDIBits returns table %d: r %02x g %02x b %02x res%02x\n",
854 i, colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
857 SelectObject(hdcmem, oldbm);
858 DeleteObject(hdib);
859 DeleteObject(hpal);
861 /* ClrUsed ignored on > 8bpp */
862 pbmi->bmiHeader.biBitCount = 16;
863 pbmi->bmiHeader.biClrUsed = 37;
864 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
865 ok(hdib != NULL, "CreateDIBSection failed\n");
866 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
867 ok(dibsec.dsBmih.biClrUsed == 0, "created DIBSection: wrong biClrUsed field: %u\n", dibsec.dsBmih.biClrUsed);
868 oldbm = SelectObject(hdcmem, hdib);
869 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
870 ok(ret == 0, "GetDIBColorTable returned %d\n", ret);
871 SelectObject(hdcmem, oldbm);
872 DeleteObject(hdib);
874 DeleteDC(hdcmem);
875 DeleteDC(hdcmem2);
876 ReleaseDC(0, hdc);
879 static void test_dib_formats(void)
881 BITMAPINFO *bi;
882 char data[256];
883 void *bits;
884 int planes, bpp, compr, format;
885 HBITMAP hdib, hbmp;
886 HDC hdc, memdc;
887 UINT ret;
888 BOOL format_ok, expect_ok;
890 bi = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
891 hdc = GetDC( 0 );
892 memdc = CreateCompatibleDC( 0 );
893 hbmp = CreateCompatibleBitmap( hdc, 10, 10 );
895 memset( data, 0xaa, sizeof(data) );
897 for (bpp = 0; bpp <= 64; bpp++)
899 for (planes = 0; planes <= 64; planes++)
901 for (compr = 0; compr < 8; compr++)
903 for (format = DIB_RGB_COLORS; format <= DIB_PAL_COLORS; format++)
905 switch (bpp)
907 case 1:
908 case 4:
909 case 8:
910 case 24: expect_ok = (compr == BI_RGB); break;
911 case 16:
912 case 32: expect_ok = (compr == BI_RGB || compr == BI_BITFIELDS); break;
913 default: expect_ok = FALSE; break;
916 memset( bi, 0, sizeof(bi->bmiHeader) );
917 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
918 bi->bmiHeader.biWidth = 2;
919 bi->bmiHeader.biHeight = 2;
920 bi->bmiHeader.biPlanes = planes;
921 bi->bmiHeader.biBitCount = bpp;
922 bi->bmiHeader.biCompression = compr;
923 bi->bmiHeader.biSizeImage = 0;
924 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
925 ret = GetDIBits(hdc, hbmp, 0, 0, data, bi, format);
926 if (expect_ok || (!bpp && compr != BI_JPEG && compr != BI_PNG) ||
927 (bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8))
928 ok( ret, "GetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
929 else
930 ok( !ret || broken(!bpp && (compr == BI_JPEG || compr == BI_PNG)), /* nt4 */
931 "GetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
933 /* all functions check planes except GetDIBits with 0 lines */
934 format_ok = expect_ok;
935 if (!planes) expect_ok = FALSE;
936 memset( bi, 0, sizeof(bi->bmiHeader) );
937 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
938 bi->bmiHeader.biWidth = 2;
939 bi->bmiHeader.biHeight = 2;
940 bi->bmiHeader.biPlanes = planes;
941 bi->bmiHeader.biBitCount = bpp;
942 bi->bmiHeader.biCompression = compr;
943 bi->bmiHeader.biSizeImage = 0;
944 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
946 hdib = CreateDIBSection(hdc, bi, format, &bits, NULL, 0);
947 if (expect_ok && (planes == 1 || planes * bpp <= 16) &&
948 (compr != BI_BITFIELDS || format != DIB_PAL_COLORS))
949 ok( hdib != NULL, "CreateDIBSection failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
950 else
951 ok( hdib == NULL, "CreateDIBSection succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
952 if (hdib) DeleteObject( hdib );
954 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, data, bi, format );
955 /* no sanity checks in CreateDIBitmap except compression */
956 if (compr == BI_JPEG || compr == BI_PNG)
957 ok( hdib == NULL || broken(hdib != NULL), /* nt4 */
958 "CreateDIBitmap succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
959 else
960 ok( hdib != NULL, "CreateDIBitmap failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
961 if (hdib) DeleteObject( hdib );
963 /* RLE needs a size */
964 bi->bmiHeader.biSizeImage = 0;
965 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, format);
966 if (expect_ok)
967 ok( ret, "SetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
968 else
969 ok( !ret ||
970 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
971 "SetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
972 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, format );
973 if (expect_ok)
974 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
975 else
976 ok( !ret ||
977 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
978 "SetDIBitsToDevice succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
979 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, format, SRCCOPY );
980 if (expect_ok)
981 ok( ret, "StretchDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
982 else
983 ok( !ret ||
984 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
985 "StretchDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
987 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, format);
988 if (expect_ok)
989 ok( ret, "GetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
990 else
991 ok( !ret, "GetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
992 ok( bi->bmiHeader.biBitCount == bpp, "GetDIBits modified bpp %u/%u\n",
993 bpp, bi->bmiHeader.biBitCount );
995 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
996 bi->bmiHeader.biWidth = 2;
997 bi->bmiHeader.biHeight = 2;
998 bi->bmiHeader.biPlanes = planes;
999 bi->bmiHeader.biBitCount = bpp;
1000 bi->bmiHeader.biCompression = compr;
1001 bi->bmiHeader.biSizeImage = 1;
1002 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
1003 /* RLE allowed with valid biSizeImage */
1004 if ((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)) expect_ok = TRUE;
1006 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, format);
1007 if (expect_ok)
1008 ok( ret, "SetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1009 else
1010 ok( !ret, "SetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1011 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, format );
1012 if (expect_ok)
1013 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1014 else
1015 ok( !ret, "SetDIBitsToDevice succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1016 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, format, SRCCOPY );
1017 if (expect_ok)
1018 ok( ret, "StretchDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1019 else
1020 ok( !ret, "StretchDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1022 bi->bmiHeader.biSizeImage = 0;
1023 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, format);
1024 if (expect_ok || !bpp)
1025 ok( ret, "GetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1026 else
1027 ok( !ret || broken(format_ok && !planes), /* nt4 */
1028 "GetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1034 memset( bi, 0, sizeof(bi->bmiHeader) );
1035 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1036 bi->bmiHeader.biWidth = 2;
1037 bi->bmiHeader.biHeight = 2;
1038 bi->bmiHeader.biPlanes = 1;
1039 bi->bmiHeader.biBitCount = 16;
1040 bi->bmiHeader.biCompression = BI_BITFIELDS;
1041 bi->bmiHeader.biSizeImage = 0;
1042 *(DWORD *)&bi->bmiColors[0] = 0;
1043 *(DWORD *)&bi->bmiColors[1] = 0;
1044 *(DWORD *)&bi->bmiColors[2] = 0;
1046 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1047 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1048 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1049 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1050 /* other functions don't check */
1051 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1052 ok( hdib != NULL, "CreateDIBitmap failed with null bitfields\n" );
1053 DeleteObject( hdib );
1054 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1055 ok( ret, "SetDIBitsToDevice failed with null bitfields\n" );
1056 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1057 ok( ret, "StretchDIBits failed with null bitfields\n" );
1058 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1059 ok( ret, "GetDIBits failed with null bitfields\n" );
1060 bi->bmiHeader.biPlanes = 1;
1061 bi->bmiHeader.biBitCount = 16;
1062 bi->bmiHeader.biCompression = BI_BITFIELDS;
1063 bi->bmiHeader.biSizeImage = 0;
1064 *(DWORD *)&bi->bmiColors[0] = 0;
1065 *(DWORD *)&bi->bmiColors[1] = 0;
1066 *(DWORD *)&bi->bmiColors[2] = 0;
1067 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1068 ok( ret, "GetDIBits failed with null bitfields\n" );
1070 /* all fields must be non-zero */
1071 *(DWORD *)&bi->bmiColors[0] = 3;
1072 *(DWORD *)&bi->bmiColors[1] = 0;
1073 *(DWORD *)&bi->bmiColors[2] = 7;
1074 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1075 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1076 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1077 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1079 /* garbage is ok though */
1080 *(DWORD *)&bi->bmiColors[0] = 0x55;
1081 *(DWORD *)&bi->bmiColors[1] = 0x44;
1082 *(DWORD *)&bi->bmiColors[2] = 0x33;
1083 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1084 ok( hdib != NULL, "CreateDIBSection failed with bad bitfields\n" );
1085 if (hdib) DeleteObject( hdib );
1086 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1087 ok( ret, "SetDIBits failed with bad bitfields\n" );
1089 bi->bmiHeader.biWidth = -2;
1090 bi->bmiHeader.biHeight = 2;
1091 bi->bmiHeader.biBitCount = 32;
1092 bi->bmiHeader.biCompression = BI_RGB;
1093 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1094 ok( hdib == NULL, "CreateDIBSection succeeded with negative width\n" );
1095 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1096 ok( hdib == NULL, "CreateDIBitmap succeeded with negative width\n" );
1097 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1098 ok( !ret, "SetDIBits succeeded with negative width\n" );
1099 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1100 ok( !ret, "SetDIBitsToDevice succeeded with negative width\n" );
1101 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1102 ok( !ret, "StretchDIBits succeeded with negative width\n" );
1103 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1104 ok( !ret, "GetDIBits succeeded with negative width\n" );
1105 bi->bmiHeader.biWidth = -2;
1106 bi->bmiHeader.biHeight = 2;
1107 bi->bmiHeader.biBitCount = 32;
1108 bi->bmiHeader.biCompression = BI_RGB;
1109 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1110 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with negative width\n" );
1112 bi->bmiHeader.biWidth = 0;
1113 bi->bmiHeader.biHeight = 2;
1114 bi->bmiHeader.biBitCount = 32;
1115 bi->bmiHeader.biCompression = BI_RGB;
1116 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1117 ok( hdib == NULL, "CreateDIBSection succeeded with zero width\n" );
1118 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1119 ok( hdib != NULL, "CreateDIBitmap failed with zero width\n" );
1120 DeleteObject( hdib );
1121 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1122 ok( !ret || broken(ret), /* nt4 */ "SetDIBits succeeded with zero width\n" );
1123 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1124 ok( !ret || broken(ret), /* nt4 */ "SetDIBitsToDevice succeeded with zero width\n" );
1125 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1126 ok( !ret || broken(ret), /* nt4 */ "StretchDIBits succeeded with zero width\n" );
1127 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1128 ok( !ret, "GetDIBits succeeded with zero width\n" );
1129 bi->bmiHeader.biWidth = 0;
1130 bi->bmiHeader.biHeight = 2;
1131 bi->bmiHeader.biBitCount = 32;
1132 bi->bmiHeader.biCompression = BI_RGB;
1133 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1134 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero width\n" );
1136 bi->bmiHeader.biWidth = 2;
1137 bi->bmiHeader.biHeight = 0;
1138 bi->bmiHeader.biBitCount = 32;
1139 bi->bmiHeader.biCompression = BI_RGB;
1140 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1141 ok( hdib == NULL, "CreateDIBSection succeeded with zero height\n" );
1142 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1143 ok( hdib != NULL, "CreateDIBitmap failed with zero height\n" );
1144 DeleteObject( hdib );
1145 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1146 ok( !ret, "SetDIBits succeeded with zero height\n" );
1147 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1148 ok( !ret, "SetDIBitsToDevice succeeded with zero height\n" );
1149 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1150 ok( !ret, "StretchDIBits succeeded with zero height\n" );
1151 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1152 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1153 bi->bmiHeader.biWidth = 2;
1154 bi->bmiHeader.biHeight = 0;
1155 bi->bmiHeader.biBitCount = 32;
1156 bi->bmiHeader.biCompression = BI_RGB;
1157 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1158 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1160 /* some functions accept DIB_PAL_COLORS+1, but not beyond */
1162 bi->bmiHeader.biWidth = 2;
1163 bi->bmiHeader.biHeight = 2;
1164 bi->bmiHeader.biBitCount = 1;
1165 bi->bmiHeader.biCompression = BI_RGB;
1166 hdib = CreateDIBSection(hdc, bi, DIB_PAL_COLORS+1, &bits, NULL, 0);
1167 ok( hdib == NULL, "CreateDIBSection succeeded with DIB_PAL_COLORS+1\n" );
1168 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_PAL_COLORS+1 );
1169 ok( hdib != NULL, "CreateDIBitmap failed with DIB_PAL_COLORS+1\n" );
1170 DeleteObject( hdib );
1171 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_PAL_COLORS+1);
1172 ok( !ret, "SetDIBits succeeded with DIB_PAL_COLORS+1\n" );
1173 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_PAL_COLORS+1 );
1174 ok( ret, "SetDIBitsToDevice failed with DIB_PAL_COLORS+1\n" );
1175 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_PAL_COLORS+1, SRCCOPY );
1176 ok( ret, "StretchDIBits failed with DIB_PAL_COLORS+1\n" );
1177 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_PAL_COLORS+1);
1178 ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+1\n" );
1179 bi->bmiHeader.biWidth = 2;
1180 bi->bmiHeader.biHeight = 2;
1181 bi->bmiHeader.biBitCount = 1;
1182 bi->bmiHeader.biCompression = BI_RGB;
1183 ret = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS+1);
1184 ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+1\n" );
1186 bi->bmiHeader.biWidth = 2;
1187 bi->bmiHeader.biHeight = 2;
1188 bi->bmiHeader.biBitCount = 1;
1189 bi->bmiHeader.biCompression = BI_RGB;
1190 hdib = CreateDIBSection(hdc, bi, DIB_PAL_COLORS+2, &bits, NULL, 0);
1191 ok( hdib == NULL, "CreateDIBSection succeeded with DIB_PAL_COLORS+2\n" );
1192 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_PAL_COLORS+2 );
1193 ok( hdib == NULL, "CreateDIBitmap succeeded with DIB_PAL_COLORS+2\n" );
1194 DeleteObject( hdib );
1195 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_PAL_COLORS+2);
1196 ok( !ret, "SetDIBits succeeded with DIB_PAL_COLORS+2\n" );
1197 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_PAL_COLORS+2 );
1198 ok( !ret, "SetDIBitsToDevice succeeded with DIB_PAL_COLORS+2\n" );
1199 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_PAL_COLORS+2, SRCCOPY );
1200 ok( !ret, "StretchDIBits succeeded with DIB_PAL_COLORS+2\n" );
1201 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_PAL_COLORS+2);
1202 ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+2\n" );
1203 bi->bmiHeader.biWidth = 2;
1204 bi->bmiHeader.biHeight = 2;
1205 bi->bmiHeader.biBitCount = 1;
1206 bi->bmiHeader.biCompression = BI_RGB;
1207 ret = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS+2);
1208 ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+2\n" );
1210 DeleteDC( memdc );
1211 DeleteObject( hbmp );
1212 ReleaseDC( 0, hdc );
1213 HeapFree( GetProcessHeap(), 0, bi );
1216 static void test_mono_dibsection(void)
1218 HDC hdc, memdc;
1219 HBITMAP old_bm, mono_ds;
1220 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
1221 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
1222 RGBQUAD *colors = pbmi->bmiColors;
1223 BYTE bits[10 * 4];
1224 BYTE *ds_bits;
1225 int num;
1227 hdc = GetDC(0);
1229 memdc = CreateCompatibleDC(hdc);
1231 memset(pbmi, 0, sizeof(bmibuf));
1232 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
1233 pbmi->bmiHeader.biHeight = 10;
1234 pbmi->bmiHeader.biWidth = 10;
1235 pbmi->bmiHeader.biBitCount = 1;
1236 pbmi->bmiHeader.biPlanes = 1;
1237 pbmi->bmiHeader.biCompression = BI_RGB;
1238 colors[0].rgbRed = 0xff;
1239 colors[0].rgbGreen = 0xff;
1240 colors[0].rgbBlue = 0xff;
1241 colors[1].rgbRed = 0x0;
1242 colors[1].rgbGreen = 0x0;
1243 colors[1].rgbBlue = 0x0;
1246 * First dib section is 'inverted' ie color[0] is white, color[1] is black
1249 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1250 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1251 old_bm = SelectObject(memdc, mono_ds);
1253 /* black border, white interior */
1254 Rectangle(memdc, 0, 0, 10, 10);
1255 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1256 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1258 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1260 memset(bits, 0, sizeof(bits));
1261 bits[0] = 0xaa;
1263 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1264 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1266 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1268 colors[0].rgbRed = 0x0;
1269 colors[0].rgbGreen = 0x0;
1270 colors[0].rgbBlue = 0x0;
1271 colors[1].rgbRed = 0xff;
1272 colors[1].rgbGreen = 0xff;
1273 colors[1].rgbBlue = 0xff;
1275 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1276 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1278 SelectObject(memdc, old_bm);
1279 DeleteObject(mono_ds);
1282 * Next dib section is 'normal' ie color[0] is black, color[1] is white
1285 colors[0].rgbRed = 0x0;
1286 colors[0].rgbGreen = 0x0;
1287 colors[0].rgbBlue = 0x0;
1288 colors[1].rgbRed = 0xff;
1289 colors[1].rgbGreen = 0xff;
1290 colors[1].rgbBlue = 0xff;
1292 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1293 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1294 old_bm = SelectObject(memdc, mono_ds);
1296 /* black border, white interior */
1297 Rectangle(memdc, 0, 0, 10, 10);
1298 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
1299 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
1301 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
1303 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1304 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1306 /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
1308 colors[0].rgbRed = 0xff;
1309 colors[0].rgbGreen = 0xff;
1310 colors[0].rgbBlue = 0xff;
1311 colors[1].rgbRed = 0x0;
1312 colors[1].rgbGreen = 0x0;
1313 colors[1].rgbBlue = 0x0;
1315 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1316 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1319 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
1322 colors[0].rgbRed = 0xff;
1323 colors[0].rgbGreen = 0xff;
1324 colors[0].rgbBlue = 0xff;
1325 colors[1].rgbRed = 0x0;
1326 colors[1].rgbGreen = 0x0;
1327 colors[1].rgbBlue = 0x0;
1328 num = SetDIBColorTable(memdc, 0, 2, colors);
1329 ok(num == 2, "num = %d\n", num);
1331 /* black border, white interior */
1332 Rectangle(memdc, 0, 0, 10, 10);
1333 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1334 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1336 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1338 memset(bits, 0, sizeof(bits));
1339 bits[0] = 0xaa;
1341 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1342 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1344 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1346 colors[0].rgbRed = 0x0;
1347 colors[0].rgbGreen = 0x0;
1348 colors[0].rgbBlue = 0x0;
1349 colors[1].rgbRed = 0xff;
1350 colors[1].rgbGreen = 0xff;
1351 colors[1].rgbBlue = 0xff;
1353 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1354 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1356 SelectObject(memdc, old_bm);
1357 DeleteObject(mono_ds);
1360 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
1363 colors[0].rgbRed = 0xff;
1364 colors[0].rgbGreen = 0x0;
1365 colors[0].rgbBlue = 0x0;
1366 colors[1].rgbRed = 0xfe;
1367 colors[1].rgbGreen = 0x0;
1368 colors[1].rgbBlue = 0x0;
1370 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1371 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1372 old_bm = SelectObject(memdc, mono_ds);
1374 /* black border, white interior */
1375 Rectangle(memdc, 0, 0, 10, 10);
1376 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1377 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1379 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1381 colors[0].rgbRed = 0x0;
1382 colors[0].rgbGreen = 0x0;
1383 colors[0].rgbBlue = 0x0;
1384 colors[1].rgbRed = 0xff;
1385 colors[1].rgbGreen = 0xff;
1386 colors[1].rgbBlue = 0xff;
1388 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1389 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1391 /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
1393 colors[0].rgbRed = 0xff;
1394 colors[0].rgbGreen = 0xff;
1395 colors[0].rgbBlue = 0xff;
1396 colors[1].rgbRed = 0x0;
1397 colors[1].rgbGreen = 0x0;
1398 colors[1].rgbBlue = 0x0;
1400 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1401 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1403 SelectObject(memdc, old_bm);
1404 DeleteObject(mono_ds);
1406 DeleteDC(memdc);
1407 ReleaseDC(0, hdc);
1410 static void test_bitmap(void)
1412 char buf[256], buf_cmp[256];
1413 HBITMAP hbmp, hbmp_old;
1414 HDC hdc;
1415 BITMAP bm;
1416 BITMAP bma[2];
1417 INT ret;
1419 hdc = CreateCompatibleDC(0);
1420 assert(hdc != 0);
1422 SetLastError(0xdeadbeef);
1423 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1424 if (!hbmp)
1426 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1427 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1428 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1430 else
1431 DeleteObject(hbmp);
1433 SetLastError(0xdeadbeef);
1434 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1435 if (!hbmp)
1437 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1438 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1439 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1441 else
1442 DeleteObject(hbmp);
1444 SetLastError(0xdeadbeef);
1445 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1446 ok(!hbmp, "CreateBitmap should fail\n");
1447 if (!hbmp)
1448 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1449 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1450 else
1451 DeleteObject(hbmp);
1453 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1454 assert(hbmp != NULL);
1456 ret = GetObject(hbmp, sizeof(bm), &bm);
1457 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1459 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1460 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1461 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1462 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1463 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1464 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1465 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1467 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1468 assert(sizeof(buf) == sizeof(buf_cmp));
1470 ret = GetBitmapBits(hbmp, 0, NULL);
1471 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1473 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1474 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1476 memset(buf, 0xAA, sizeof(buf));
1477 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1478 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1479 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1481 hbmp_old = SelectObject(hdc, hbmp);
1483 ret = GetObject(hbmp, sizeof(bm), &bm);
1484 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1486 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1487 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1488 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1489 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1490 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1491 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1492 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1494 memset(buf, 0xAA, sizeof(buf));
1495 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1496 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1497 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1499 hbmp_old = SelectObject(hdc, hbmp_old);
1500 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1502 /* test various buffer sizes for GetObject */
1503 ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
1504 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1506 ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1507 ok(ret == 0, "%d != 0\n", ret);
1509 ret = GetObject(hbmp, 0, &bm);
1510 ok(ret == 0, "%d != 0\n", ret);
1512 ret = GetObject(hbmp, 1, &bm);
1513 ok(ret == 0, "%d != 0\n", ret);
1515 DeleteObject(hbmp);
1516 DeleteDC(hdc);
1519 static COLORREF get_nearest( int r, int g, int b )
1521 return (r*r + g*g + b*b < (255-r)*(255-r) + (255-g)*(255-g) + (255-b)*(255-b)) ? 0x000000 : 0xffffff;
1524 static int is_black_pen( COLORREF fg, COLORREF bg, int r, int g, int b )
1526 if (fg == 0 || bg == 0xffffff) return RGB(r,g,b) != 0xffffff && RGB(r,g,b) != bg;
1527 return RGB(r,g,b) == 0x000000 || RGB(r,g,b) == bg;
1530 static void test_bitmap_colors( HDC hdc, COLORREF fg, COLORREF bg, int r, int g, int b )
1532 static const WORD pattern_bits[] = { 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa };
1533 char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1534 BITMAPINFO *info = (BITMAPINFO *)buffer;
1535 RGBQUAD *colors = info->bmiColors;
1536 WORD bits[16];
1537 void *bits_ptr;
1538 COLORREF res;
1539 HBRUSH old_brush;
1540 HPEN old_pen;
1541 HBITMAP bitmap;
1542 HDC memdc;
1544 res = SetPixel( hdc, 0, 0, RGB(r,g,b) );
1545 ok( res == get_nearest( r, g, b ),
1546 "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg );
1547 res = GetPixel( hdc, 0, 0 );
1548 ok( res == get_nearest( r, g, b ),
1549 "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg );
1550 res = GetNearestColor( hdc, RGB(r,g,b) );
1551 ok( res == get_nearest( r, g, b ),
1552 "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg );
1554 /* solid pen */
1555 old_pen = SelectObject( hdc, CreatePen( PS_SOLID, 1, RGB(r,g,b) ));
1556 MoveToEx( hdc, 0, 0, NULL );
1557 LineTo( hdc, 16, 0 );
1558 res = GetPixel( hdc, 0, 0 );
1559 ok( res == (is_black_pen( fg, bg, r, g, b ) ? 0 : 0xffffff),
1560 "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg );
1561 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1562 ok( bits[0] == (is_black_pen( fg, bg, r, g, b ) ? 0x00 : 0xffff),
1563 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1564 DeleteObject( SelectObject( hdc, old_pen ));
1566 /* mono DDB pattern brush */
1567 bitmap = CreateBitmap( 16, 8, 1, 1, pattern_bits );
1568 old_brush = SelectObject( hdc, CreatePatternBrush( bitmap ));
1569 PatBlt( hdc, 0, 0, 16, 16, PATCOPY );
1570 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1571 ok( bits[0] == 0x5555,
1572 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1573 DeleteObject( SelectObject( hdc, old_brush ));
1575 /* mono DDB bitmap */
1576 memdc = CreateCompatibleDC( hdc );
1577 SelectObject( memdc, bitmap );
1578 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1579 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1580 ok( bits[0] == 0x5555,
1581 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1582 SetTextColor( memdc, RGB(255,255,255) );
1583 SetBkColor( memdc, RGB(0,0,0) );
1584 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1585 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1586 ok( bits[0] == 0x5555,
1587 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1589 /* mono DIB section */
1590 memset( buffer, 0, sizeof(buffer) );
1591 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1592 info->bmiHeader.biHeight = -16;
1593 info->bmiHeader.biWidth = 16;
1594 info->bmiHeader.biBitCount = 1;
1595 info->bmiHeader.biPlanes = 1;
1596 info->bmiHeader.biCompression = BI_RGB;
1597 colors[0].rgbRed = 0xff;
1598 colors[0].rgbGreen = 0xff;
1599 colors[0].rgbBlue = 0xf0;
1600 colors[1].rgbRed = 0x20;
1601 colors[1].rgbGreen = 0x0;
1602 colors[1].rgbBlue = 0x0;
1603 bitmap = CreateDIBSection( 0, info, DIB_RGB_COLORS, &bits_ptr, NULL, 0 );
1604 memset( bits_ptr, 0x55, 64 );
1605 DeleteObject( SelectObject( memdc, bitmap ));
1606 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1607 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1608 ok( bits[0] == 0x5555,
1609 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1611 colors[0].rgbRed = 0x0;
1612 colors[0].rgbGreen = 0x0;
1613 colors[0].rgbBlue = 0x10;
1614 colors[1].rgbRed = 0xff;
1615 colors[1].rgbGreen = 0xf0;
1616 colors[1].rgbBlue = 0xff;
1617 bitmap = CreateDIBSection( 0, info, DIB_RGB_COLORS, &bits_ptr, NULL, 0 );
1618 memset( bits_ptr, 0x55, 64 );
1619 DeleteObject( SelectObject( memdc, bitmap ));
1620 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1621 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1622 ok( bits[0] == 0xaaaa,
1623 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1625 SetTextColor( memdc, RGB(0,20,0) );
1626 SetBkColor( memdc, RGB(240,240,240) );
1627 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1628 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1629 ok( bits[0] == 0x5555,
1630 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1632 SetTextColor( memdc, RGB(250,250,250) );
1633 SetBkColor( memdc, RGB(10,10,10) );
1634 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1635 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1636 ok( bits[0] == 0xaaaa,
1637 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1638 DeleteDC( memdc );
1639 DeleteObject( bitmap );
1642 static void test_mono_bitmap(void)
1644 static const COLORREF colors[][2] =
1646 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff) },
1647 { RGB(0xff,0xff,0xff), RGB(0x00,0x00,0x00) },
1648 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xfe) },
1649 { RGB(0x00,0x01,0x00), RGB(0xff,0xff,0xff) },
1650 { RGB(0x00,0x00,0x00), RGB(0x80,0x80,0x80) },
1651 { RGB(0x80,0x80,0x80), RGB(0xff,0xff,0xff) },
1652 { RGB(0x30,0x40,0x50), RGB(0x60,0x70,0x80) },
1653 { RGB(0xa0,0xa0,0xa0), RGB(0x20,0x30,0x10) },
1654 { PALETTEINDEX(0), PALETTEINDEX(255) },
1655 { PALETTEINDEX(1), PALETTEINDEX(2) },
1658 HBITMAP hbmp;
1659 HDC hdc;
1660 DWORD col;
1661 int i, r, g, b;
1663 hdc = CreateCompatibleDC(0);
1664 assert(hdc != 0);
1666 hbmp = CreateBitmap(16, 16, 1, 1, NULL);
1667 assert(hbmp != NULL);
1669 SelectObject( hdc, hbmp );
1671 for (col = 0; col < sizeof(colors) / sizeof(colors[0]); col++)
1673 SetTextColor( hdc, colors[col][0] );
1674 SetBkColor( hdc, colors[col][1] );
1676 for (i = 0; i < 256; i++)
1678 HPALETTE pal = GetCurrentObject( hdc, OBJ_PAL );
1679 PALETTEENTRY ent;
1681 if (!GetPaletteEntries( pal, i, 1, &ent )) GetPaletteEntries( pal, 0, 1, &ent );
1682 test_color( hdc, PALETTEINDEX(i), get_nearest( ent.peRed, ent.peGreen, ent.peBlue ));
1683 test_color( hdc, DIBINDEX(i), (i == 1) ? 0xffffff : 0x000000 );
1686 for (r = 0; r < 256; r += 15)
1687 for (g = 0; g < 256; g += 15)
1688 for (b = 0; b < 256; b += 15)
1689 test_bitmap_colors( hdc, colors[col][0], colors[col][1], r, g, b );
1692 DeleteDC(hdc);
1693 DeleteObject(hbmp);
1696 static void test_bmBits(void)
1698 BYTE bits[4];
1699 HBITMAP hbmp;
1700 BITMAP bmp;
1702 memset(bits, 0, sizeof(bits));
1703 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1704 ok(hbmp != NULL, "CreateBitmap failed\n");
1706 memset(&bmp, 0xFF, sizeof(bmp));
1707 ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1708 "GetObject failed or returned a wrong structure size\n");
1709 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1711 DeleteObject(hbmp);
1714 static void test_GetDIBits_selected_DIB(UINT bpp)
1716 HBITMAP dib;
1717 BITMAPINFO *info;
1718 BITMAPINFO *info2;
1719 void * bits;
1720 void * bits2;
1721 UINT dib_size, dib32_size;
1722 DWORD pixel;
1723 HDC dib_dc, dc;
1724 HBITMAP old_bmp;
1725 UINT i;
1726 int res;
1728 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1729 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1731 /* Create a DIB section with a color table */
1733 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1734 info->bmiHeader.biWidth = 32;
1735 info->bmiHeader.biHeight = 32;
1736 info->bmiHeader.biPlanes = 1;
1737 info->bmiHeader.biBitCount = bpp;
1738 info->bmiHeader.biCompression = BI_RGB;
1739 info->bmiHeader.biXPelsPerMeter = 0;
1740 info->bmiHeader.biYPelsPerMeter = 0;
1741 info->bmiHeader.biClrUsed = 0;
1742 info->bmiHeader.biClrImportant = 0;
1744 for (i=0; i < (1u << bpp); i++)
1746 BYTE c = i * (1 << (8 - bpp));
1747 info->bmiColors[i].rgbRed = c;
1748 info->bmiColors[i].rgbGreen = c;
1749 info->bmiColors[i].rgbBlue = c;
1750 info->bmiColors[i].rgbReserved = 0;
1753 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1754 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1755 dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1757 /* Set the bits of the DIB section */
1758 for (i=0; i < dib_size; i++)
1760 ((BYTE *)bits)[i] = i % 256;
1763 /* Select the DIB into a DC */
1764 dib_dc = CreateCompatibleDC(NULL);
1765 old_bmp = SelectObject(dib_dc, dib);
1766 dc = CreateCompatibleDC(NULL);
1767 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
1769 /* Copy the DIB attributes but not the color table */
1770 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1772 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1773 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1775 /* Compare the color table and the bits */
1776 for (i=0; i < (1u << bpp); i++)
1777 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1778 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1779 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1780 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1781 "color table entry %d differs (bpp %d)\n", i, bpp );
1783 ok( !memcmp( bits, bits2, dib_size ), "bit mismatch (bpp %d)\n", bpp );
1785 /* Test various combinations of lines = 0 and bits2 = NULL */
1786 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1787 res = GetDIBits( dc, dib, 0, 0, bits2, info2, DIB_RGB_COLORS );
1788 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1789 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1790 "color table mismatch (bpp %d)\n", bpp );
1792 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1793 res = GetDIBits( dc, dib, 0, 0, NULL, info2, DIB_RGB_COLORS );
1794 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1795 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1796 "color table mismatch (bpp %d)\n", bpp );
1798 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1799 res = GetDIBits( dc, dib, 0, info->bmiHeader.biHeight, NULL, info2, DIB_RGB_COLORS );
1800 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1801 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1802 "color table mismatch (bpp %d)\n", bpp );
1804 /* Map into a 32bit-DIB */
1805 info2->bmiHeader.biBitCount = 32;
1806 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1807 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1809 /* Check if last pixel was set */
1810 pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
1811 ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
1813 HeapFree(GetProcessHeap(), 0, bits2);
1814 DeleteDC(dc);
1816 SelectObject(dib_dc, old_bmp);
1817 DeleteDC(dib_dc);
1818 DeleteObject(dib);
1819 HeapFree(GetProcessHeap(), 0, info2);
1820 HeapFree(GetProcessHeap(), 0, info);
1823 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1825 HBITMAP ddb;
1826 BITMAPINFO *info;
1827 BITMAPINFO *info2;
1828 void * bits;
1829 void * bits2;
1830 HDC ddb_dc, dc;
1831 HBITMAP old_bmp;
1832 UINT width, height;
1833 UINT bpp;
1834 UINT i, j;
1835 int res;
1837 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1838 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1840 width = height = 16;
1842 /* Create a DDB (device-dependent bitmap) */
1843 if (monochrome)
1845 bpp = 1;
1846 ddb = CreateBitmap(width, height, 1, 1, NULL);
1848 else
1850 HDC screen_dc = GetDC(NULL);
1851 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1852 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1853 ReleaseDC(NULL, screen_dc);
1856 /* Set the pixels */
1857 ddb_dc = CreateCompatibleDC(NULL);
1858 old_bmp = SelectObject(ddb_dc, ddb);
1859 for (i = 0; i < width; i++)
1861 for (j=0; j < height; j++)
1863 BYTE c = (i * width + j) % 256;
1864 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1867 SelectObject(ddb_dc, old_bmp);
1869 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1870 info->bmiHeader.biWidth = width;
1871 info->bmiHeader.biHeight = height;
1872 info->bmiHeader.biPlanes = 1;
1873 info->bmiHeader.biBitCount = bpp;
1874 info->bmiHeader.biCompression = BI_RGB;
1876 dc = CreateCompatibleDC(NULL);
1878 /* Fill in biSizeImage */
1879 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1880 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1882 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1883 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1885 /* Get the bits */
1886 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1887 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1889 /* Copy the DIB attributes but not the color table */
1890 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1892 /* Select the DDB into another DC */
1893 old_bmp = SelectObject(ddb_dc, ddb);
1895 /* Get the bits */
1896 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1897 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1899 /* Compare the color table and the bits */
1900 if (bpp <= 8)
1902 for (i=0; i < (1u << bpp); i++)
1903 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1904 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1905 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1906 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1907 "color table entry %d differs (bpp %d)\n", i, bpp );
1910 ok( !memcmp( bits, bits2, info->bmiHeader.biSizeImage ), "bit mismatch (bpp %d)\n", bpp );
1912 /* Test the palette */
1913 if (info2->bmiHeader.biBitCount <= 8)
1915 WORD *colors = (WORD*)info2->bmiColors;
1917 /* Get the palette indices */
1918 res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1919 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1921 for (i = 0; i < (1 << info->bmiHeader.biBitCount); i++)
1922 ok( colors[i] == i, "%d: got %d (bpp %d)\n", i, colors[i], bpp );
1925 HeapFree(GetProcessHeap(), 0, bits2);
1926 HeapFree(GetProcessHeap(), 0, bits);
1927 DeleteDC(dc);
1929 SelectObject(ddb_dc, old_bmp);
1930 DeleteDC(ddb_dc);
1931 DeleteObject(ddb);
1932 HeapFree(GetProcessHeap(), 0, info2);
1933 HeapFree(GetProcessHeap(), 0, info);
1936 static void test_GetDIBits(void)
1938 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1939 static const BYTE bmp_bits_1[16 * 2] =
1941 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1942 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1943 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1944 0xff,0xff, 0,0, 0xff,0xff, 0,0
1946 /* 4-bytes aligned 1-bit DIB data: 16x16 */
1947 static const BYTE dib_bits_1[16 * 4] =
1949 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1950 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1951 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1952 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1954 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1955 static const BYTE bmp_bits_24[16 * 16*3] =
1957 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1958 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1959 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1960 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1961 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1962 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1963 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1964 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1965 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1966 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1967 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1968 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1969 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1970 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1971 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1972 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1973 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1974 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1975 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1976 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1977 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1978 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1979 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1980 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1981 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1982 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1983 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1984 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1985 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1986 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1987 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1988 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1990 /* 4-bytes aligned 24-bit DIB data: 16x16 */
1991 static const BYTE dib_bits_24[16 * 16*3] =
1993 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1994 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1995 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1996 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1997 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1998 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1999 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2000 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2001 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2002 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2003 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2004 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2005 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2006 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2007 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2008 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2009 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2010 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2011 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2012 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2013 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2014 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2015 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2016 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2017 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2018 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2019 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2020 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2021 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2022 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2023 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2024 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
2026 HBITMAP hbmp;
2027 BITMAP bm;
2028 HDC hdc;
2029 int i, bytes, lines;
2030 BYTE buf[1024];
2031 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
2032 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
2033 RGBQUAD *colors = bi->bmiColors;
2034 PALETTEENTRY pal_ents[20];
2036 hdc = GetDC(0);
2038 /* 1-bit source bitmap data */
2039 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
2040 ok(hbmp != 0, "CreateBitmap failed\n");
2042 memset(&bm, 0xAA, sizeof(bm));
2043 bytes = GetObject(hbmp, sizeof(bm), &bm);
2044 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2045 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2046 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
2047 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
2048 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2049 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
2050 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2051 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2053 bytes = GetBitmapBits(hbmp, 0, NULL);
2054 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
2055 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
2056 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
2057 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
2059 /* retrieve 1-bit DIB data */
2060 memset(bi, 0, sizeof(*bi));
2061 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2062 bi->bmiHeader.biWidth = bm.bmWidth;
2063 bi->bmiHeader.biHeight = bm.bmHeight;
2064 bi->bmiHeader.biPlanes = 1;
2065 bi->bmiHeader.biBitCount = 1;
2066 bi->bmiHeader.biCompression = BI_RGB;
2067 bi->bmiHeader.biClrUsed = 37;
2068 bi->bmiHeader.biSizeImage = 0;
2069 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2070 SetLastError(0xdeadbeef);
2071 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2072 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
2073 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
2074 broken(GetLastError() == 0xdeadbeef), /* winnt */
2075 "wrong error %u\n", GetLastError());
2076 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
2077 ok(bi->bmiHeader.biClrUsed == 37 || broken(bi->bmiHeader.biClrUsed == 0),
2078 "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2080 memset(buf, 0xAA, sizeof(buf));
2081 SetLastError(0xdeadbeef);
2082 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2083 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2084 lines, bm.bmHeight, GetLastError());
2085 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
2086 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2088 /* the color table consists of black and white */
2089 ok(colors[0].rgbRed == 0 && colors[0].rgbGreen == 0 &&
2090 colors[0].rgbBlue == 0 && colors[0].rgbReserved == 0,
2091 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
2092 colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue, colors[0].rgbReserved);
2093 ok(colors[1].rgbRed == 0xff && colors[1].rgbGreen == 0xff &&
2094 colors[1].rgbBlue == 0xff && colors[1].rgbReserved == 0,
2095 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
2096 colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue, colors[1].rgbReserved);
2097 for (i = 2; i < 256; i++)
2099 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2100 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2101 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2102 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2105 /* returned bits are DWORD aligned and upside down */
2106 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
2108 /* Test the palette indices */
2109 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2110 SetLastError(0xdeadbeef);
2111 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
2112 ok(((WORD*)colors)[0] == 0, "Color 0 is %d\n", ((WORD*)colors)[0]);
2113 ok(((WORD*)colors)[1] == 1, "Color 1 is %d\n", ((WORD*)colors)[1]);
2114 for (i = 2; i < 256; i++)
2115 ok(((WORD*)colors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)colors)[1]);
2117 /* retrieve 24-bit DIB data */
2118 memset(bi, 0, sizeof(*bi));
2119 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2120 bi->bmiHeader.biWidth = bm.bmWidth;
2121 bi->bmiHeader.biHeight = bm.bmHeight;
2122 bi->bmiHeader.biPlanes = 1;
2123 bi->bmiHeader.biBitCount = 24;
2124 bi->bmiHeader.biCompression = BI_RGB;
2125 bi->bmiHeader.biClrUsed = 37;
2126 bi->bmiHeader.biSizeImage = 0;
2127 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2128 memset(buf, 0xAA, sizeof(buf));
2129 SetLastError(0xdeadbeef);
2130 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2131 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2132 lines, bm.bmHeight, GetLastError());
2133 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2134 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2136 /* the color table doesn't exist for 24-bit images */
2137 for (i = 0; i < 256; i++)
2139 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2140 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2141 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2142 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2145 /* returned bits are DWORD aligned and upside down */
2146 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2147 DeleteObject(hbmp);
2149 /* 24-bit source bitmap data */
2150 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
2151 ok(hbmp != 0, "CreateBitmap failed\n");
2152 SetLastError(0xdeadbeef);
2153 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
2154 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
2155 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
2156 lines, bm.bmHeight, GetLastError());
2158 memset(&bm, 0xAA, sizeof(bm));
2159 bytes = GetObject(hbmp, sizeof(bm), &bm);
2160 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2161 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2162 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
2163 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
2164 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2165 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
2166 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2167 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2169 bytes = GetBitmapBits(hbmp, 0, NULL);
2170 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
2171 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
2172 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
2173 bm.bmWidthBytes * bm.bmHeight, bytes);
2175 /* retrieve 1-bit DIB data */
2176 memset(bi, 0, sizeof(*bi));
2177 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2178 bi->bmiHeader.biWidth = bm.bmWidth;
2179 bi->bmiHeader.biHeight = bm.bmHeight;
2180 bi->bmiHeader.biPlanes = 1;
2181 bi->bmiHeader.biBitCount = 1;
2182 bi->bmiHeader.biCompression = BI_RGB;
2183 bi->bmiHeader.biClrUsed = 37;
2184 bi->bmiHeader.biSizeImage = 0;
2185 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2186 memset(buf, 0xAA, sizeof(buf));
2187 SetLastError(0xdeadbeef);
2188 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2189 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2190 lines, bm.bmHeight, GetLastError());
2191 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
2192 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2194 /* the color table consists of black and white */
2195 ok(colors[0].rgbRed == 0 && colors[0].rgbGreen == 0 &&
2196 colors[0].rgbBlue == 0 && colors[0].rgbReserved == 0,
2197 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
2198 colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue, colors[0].rgbReserved);
2199 ok(colors[1].rgbRed == 0xff && colors[1].rgbGreen == 0xff &&
2200 colors[1].rgbBlue == 0xff && colors[1].rgbReserved == 0,
2201 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
2202 colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue, colors[1].rgbReserved);
2203 for (i = 2; i < 256; i++)
2205 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2206 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2207 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2208 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2211 /* returned bits are DWORD aligned and upside down */
2212 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
2214 /* Test the palette indices */
2215 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2216 SetLastError(0xdeadbeef);
2217 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
2218 ok(((WORD*)colors)[0] == 0, "Color 0 is %d\n", ((WORD*)colors)[0]);
2219 ok(((WORD*)colors)[1] == 1, "Color 1 is %d\n", ((WORD*)colors)[1]);
2220 for (i = 2; i < 256; i++)
2221 ok(((WORD*)colors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)colors)[i]);
2223 /* retrieve 4-bit DIB data */
2224 memset(bi, 0, sizeof(*bi));
2225 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2226 bi->bmiHeader.biWidth = bm.bmWidth;
2227 bi->bmiHeader.biHeight = bm.bmHeight;
2228 bi->bmiHeader.biPlanes = 1;
2229 bi->bmiHeader.biBitCount = 4;
2230 bi->bmiHeader.biCompression = BI_RGB;
2231 bi->bmiHeader.biClrUsed = 37;
2232 bi->bmiHeader.biSizeImage = 0;
2233 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2234 memset(buf, 0xAA, sizeof(buf));
2235 SetLastError(0xdeadbeef);
2236 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2237 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2238 lines, bm.bmHeight, GetLastError());
2239 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2241 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2243 for (i = 0; i < 16; i++)
2245 RGBQUAD expect;
2246 int entry = i < 8 ? i : i + 4;
2248 if(entry == 7) entry = 12;
2249 else if(entry == 12) entry = 7;
2251 expect.rgbRed = pal_ents[entry].peRed;
2252 expect.rgbGreen = pal_ents[entry].peGreen;
2253 expect.rgbBlue = pal_ents[entry].peBlue;
2254 expect.rgbReserved = 0;
2256 ok(!memcmp(colors + i, &expect, sizeof(expect)),
2257 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2258 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2259 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2262 /* retrieve 8-bit DIB data */
2263 memset(bi, 0, sizeof(*bi));
2264 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2265 bi->bmiHeader.biWidth = bm.bmWidth;
2266 bi->bmiHeader.biHeight = bm.bmHeight;
2267 bi->bmiHeader.biPlanes = 1;
2268 bi->bmiHeader.biBitCount = 8;
2269 bi->bmiHeader.biCompression = BI_RGB;
2270 bi->bmiHeader.biClrUsed = 37;
2271 bi->bmiHeader.biSizeImage = 0;
2272 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2273 memset(buf, 0xAA, sizeof(buf));
2274 SetLastError(0xdeadbeef);
2275 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2276 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2277 lines, bm.bmHeight, GetLastError());
2278 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2280 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2282 for (i = 0; i < 256; i++)
2284 RGBQUAD expect;
2286 if (i < 10 || i >= 246)
2288 int entry = i < 10 ? i : i - 236;
2289 expect.rgbRed = pal_ents[entry].peRed;
2290 expect.rgbGreen = pal_ents[entry].peGreen;
2291 expect.rgbBlue = pal_ents[entry].peBlue;
2293 else
2295 expect.rgbRed = (i & 0x07) << 5;
2296 expect.rgbGreen = (i & 0x38) << 2;
2297 expect.rgbBlue = i & 0xc0;
2299 expect.rgbReserved = 0;
2301 ok(!memcmp(colors + i, &expect, sizeof(expect)),
2302 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2303 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2304 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2307 /* retrieve 24-bit DIB data */
2308 memset(bi, 0, sizeof(*bi));
2309 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2310 bi->bmiHeader.biWidth = bm.bmWidth;
2311 bi->bmiHeader.biHeight = bm.bmHeight;
2312 bi->bmiHeader.biPlanes = 1;
2313 bi->bmiHeader.biBitCount = 24;
2314 bi->bmiHeader.biCompression = BI_RGB;
2315 bi->bmiHeader.biClrUsed = 37;
2316 bi->bmiHeader.biSizeImage = 0;
2317 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2318 memset(buf, 0xAA, sizeof(buf));
2319 SetLastError(0xdeadbeef);
2320 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2321 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2322 lines, bm.bmHeight, GetLastError());
2323 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2324 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2326 /* the color table doesn't exist for 24-bit images */
2327 for (i = 0; i < 256; i++)
2329 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2330 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2331 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2332 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2335 /* returned bits are DWORD aligned and upside down */
2336 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2337 DeleteObject(hbmp);
2339 ReleaseDC(0, hdc);
2342 static void test_GetDIBits_BI_BITFIELDS(void)
2344 /* Try a screen resolution detection technique
2345 * from the September 1999 issue of Windows Developer's Journal
2346 * which seems to be in widespread use.
2347 * http://www.lesher.ws/highcolor.html
2348 * http://www.lesher.ws/vidfmt.c
2349 * It hinges on being able to retrieve the bitmaps
2350 * for the three primary colors in non-paletted 16 bit mode.
2352 char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
2353 DWORD bits[32];
2354 LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
2355 DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
2356 HDC hdc;
2357 HBITMAP hbm;
2358 int ret;
2359 void *ptr;
2361 memset(dibinfo, 0, sizeof(dibinfo_buf));
2362 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2364 hdc = GetDC(NULL);
2365 ok(hdc != NULL, "GetDC failed?\n");
2366 hbm = CreateCompatibleBitmap(hdc, 1, 1);
2367 ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
2369 /* Call GetDIBits to fill in bmiHeader. */
2370 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2371 ok(ret == 1, "GetDIBits failed\n");
2372 if (dibinfo->bmiHeader.biBitCount > 8)
2374 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2375 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2376 "compression is %u (%d bpp)\n", dibinfo->bmiHeader.biCompression, dibinfo->bmiHeader.biBitCount );
2378 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2380 ok( !bitmasks[0], "red mask is set\n" );
2381 ok( !bitmasks[1], "green mask is set\n" );
2382 ok( !bitmasks[2], "blue mask is set\n" );
2384 /* test with NULL bits pointer and correct bpp */
2385 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2386 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2387 ok(ret == 1, "GetDIBits failed\n");
2389 ok( bitmasks[0] != 0, "red mask is not set\n" );
2390 ok( bitmasks[1] != 0, "green mask is not set\n" );
2391 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2392 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2394 /* test with valid bits pointer */
2395 memset(dibinfo, 0, sizeof(dibinfo_buf));
2396 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2397 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2398 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2399 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2400 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2401 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2403 ok( bitmasks[0] != 0, "red mask is not set\n" );
2404 ok( bitmasks[1] != 0, "green mask is not set\n" );
2405 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2406 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2408 /* now with bits and 0 lines */
2409 memset(dibinfo, 0, sizeof(dibinfo_buf));
2410 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2411 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2412 SetLastError(0xdeadbeef);
2413 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2414 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2416 ok( !bitmasks[0], "red mask is set\n" );
2417 ok( !bitmasks[1], "green mask is set\n" );
2418 ok( !bitmasks[2], "blue mask is set\n" );
2419 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2421 memset(bitmasks, 0, 3*sizeof(DWORD));
2422 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2423 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2424 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2426 ok( bitmasks[0] != 0, "red mask is not set\n" );
2427 ok( bitmasks[1] != 0, "green mask is not set\n" );
2428 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2429 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2432 else skip("bitmap in colortable mode, skipping BI_BITFIELDS tests\n");
2434 DeleteObject(hbm);
2436 /* same thing now with a 32-bpp DIB section */
2438 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2439 dibinfo->bmiHeader.biWidth = 1;
2440 dibinfo->bmiHeader.biHeight = 1;
2441 dibinfo->bmiHeader.biPlanes = 1;
2442 dibinfo->bmiHeader.biBitCount = 32;
2443 dibinfo->bmiHeader.biCompression = BI_RGB;
2444 dibinfo->bmiHeader.biSizeImage = 0;
2445 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2446 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2447 dibinfo->bmiHeader.biClrUsed = 0;
2448 dibinfo->bmiHeader.biClrImportant = 0;
2449 bitmasks[0] = 0x0000ff;
2450 bitmasks[1] = 0x00ff00;
2451 bitmasks[2] = 0xff0000;
2452 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2453 ok( hbm != 0, "failed to create bitmap\n" );
2455 memset(dibinfo, 0, sizeof(dibinfo_buf));
2456 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2457 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2458 ok(ret == 1, "GetDIBits failed\n");
2459 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2461 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2462 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2463 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2464 ok( !bitmasks[0], "red mask is set\n" );
2465 ok( !bitmasks[1], "green mask is set\n" );
2466 ok( !bitmasks[2], "blue mask is set\n" );
2468 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2469 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2470 ok(ret == 1, "GetDIBits failed\n");
2471 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2472 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2473 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2474 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2475 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2477 ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
2478 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2479 ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
2481 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2483 DeleteObject(hbm);
2485 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2486 dibinfo->bmiHeader.biWidth = 1;
2487 dibinfo->bmiHeader.biHeight = 1;
2488 dibinfo->bmiHeader.biPlanes = 1;
2489 dibinfo->bmiHeader.biBitCount = 32;
2490 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2491 dibinfo->bmiHeader.biSizeImage = 0;
2492 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2493 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2494 dibinfo->bmiHeader.biClrUsed = 0;
2495 dibinfo->bmiHeader.biClrImportant = 0;
2496 bitmasks[0] = 0x0000ff;
2497 bitmasks[1] = 0x00ff00;
2498 bitmasks[2] = 0xff0000;
2499 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2500 ok( hbm != 0, "failed to create bitmap\n" );
2502 if (hbm)
2504 memset(dibinfo, 0, sizeof(dibinfo_buf));
2505 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2506 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2507 ok(ret == 1, "GetDIBits failed\n");
2509 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
2510 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2511 ok( !bitmasks[0], "red mask is set\n" );
2512 ok( !bitmasks[1], "green mask is set\n" );
2513 ok( !bitmasks[2], "blue mask is set\n" );
2515 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2516 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2517 ok(ret == 1, "GetDIBits failed\n");
2518 ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
2519 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2520 ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
2521 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2523 DeleteObject(hbm);
2526 /* 24-bpp DIB sections don't have bitfields */
2528 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2529 dibinfo->bmiHeader.biWidth = 1;
2530 dibinfo->bmiHeader.biHeight = 1;
2531 dibinfo->bmiHeader.biPlanes = 1;
2532 dibinfo->bmiHeader.biBitCount = 24;
2533 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2534 dibinfo->bmiHeader.biSizeImage = 0;
2535 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2536 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2537 dibinfo->bmiHeader.biClrUsed = 0;
2538 dibinfo->bmiHeader.biClrImportant = 0;
2539 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2540 ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
2541 dibinfo->bmiHeader.biCompression = BI_RGB;
2542 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2543 ok( hbm != 0, "failed to create bitmap\n" );
2545 memset(dibinfo, 0, sizeof(dibinfo_buf));
2546 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2547 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2548 ok(ret == 1, "GetDIBits failed\n");
2549 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2551 ok( dibinfo->bmiHeader.biCompression == BI_RGB,
2552 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2553 ok( !bitmasks[0], "red mask is set\n" );
2554 ok( !bitmasks[1], "green mask is set\n" );
2555 ok( !bitmasks[2], "blue mask is set\n" );
2557 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2558 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2559 ok(ret == 1, "GetDIBits failed\n");
2560 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2561 ok( !bitmasks[0], "red mask is set\n" );
2562 ok( !bitmasks[1], "green mask is set\n" );
2563 ok( !bitmasks[2], "blue mask is set\n" );
2564 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2566 DeleteObject(hbm);
2567 ReleaseDC(NULL, hdc);
2570 static void test_select_object(void)
2572 HDC hdc;
2573 HBITMAP hbm, hbm_old;
2574 INT planes, bpp, i;
2575 DWORD depths[] = {8, 15, 16, 24, 32};
2576 BITMAP bm;
2577 DWORD bytes;
2579 hdc = GetDC(0);
2580 ok(hdc != 0, "GetDC(0) failed\n");
2581 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2582 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2584 hbm_old = SelectObject(hdc, hbm);
2585 ok(hbm_old == 0, "SelectObject should fail\n");
2587 DeleteObject(hbm);
2588 ReleaseDC(0, hdc);
2590 hdc = CreateCompatibleDC(0);
2591 ok(hdc != 0, "GetDC(0) failed\n");
2592 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2593 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2595 hbm_old = SelectObject(hdc, hbm);
2596 ok(hbm_old != 0, "SelectObject failed\n");
2597 hbm_old = SelectObject(hdc, hbm_old);
2598 ok(hbm_old == hbm, "SelectObject failed\n");
2600 DeleteObject(hbm);
2602 /* test an 1-bpp bitmap */
2603 planes = GetDeviceCaps(hdc, PLANES);
2604 bpp = 1;
2606 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
2607 ok(hbm != 0, "CreateBitmap failed\n");
2609 hbm_old = SelectObject(hdc, hbm);
2610 ok(hbm_old != 0, "SelectObject failed\n");
2611 hbm_old = SelectObject(hdc, hbm_old);
2612 ok(hbm_old == hbm, "SelectObject failed\n");
2614 DeleteObject(hbm);
2616 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
2617 /* test a color bitmap to dc bpp matching */
2618 planes = GetDeviceCaps(hdc, PLANES);
2619 bpp = GetDeviceCaps(hdc, BITSPIXEL);
2621 hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
2622 ok(hbm != 0, "CreateBitmap failed\n");
2624 hbm_old = SelectObject(hdc, hbm);
2625 if(depths[i] == bpp ||
2626 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
2628 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
2629 SelectObject(hdc, hbm_old);
2630 } else {
2631 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
2634 memset(&bm, 0xAA, sizeof(bm));
2635 bytes = GetObject(hbm, sizeof(bm), &bm);
2636 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2637 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2638 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
2639 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
2640 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2641 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
2642 if(depths[i] == 15) {
2643 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
2644 } else {
2645 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2647 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2649 DeleteObject(hbm);
2652 DeleteDC(hdc);
2655 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
2657 INT ret;
2658 BITMAP bm;
2660 ret = GetObjectType(hbmp);
2661 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
2663 ret = GetObject(hbmp, 0, 0);
2664 ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
2666 memset(&bm, 0xDA, sizeof(bm));
2667 SetLastError(0xdeadbeef);
2668 ret = GetObject(hbmp, sizeof(bm), &bm);
2669 if (!ret) /* XP, only for curObj2 */ return;
2670 ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
2671 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2672 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2673 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2674 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2675 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2676 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2677 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2680 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2682 static void test_CreateBitmap(void)
2684 BITMAP bmp;
2685 HDC screenDC = GetDC(0);
2686 HDC hdc = CreateCompatibleDC(screenDC);
2687 UINT i, expect = 0;
2689 /* all of these are the stock monochrome bitmap */
2690 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2691 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2692 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2693 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2694 HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2695 HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2697 /* these 2 are not the stock monochrome bitmap */
2698 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2699 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2701 HBITMAP old1 = SelectObject(hdc, bm2);
2702 HBITMAP old2 = SelectObject(screenDC, bm3);
2703 SelectObject(hdc, old1);
2704 SelectObject(screenDC, old2);
2706 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2707 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2708 bm, bm1, bm4, bm5, curObj1, old1);
2709 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2710 todo_wine
2711 ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
2712 ok(old2 == 0, "old2 %p\n", old2);
2714 test_mono_1x1_bmp(bm);
2715 test_mono_1x1_bmp(bm1);
2716 test_mono_1x1_bmp(bm2);
2717 test_mono_1x1_bmp(bm3);
2718 test_mono_1x1_bmp(bm4);
2719 test_mono_1x1_bmp(bm5);
2720 test_mono_1x1_bmp(old1);
2721 test_mono_1x1_bmp(curObj1);
2723 DeleteObject(bm);
2724 DeleteObject(bm1);
2725 DeleteObject(bm2);
2726 DeleteObject(bm3);
2727 DeleteObject(bm4);
2728 DeleteObject(bm5);
2730 DeleteDC(hdc);
2731 ReleaseDC(0, screenDC);
2733 /* show that Windows ignores the provided bm.bmWidthBytes */
2734 bmp.bmType = 0;
2735 bmp.bmWidth = 1;
2736 bmp.bmHeight = 1;
2737 bmp.bmWidthBytes = 28;
2738 bmp.bmPlanes = 1;
2739 bmp.bmBitsPixel = 1;
2740 bmp.bmBits = NULL;
2741 bm = CreateBitmapIndirect(&bmp);
2742 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2743 test_mono_1x1_bmp(bm);
2744 DeleteObject(bm);
2746 /* Test how the bmBitsPixel field is treated */
2747 for(i = 1; i <= 33; i++) {
2748 bmp.bmType = 0;
2749 bmp.bmWidth = 1;
2750 bmp.bmHeight = 1;
2751 bmp.bmWidthBytes = 28;
2752 bmp.bmPlanes = 1;
2753 bmp.bmBitsPixel = i;
2754 bmp.bmBits = NULL;
2755 SetLastError(0xdeadbeef);
2756 bm = CreateBitmapIndirect(&bmp);
2757 if(i > 32) {
2758 DWORD error = GetLastError();
2759 ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
2760 ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2761 DeleteObject(bm);
2762 continue;
2764 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2765 GetObject(bm, sizeof(bmp), &bmp);
2766 if(i == 1) {
2767 expect = 1;
2768 } else if(i <= 4) {
2769 expect = 4;
2770 } else if(i <= 8) {
2771 expect = 8;
2772 } else if(i <= 16) {
2773 expect = 16;
2774 } else if(i <= 24) {
2775 expect = 24;
2776 } else if(i <= 32) {
2777 expect = 32;
2779 ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2780 i, bmp.bmBitsPixel, expect);
2781 DeleteObject(bm);
2785 static void test_bitmapinfoheadersize(void)
2787 HBITMAP hdib;
2788 BITMAPINFO bmi;
2789 BITMAPCOREINFO bci;
2790 HDC hdc = GetDC(0);
2792 memset(&bmi, 0, sizeof(BITMAPINFO));
2793 bmi.bmiHeader.biHeight = 100;
2794 bmi.bmiHeader.biWidth = 512;
2795 bmi.bmiHeader.biBitCount = 24;
2796 bmi.bmiHeader.biPlanes = 1;
2798 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2800 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2801 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2803 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2805 SetLastError(0xdeadbeef);
2806 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2807 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2808 DeleteObject(hdib);
2810 bmi.bmiHeader.biSize++;
2812 SetLastError(0xdeadbeef);
2813 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2814 ok(hdib != NULL ||
2815 broken(!hdib), /* Win98, WinMe */
2816 "CreateDIBSection error %d\n", GetLastError());
2817 DeleteObject(hdib);
2819 bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2821 SetLastError(0xdeadbeef);
2822 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2823 ok(hdib != NULL ||
2824 broken(!hdib), /* Win98, WinMe */
2825 "CreateDIBSection error %d\n", GetLastError());
2826 DeleteObject(hdib);
2828 bmi.bmiHeader.biSize++;
2830 SetLastError(0xdeadbeef);
2831 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2832 ok(hdib != NULL ||
2833 broken(!hdib), /* Win98, WinMe */
2834 "CreateDIBSection error %d\n", GetLastError());
2835 DeleteObject(hdib);
2837 bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2839 SetLastError(0xdeadbeef);
2840 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2841 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2842 DeleteObject(hdib);
2844 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2846 SetLastError(0xdeadbeef);
2847 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2848 ok(hdib != NULL ||
2849 broken(!hdib), /* Win95 */
2850 "CreateDIBSection error %d\n", GetLastError());
2851 DeleteObject(hdib);
2853 memset(&bci, 0, sizeof(BITMAPCOREINFO));
2854 bci.bmciHeader.bcHeight = 100;
2855 bci.bmciHeader.bcWidth = 512;
2856 bci.bmciHeader.bcBitCount = 24;
2857 bci.bmciHeader.bcPlanes = 1;
2859 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2861 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2862 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2864 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2866 SetLastError(0xdeadbeef);
2867 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2868 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2869 DeleteObject(hdib);
2871 bci.bmciHeader.bcSize++;
2873 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2874 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2876 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2878 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2879 ok(hdib == NULL, "CreateDIBSection succeeded\n");
2881 ReleaseDC(0, hdc);
2884 static void test_get16dibits(void)
2886 BYTE bits[4 * (16 / sizeof(BYTE))];
2887 HBITMAP hbmp;
2888 HDC screen_dc = GetDC(NULL);
2889 int ret;
2890 BITMAPINFO * info;
2891 int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2892 BYTE *p;
2893 int overwritten_bytes = 0;
2895 memset(bits, 0, sizeof(bits));
2896 hbmp = CreateBitmap(2, 2, 1, 16, bits);
2897 ok(hbmp != NULL, "CreateBitmap failed\n");
2899 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2900 assert(info);
2902 memset(info, '!', info_len);
2903 memset(info, 0, sizeof(info->bmiHeader));
2905 info->bmiHeader.biSize = sizeof(info->bmiHeader);
2906 info->bmiHeader.biWidth = 2;
2907 info->bmiHeader.biHeight = 2;
2908 info->bmiHeader.biPlanes = 1;
2909 info->bmiHeader.biCompression = BI_RGB;
2911 ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2912 ok(ret != 0, "GetDIBits failed got %d\n", ret);
2914 for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2915 if (*p != '!')
2916 overwritten_bytes++;
2917 ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2919 HeapFree(GetProcessHeap(), 0, info);
2920 DeleteObject(hbmp);
2921 ReleaseDC(NULL, screen_dc);
2924 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2925 DWORD dwRop, UINT32 expected, int line)
2927 *srcBuffer = 0xFEDCBA98;
2928 *dstBuffer = 0x89ABCDEF;
2929 BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
2930 ok(expected == *dstBuffer,
2931 "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2932 dwRop, expected, *dstBuffer, line);
2935 static void test_BitBlt(void)
2937 HBITMAP bmpDst, bmpSrc;
2938 HBITMAP oldDst, oldSrc;
2939 HDC hdcScreen, hdcDst, hdcSrc;
2940 UINT32 *dstBuffer, *srcBuffer;
2941 HBRUSH hBrush, hOldBrush;
2942 BITMAPINFO bitmapInfo;
2944 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2945 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2946 bitmapInfo.bmiHeader.biWidth = 1;
2947 bitmapInfo.bmiHeader.biHeight = 1;
2948 bitmapInfo.bmiHeader.biPlanes = 1;
2949 bitmapInfo.bmiHeader.biBitCount = 32;
2950 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2951 bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2953 hdcScreen = CreateCompatibleDC(0);
2954 hdcDst = CreateCompatibleDC(hdcScreen);
2955 hdcSrc = CreateCompatibleDC(hdcDst);
2957 /* Setup the destination dib section */
2958 bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
2959 NULL, 0);
2960 oldDst = SelectObject(hdcDst, bmpDst);
2962 hBrush = CreateSolidBrush(0x12345678);
2963 hOldBrush = SelectObject(hdcDst, hBrush);
2965 /* Setup the source dib section */
2966 bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
2967 NULL, 0);
2968 oldSrc = SelectObject(hdcSrc, bmpSrc);
2970 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2971 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2972 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2973 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2974 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2975 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2976 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2977 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2978 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2979 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2980 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2981 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2982 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2983 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2984 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2986 /* Tidy up */
2987 SelectObject(hdcSrc, oldSrc);
2988 DeleteObject(bmpSrc);
2989 DeleteDC(hdcSrc);
2991 SelectObject(hdcDst, hOldBrush);
2992 DeleteObject(hBrush);
2993 SelectObject(hdcDst, oldDst);
2994 DeleteObject(bmpDst);
2995 DeleteDC(hdcDst);
2998 DeleteDC(hdcScreen);
3001 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
3002 DWORD dwRop, UINT32 expected, int line)
3004 *srcBuffer = 0xFEDCBA98;
3005 *dstBuffer = 0x89ABCDEF;
3006 StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
3007 ok(expected == *dstBuffer,
3008 "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
3009 dwRop, expected, *dstBuffer, line);
3012 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, BITMAPINFO *dst_info, UINT32 *dstBuffer, UINT32 *srcBuffer,
3013 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
3014 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
3015 UINT32 *expected, int line)
3017 int dst_size = get_dib_image_size( dst_info );
3019 memset(dstBuffer, 0, dst_size);
3020 StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
3021 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
3022 ok(memcmp(dstBuffer, expected, dst_size) == 0,
3023 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
3024 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
3025 expected[0], expected[1], expected[2], expected[3],
3026 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
3027 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3028 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
3031 static void test_StretchBlt(void)
3033 HBITMAP bmpDst, bmpSrc;
3034 HBITMAP oldDst, oldSrc;
3035 HDC hdcScreen, hdcDst, hdcSrc;
3036 UINT32 *dstBuffer, *srcBuffer;
3037 HBRUSH hBrush, hOldBrush;
3038 BITMAPINFO biDst, biSrc;
3039 UINT32 expected[256];
3040 RGBQUAD colors[2];
3042 memset(&biDst, 0, sizeof(BITMAPINFO));
3043 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3044 biDst.bmiHeader.biWidth = 16;
3045 biDst.bmiHeader.biHeight = -16;
3046 biDst.bmiHeader.biPlanes = 1;
3047 biDst.bmiHeader.biBitCount = 32;
3048 biDst.bmiHeader.biCompression = BI_RGB;
3049 memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
3051 hdcScreen = CreateCompatibleDC(0);
3052 hdcDst = CreateCompatibleDC(hdcScreen);
3053 hdcSrc = CreateCompatibleDC(hdcDst);
3055 /* Pixel Tests */
3056 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3057 NULL, 0);
3058 oldDst = SelectObject(hdcDst, bmpDst);
3060 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
3061 NULL, 0);
3062 oldSrc = SelectObject(hdcSrc, bmpSrc);
3064 hBrush = CreateSolidBrush(0x012345678);
3065 hOldBrush = SelectObject(hdcDst, hBrush);
3067 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3068 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3069 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3070 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3071 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3072 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3073 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3074 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3075 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3076 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3077 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3078 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3079 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3080 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3081 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3083 SelectObject(hdcDst, hOldBrush);
3084 DeleteObject(hBrush);
3086 /* Top-down to top-down tests */
3087 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3088 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
3090 memset( expected, 0, get_dib_image_size( &biDst ) );
3091 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
3092 expected[16] = 0xFEDCBA98, expected[17] = 0x76543210;
3093 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3094 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3096 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3097 expected[16] = 0x00000000, expected[17] = 0x00000000;
3098 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3099 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
3101 expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
3102 expected[16] = 0xCAFED00D, expected[17] = 0xCAFED00D;
3103 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3104 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
3106 /* This is an example of the dst width (height) == 1 exception, explored below */
3107 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3108 expected[16] = 0x00000000, expected[17] = 0x00000000;
3109 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3110 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
3112 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
3113 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
3114 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3115 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3117 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
3118 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
3119 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3120 1, 1, -2, -2, 0, 0, 2, 2, expected, __LINE__);
3122 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3123 expected[16] = 0x00000000, expected[17] = 0x00000000;
3124 todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3125 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
3127 expected[0] = 0x00000000, expected[1] = 0x00000000;
3128 expected[16] = 0x00000000, expected[17] = 0xCAFED00D, expected[18] = 0xFEEDFACE;
3129 expected[32] = 0x00000000, expected[33] = 0xFEDCBA98, expected[34] = 0x76543210;
3131 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3132 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3134 /* when dst width is 1 merge src width - 1 pixels */
3135 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
3136 srcBuffer[0] = 0x0000ff00, srcBuffer[1] = 0x0000f0f0, srcBuffer[2] = 0x0000cccc, srcBuffer[3] = 0x0000aaaa;
3137 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
3139 memset( expected, 0, get_dib_image_size( &biDst ) );
3140 expected[0] = srcBuffer[0];
3141 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3142 0, 0, 1, 1, 0, 0, 2, 1, expected, __LINE__);
3144 expected[0] = srcBuffer[0] & srcBuffer[1];
3145 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3146 0, 0, 1, 1, 0, 0, 3, 1, expected, __LINE__);
3148 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
3149 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3150 0, 0, 1, 1, 0, 0, 4, 1, expected, __LINE__);
3152 /* this doesn't happen if the src width is -ve */
3153 expected[0] = srcBuffer[1] & srcBuffer[2];
3154 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3155 0, 0, 1, 1, 2, 0, -2, 1, expected, __LINE__);
3157 /* when dst width > 1 behaviour reverts to what one would expect */
3158 expected[0] = srcBuffer[0] & srcBuffer[1], expected[1] = srcBuffer[2] & srcBuffer[3];
3159 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3160 0, 0, 2, 1, 0, 0, 4, 1, expected, __LINE__);
3162 /* similarly in the vertical direction */
3163 memset( expected, 0, get_dib_image_size( &biDst ) );
3164 expected[0] = srcBuffer[0];
3165 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3166 0, 0, 1, 1, 0, 0, 1, 2, expected, __LINE__);
3168 /* check that it's the dst size in device units that needs to be 1 */
3169 SetMapMode( hdcDst, MM_ISOTROPIC );
3170 SetWindowExtEx( hdcDst, 200, 200, NULL );
3171 SetViewportExtEx( hdcDst, 100, 100, NULL );
3173 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
3174 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3175 0, 0, 2, 2, 0, 0, 4, 1, expected, __LINE__);
3176 SetMapMode( hdcDst, MM_TEXT );
3178 SelectObject(hdcDst, oldDst);
3179 DeleteObject(bmpDst);
3181 /* Top-down to bottom-up tests */
3182 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
3183 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3184 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
3186 biDst.bmiHeader.biHeight = 16;
3187 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3188 NULL, 0);
3189 oldDst = SelectObject(hdcDst, bmpDst);
3191 memset( expected, 0, get_dib_image_size( &biDst ) );
3193 expected[224] = 0xFEDCBA98, expected[225] = 0x76543210;
3194 expected[240] = 0xCAFED00D, expected[241] = 0xFEEDFACE;
3195 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3196 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3198 expected[224] = 0xFEEDFACE, expected[225] = 0xCAFED00D;
3199 expected[240] = 0x76543210, expected[241] = 0xFEDCBA98;
3200 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3201 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3203 SelectObject(hdcSrc, oldSrc);
3204 DeleteObject(bmpSrc);
3206 /* Bottom-up to bottom-up tests */
3207 biSrc.bmiHeader.biHeight = 16;
3208 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
3209 NULL, 0);
3210 srcBuffer[224] = 0xCAFED00D, srcBuffer[225] = 0xFEEDFACE;
3211 srcBuffer[240] = 0xFEDCBA98, srcBuffer[241] = 0x76543210;
3212 oldSrc = SelectObject(hdcSrc, bmpSrc);
3214 memset( expected, 0, get_dib_image_size( &biDst ) );
3216 expected[224] = 0xCAFED00D, expected[225] = 0xFEEDFACE;
3217 expected[240] = 0xFEDCBA98, expected[241] = 0x76543210;
3218 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3219 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3221 expected[224] = 0x76543210, expected[225] = 0xFEDCBA98;
3222 expected[240] = 0xFEEDFACE, expected[241] = 0xCAFED00D;
3223 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3224 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3226 SelectObject(hdcDst, oldDst);
3227 DeleteObject(bmpDst);
3229 /* Bottom-up to top-down tests */
3230 biDst.bmiHeader.biHeight = -16;
3231 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3232 NULL, 0);
3233 oldDst = SelectObject(hdcDst, bmpDst);
3235 memset( expected, 0, get_dib_image_size( &biDst ) );
3236 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3237 expected[16] = 0xCAFED00D, expected[17] = 0xFEEDFACE;
3238 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3239 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3241 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3242 expected[16] = 0x76543210, expected[17] = 0xFEDCBA98;
3243 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3244 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3246 SelectObject(hdcSrc, oldSrc);
3247 DeleteObject(bmpSrc);
3249 biSrc.bmiHeader.biHeight = -2;
3250 biSrc.bmiHeader.biBitCount = 24;
3251 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
3252 oldSrc = SelectObject(hdcSrc, bmpSrc);
3254 memset( expected, 0, get_dib_image_size( &biDst ) );
3255 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3256 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
3257 memcpy(dstBuffer, expected, 4 * sizeof(*dstBuffer));
3258 StretchBlt(hdcSrc, 0, 0, 4, 1, hdcDst, 0, 0, 4, 1, SRCCOPY );
3259 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
3260 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3261 expected[0] = 0x00EDFACE, expected[1] = 0x00FED00D;
3262 expected[2] = 0x00543210, expected[3] = 0x00DCBA98;
3263 ok(!memcmp(dstBuffer, expected, 16),
3264 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3265 expected[0], expected[1], expected[2], expected[3],
3266 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3268 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3269 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
3270 memcpy(srcBuffer, expected, 4 * sizeof(*dstBuffer));
3271 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
3272 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3273 expected[0] = 0x00EDFACE, expected[1] = 0x00D00DFE;
3274 expected[2] = 0x0010CAFE, expected[3] = 0x00765432;
3275 ok(!memcmp(dstBuffer, expected, 16),
3276 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3277 expected[0], expected[1], expected[2], expected[3],
3278 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3280 SelectObject(hdcSrc, oldSrc);
3281 DeleteObject(bmpSrc);
3283 biSrc.bmiHeader.biBitCount = 1;
3284 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
3285 oldSrc = SelectObject(hdcSrc, bmpSrc);
3286 *((DWORD *)colors + 0) = 0x123456;
3287 *((DWORD *)colors + 1) = 0x335577;
3288 SetDIBColorTable( hdcSrc, 0, 2, colors );
3289 srcBuffer[0] = 0x55555555;
3290 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
3291 SetTextColor( hdcDst, 0 );
3292 SetBkColor( hdcDst, 0 );
3293 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3294 expected[0] = expected[2] = 0x00123456;
3295 expected[1] = expected[3] = 0x00335577;
3296 ok(!memcmp(dstBuffer, expected, 16),
3297 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3298 expected[0], expected[1], expected[2], expected[3],
3299 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3301 SelectObject(hdcSrc, oldSrc);
3302 DeleteObject(bmpSrc);
3304 bmpSrc = CreateBitmap( 16, 16, 1, 1, 0 );
3305 oldSrc = SelectObject(hdcSrc, bmpSrc);
3306 SetPixel( hdcSrc, 0, 0, 0 );
3307 SetPixel( hdcSrc, 1, 0, 0xffffff );
3308 SetPixel( hdcSrc, 2, 0, 0xffffff );
3309 SetPixel( hdcSrc, 3, 0, 0 );
3310 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
3311 SetTextColor( hdcDst, RGB(0x22,0x44,0x66) );
3312 SetBkColor( hdcDst, RGB(0x65,0x43,0x21) );
3313 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3314 expected[0] = expected[3] = 0x00224466;
3315 expected[1] = expected[2] = 0x00654321;
3316 ok(!memcmp(dstBuffer, expected, 16),
3317 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3318 expected[0], expected[1], expected[2], expected[3],
3319 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3321 SelectObject(hdcSrc, oldSrc);
3322 DeleteObject(bmpSrc);
3324 DeleteDC(hdcSrc);
3326 SelectObject(hdcDst, oldDst);
3327 DeleteObject(bmpDst);
3328 DeleteDC(hdcDst);
3330 DeleteDC(hdcScreen);
3333 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3334 DWORD dwRop, UINT32 expected, int line)
3336 const UINT32 buffer[2] = { 0xFEDCBA98, 0 };
3337 BITMAPINFO bitmapInfo;
3339 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3340 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3341 bitmapInfo.bmiHeader.biWidth = 2;
3342 bitmapInfo.bmiHeader.biHeight = 1;
3343 bitmapInfo.bmiHeader.biPlanes = 1;
3344 bitmapInfo.bmiHeader.biBitCount = 32;
3345 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3346 bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer);
3348 *dstBuffer = 0x89ABCDEF;
3350 StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop);
3351 ok(expected == *dstBuffer,
3352 "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
3353 dwRop, expected, *dstBuffer, line);
3356 static INT check_StretchDIBits_stretch( HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3357 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
3358 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
3359 UINT32 expected[4], int line)
3361 BITMAPINFO bitmapInfo;
3362 INT ret;
3364 memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3365 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3366 bitmapInfo.bmiHeader.biWidth = 2;
3367 bitmapInfo.bmiHeader.biHeight = -2;
3368 bitmapInfo.bmiHeader.biPlanes = 1;
3369 bitmapInfo.bmiHeader.biBitCount = 32;
3370 bitmapInfo.bmiHeader.biCompression = BI_RGB;
3372 memset(dstBuffer, 0, 16);
3373 ret = StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
3374 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3375 srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
3376 ok(memcmp(dstBuffer, expected, 16) == 0,
3377 "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
3378 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
3379 expected[0], expected[1], expected[2], expected[3],
3380 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
3381 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3382 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
3383 return ret;
3386 static void test_StretchDIBits(void)
3388 HBITMAP bmpDst;
3389 HBITMAP oldDst;
3390 HDC hdcScreen, hdcDst;
3391 UINT32 *dstBuffer, srcBuffer[4];
3392 HBRUSH hBrush, hOldBrush;
3393 BITMAPINFO biDst;
3394 UINT32 expected[4];
3395 INT ret;
3397 memset(&biDst, 0, sizeof(BITMAPINFO));
3398 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3399 biDst.bmiHeader.biWidth = 2;
3400 biDst.bmiHeader.biHeight = -2;
3401 biDst.bmiHeader.biPlanes = 1;
3402 biDst.bmiHeader.biBitCount = 32;
3403 biDst.bmiHeader.biCompression = BI_RGB;
3405 hdcScreen = CreateCompatibleDC(0);
3406 hdcDst = CreateCompatibleDC(hdcScreen);
3408 /* Pixel Tests */
3409 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3410 NULL, 0);
3411 oldDst = SelectObject(hdcDst, bmpDst);
3413 hBrush = CreateSolidBrush(0x012345678);
3414 hOldBrush = SelectObject(hdcDst, hBrush);
3416 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3417 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3418 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3419 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3420 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3421 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3422 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3423 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3424 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3425 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3426 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3427 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3428 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3429 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3430 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3432 SelectObject(hdcDst, hOldBrush);
3433 DeleteObject(hBrush);
3435 /* Top-down destination tests */
3436 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3437 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
3439 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
3440 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
3441 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3442 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3443 ok( ret == 2, "got ret %d\n", ret );
3445 expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3446 expected[2] = 0x00000000, expected[3] = 0x00000000;
3447 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3448 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
3449 todo_wine ok( ret == 1, "got ret %d\n", ret );
3451 expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
3452 expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
3453 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3454 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
3455 ok( ret == 2, "got ret %d\n", ret );
3457 expected[0] = 0x42441000, expected[1] = 0x00000000;
3458 expected[2] = 0x00000000, expected[3] = 0x00000000;
3459 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3460 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
3461 ok( ret == 2, "got ret %d\n", ret );
3463 expected[0] = 0x00000000, expected[1] = 0x00000000;
3464 expected[2] = 0x00000000, expected[3] = 0x00000000;
3465 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3466 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3467 ok( ret == 0, "got ret %d\n", ret );
3469 expected[0] = 0x00000000, expected[1] = 0x00000000;
3470 expected[2] = 0x00000000, expected[3] = 0x00000000;
3471 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3472 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3473 ok( ret == 0, "got ret %d\n", ret );
3475 expected[0] = 0x00000000, expected[1] = 0x00000000;
3476 expected[2] = 0x00000000, expected[3] = 0x00000000;
3477 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3478 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
3479 ok( ret == 0, "got ret %d\n", ret );
3481 expected[0] = 0x00000000, expected[1] = 0x00000000;
3482 expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
3483 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3484 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3485 ok( ret == 2, "got ret %d\n", ret );
3487 expected[0] = 0x00000000, expected[1] = 0x00000000;
3488 expected[2] = 0x00000000, expected[3] = 0x00000000;
3489 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3490 2, 2, 4, 4, 0, 0, 2, 2, expected, __LINE__);
3491 ok( ret == 2, "got ret %d\n", ret );
3493 expected[0] = 0x00000000, expected[1] = 0x00000000;
3494 expected[2] = 0x00000000, expected[3] = 0x00000000;
3495 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3496 -4, -4, 4, 4, 0, 0, 4, 4, expected, __LINE__);
3497 ok( ret == 2, "got ret %d\n", ret );
3499 SelectObject(hdcDst, oldDst);
3500 DeleteObject(bmpDst);
3502 /* Bottom up destination tests */
3503 biDst.bmiHeader.biHeight = 2;
3504 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3505 NULL, 0);
3506 oldDst = SelectObject(hdcDst, bmpDst);
3508 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3509 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
3510 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3511 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3513 /* Tidy up */
3514 SelectObject(hdcDst, oldDst);
3515 DeleteObject(bmpDst);
3516 DeleteDC(hdcDst);
3518 DeleteDC(hdcScreen);
3521 static void test_GdiAlphaBlend(void)
3523 HDC hdcNull;
3524 HDC hdcDst;
3525 HBITMAP bmpDst;
3526 HBITMAP oldDst;
3527 BITMAPINFO *bmi;
3528 HDC hdcSrc;
3529 HBITMAP bmpSrc;
3530 HBITMAP oldSrc;
3531 LPVOID bits;
3532 BOOL ret;
3533 BLENDFUNCTION blend;
3535 if (!pGdiAlphaBlend)
3537 win_skip("GdiAlphaBlend() is not implemented\n");
3538 return;
3541 hdcNull = GetDC(NULL);
3542 hdcDst = CreateCompatibleDC(hdcNull);
3543 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
3544 hdcSrc = CreateCompatibleDC(hdcNull);
3546 bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3547 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3548 bmi->bmiHeader.biHeight = 20;
3549 bmi->bmiHeader.biWidth = 20;
3550 bmi->bmiHeader.biBitCount = 32;
3551 bmi->bmiHeader.biPlanes = 1;
3552 bmi->bmiHeader.biCompression = BI_RGB;
3553 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3554 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3556 oldDst = SelectObject(hdcDst, bmpDst);
3557 oldSrc = SelectObject(hdcSrc, bmpSrc);
3559 blend.BlendOp = AC_SRC_OVER;
3560 blend.BlendFlags = 0;
3561 blend.SourceConstantAlpha = 128;
3562 blend.AlphaFormat = 0;
3564 SetLastError(0xdeadbeef);
3565 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3566 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3568 SetLastError(0xdeadbeef);
3569 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3570 ok( !ret, "GdiAlphaBlend succeeded\n" );
3571 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3573 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3574 ok( !ret, "GdiAlphaBlend succeeded\n" );
3575 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend);
3576 ok( !ret, "GdiAlphaBlend succeeded\n" );
3577 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3578 ok( !ret, "GdiAlphaBlend succeeded\n" );
3579 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3580 ok( !ret, "GdiAlphaBlend succeeded\n" );
3582 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
3583 SetLastError(0xdeadbeef);
3584 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3585 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3586 SetLastError(0xdeadbeef);
3587 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3588 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3589 SetMapMode(hdcSrc, MM_ANISOTROPIC);
3590 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
3591 SetLastError(0xdeadbeef);
3592 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend);
3593 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3594 SetLastError(0xdeadbeef);
3595 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend);
3596 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3598 SetMapMode(hdcDst, MM_ANISOTROPIC);
3599 SetViewportExtEx(hdcDst, -1, -1, NULL);
3600 SetLastError(0xdeadbeef);
3601 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 50, 50, blend);
3602 todo_wine
3603 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3604 SetLastError(0xdeadbeef);
3605 ret = pGdiAlphaBlend(hdcDst, -20, -20, 20, 20, hdcSrc, 0, -1, 50, 50, blend);
3606 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3607 SetLastError(0xdeadbeef);
3608 ret = pGdiAlphaBlend(hdcDst, -20, -20, -20, -20, hdcSrc, 0, -1, 50, 50, blend);
3609 ok( !ret, "GdiAlphaBlend succeeded\n" );
3610 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3611 SetLastError(0xdeadbeef);
3612 ret = pGdiAlphaBlend(hdcDst, -20, 0, -20, 20, hdcSrc, 0, -1, 50, 50, blend);
3613 ok( !ret, "GdiAlphaBlend succeeded\n" );
3614 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3615 SetLastError(0xdeadbeef);
3616 ret = pGdiAlphaBlend(hdcDst, 0, -20, 20, -20, hdcSrc, 0, -1, 50, 50, blend);
3617 ok( !ret, "GdiAlphaBlend succeeded\n" );
3618 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3619 SetMapMode(hdcDst, MM_TEXT);
3621 SetViewportExtEx(hdcSrc, -1, -1, NULL);
3622 SetLastError(0xdeadbeef);
3623 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, -30, -30, blend);
3624 ok( !ret, "GdiAlphaBlend succeeded\n" );
3625 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3626 SetLastError(0xdeadbeef);
3627 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, 30, -30, blend);
3628 ok( !ret, "GdiAlphaBlend succeeded\n" );
3629 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3630 SetLastError(0xdeadbeef);
3631 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, -30, 30, blend);
3632 ok( !ret, "GdiAlphaBlend succeeded\n" );
3633 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3634 SetLastError(0xdeadbeef);
3635 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, 30, 30, blend);
3636 ok( !ret, "GdiAlphaBlend succeeded\n" );
3637 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3638 SetLastError(0xdeadbeef);
3639 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 20, 20, 30, 30, blend);
3640 ok( !ret, "GdiAlphaBlend succeeded\n" );
3641 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3642 SetLastError(0xdeadbeef);
3643 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -60, -60, 30, 30, blend);
3644 ok( !ret, "GdiAlphaBlend succeeded\n" );
3645 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3646 SetViewportExtEx(hdcSrc, 1, 1, NULL);
3648 SetLastError(0xdeadbeef);
3649 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend);
3650 ok( !ret, "GdiAlphaBlend succeeded\n" );
3651 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3653 /* overlapping source and dest not allowed */
3655 SetLastError(0xdeadbeef);
3656 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 19, 19, 20, 20, blend);
3657 ok( !ret, "GdiAlphaBlend succeeded\n" );
3658 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3660 SetLastError(0xdeadbeef);
3661 ret = pGdiAlphaBlend(hdcDst, 20, 20, 20, 20, hdcDst, 1, 1, 20, 20, blend);
3662 ok( !ret, "GdiAlphaBlend succeeded\n" );
3663 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3665 SetLastError(0xdeadbeef);
3666 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 20, 10, 20, 20, blend);
3667 ok( ret, "GdiAlphaBlend succeeded\n" );
3668 SetLastError(0xdeadbeef);
3669 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 10, 20, 20, 20, blend);
3670 ok( ret, "GdiAlphaBlend succeeded\n" );
3672 /* AC_SRC_ALPHA requires 32-bpp BI_RGB format */
3674 blend.AlphaFormat = AC_SRC_ALPHA;
3675 SetLastError(0xdeadbeef);
3676 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3677 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3679 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3680 ((DWORD *)bmi->bmiColors)[0] = 0xff0000;
3681 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3682 ((DWORD *)bmi->bmiColors)[2] = 0x0000ff;
3683 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3684 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3685 oldSrc = SelectObject(hdcSrc, bmpSrc);
3686 DeleteObject( oldSrc );
3688 SetLastError(0xdeadbeef);
3689 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3690 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3692 bmi->bmiHeader.biCompression = BI_BITFIELDS;
3693 ((DWORD *)bmi->bmiColors)[0] = 0x0000ff;
3694 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3695 ((DWORD *)bmi->bmiColors)[2] = 0xff0000;
3696 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3697 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3698 oldSrc = SelectObject(hdcSrc, bmpSrc);
3699 DeleteObject( oldSrc );
3701 SetLastError(0xdeadbeef);
3702 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3703 ok( !ret, "GdiAlphaBlend succeeded\n" );
3704 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3706 bmi->bmiHeader.biBitCount = 24;
3707 bmi->bmiHeader.biCompression = BI_RGB;
3708 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3709 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3710 oldSrc = SelectObject(hdcSrc, bmpSrc);
3711 DeleteObject( oldSrc );
3713 SetLastError(0xdeadbeef);
3714 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3715 ok( !ret, "GdiAlphaBlend succeeded\n" );
3716 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3718 bmi->bmiHeader.biBitCount = 1;
3719 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3720 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3721 oldSrc = SelectObject(hdcSrc, bmpSrc);
3722 DeleteObject( oldSrc );
3724 SetLastError(0xdeadbeef);
3725 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3726 ok( !ret, "GdiAlphaBlend succeeded\n" );
3727 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3729 bmpSrc = CreateBitmap( 100, 100, 1, 1, NULL );
3730 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3731 oldSrc = SelectObject(hdcSrc, bmpSrc);
3732 DeleteObject( oldSrc );
3734 SetLastError(0xdeadbeef);
3735 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3736 ok( !ret, "GdiAlphaBlend succeeded\n" );
3737 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3739 SelectObject(hdcDst, oldDst);
3740 SelectObject(hdcSrc, oldSrc);
3741 DeleteObject(bmpSrc);
3742 DeleteObject(bmpDst);
3743 DeleteDC(hdcDst);
3744 DeleteDC(hdcSrc);
3746 ReleaseDC(NULL, hdcNull);
3750 static void test_GdiGradientFill(void)
3752 HDC hdc;
3753 BOOL ret;
3754 HBITMAP bmp;
3755 BITMAPINFO *bmi;
3756 void *bits;
3757 GRADIENT_RECT rect[] = { { 0, 0 }, { 0, 1 }, { 2, 3 } };
3758 GRADIENT_TRIANGLE tri[] = { { 0, 0, 0 }, { 0, 1, 2 }, { 0, 2, 1 }, { 0, 1, 3 } };
3759 TRIVERTEX vt[3] = { { 2, 2, 0xff00, 0x0000, 0x0000, 0x8000 },
3760 { 10, 10, 0x0000, 0xff00, 0x0000, 0x8000 },
3761 { 20, 10, 0x0000, 0x0000, 0xff00, 0xff00 } };
3763 if (!pGdiGradientFill)
3765 win_skip( "GdiGradientFill is not implemented\n" );
3766 return;
3769 hdc = CreateCompatibleDC( NULL );
3770 bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3771 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3772 bmi->bmiHeader.biHeight = 20;
3773 bmi->bmiHeader.biWidth = 20;
3774 bmi->bmiHeader.biBitCount = 32;
3775 bmi->bmiHeader.biPlanes = 1;
3776 bmi->bmiHeader.biCompression = BI_RGB;
3777 bmp = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3778 ok( bmp != NULL, "couldn't create bitmap\n" );
3779 SelectObject( hdc, bmp );
3781 SetLastError( 0xdeadbeef );
3782 ret = pGdiGradientFill( hdc, vt, 3, rect, 1, GRADIENT_FILL_RECT_H );
3783 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3784 SetLastError( 0xdeadbeef );
3785 ret = pGdiGradientFill( hdc, vt, 3, rect, 1, 3 );
3786 ok( !ret, "GdiGradientFill succeeded\n" );
3787 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3788 SetLastError( 0xdeadbeef );
3789 ret = pGdiGradientFill( (HDC)0xdead, vt, 3, rect, 1, GRADIENT_FILL_RECT_H );
3790 ok( !ret, "GdiGradientFill succeeded\n" );
3791 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3792 SetLastError( 0xdeadbeef );
3793 ret = pGdiGradientFill( NULL, NULL, 0, rect, 1, GRADIENT_FILL_RECT_H );
3794 ok( !ret, "GdiGradientFill succeeded\n" );
3795 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3796 ret = pGdiGradientFill( hdc, NULL, 0, rect, 1, GRADIENT_FILL_RECT_H );
3797 ok( !ret, "GdiGradientFill succeeded\n" );
3798 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3799 SetLastError( 0xdeadbeef );
3800 ret = pGdiGradientFill( hdc, NULL, 3, rect, 1, GRADIENT_FILL_RECT_H );
3801 ok( !ret, "GdiGradientFill succeeded\n" );
3802 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3803 SetLastError( 0xdeadbeef );
3804 ret = pGdiGradientFill( hdc, vt, 3, NULL, 0, GRADIENT_FILL_RECT_H );
3805 ok( !ret, "GdiGradientFill succeeded\n" );
3806 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3807 SetLastError( 0xdeadbeef );
3808 ret = pGdiGradientFill( hdc, vt, 3, NULL, 1, GRADIENT_FILL_RECT_H );
3809 ok( !ret, "GdiGradientFill succeeded\n" );
3810 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3811 SetLastError( 0xdeadbeef );
3812 ret = pGdiGradientFill( hdc, vt, 3, rect, 0, GRADIENT_FILL_RECT_H );
3813 ok( !ret, "GdiGradientFill succeeded\n" );
3814 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3815 SetLastError( 0xdeadbeef );
3816 ret = pGdiGradientFill( hdc, vt, 3, rect, 3, GRADIENT_FILL_RECT_H );
3817 ok( !ret, "GdiGradientFill succeeded\n" );
3818 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3819 rect[2].UpperLeft = rect[2].LowerRight = 1;
3820 SetLastError( 0xdeadbeef );
3821 ret = pGdiGradientFill( hdc, vt, 3, rect, 3, GRADIENT_FILL_RECT_H );
3822 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3823 SetLastError( 0xdeadbeef );
3824 ret = pGdiGradientFill( hdc, vt, 1, rect, 1, GRADIENT_FILL_RECT_H );
3825 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3826 SetLastError( 0xdeadbeef );
3827 ret = pGdiGradientFill( hdc, vt, 1, tri, 0, GRADIENT_FILL_TRIANGLE );
3828 ok( !ret, "GdiGradientFill succeeded\n" );
3829 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3830 SetLastError( 0xdeadbeef );
3831 ret = pGdiGradientFill( hdc, vt, 1, tri, 1, GRADIENT_FILL_TRIANGLE );
3832 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3833 SetLastError( 0xdeadbeef );
3834 ret = pGdiGradientFill( hdc, vt, 3, tri, 2, GRADIENT_FILL_TRIANGLE );
3835 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3836 SetLastError( 0xdeadbeef );
3837 ret = pGdiGradientFill( hdc, vt, 3, tri, 3, GRADIENT_FILL_TRIANGLE );
3838 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3839 SetLastError( 0xdeadbeef );
3840 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3841 ok( !ret, "GdiGradientFill succeeded\n" );
3842 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3843 tri[3].Vertex3 = 1;
3844 SetLastError( 0xdeadbeef );
3845 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3846 ok( !ret, "GdiGradientFill succeeded\n" );
3847 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3848 tri[3].Vertex3 = 0;
3849 SetLastError( 0xdeadbeef );
3850 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3851 ok( !ret, "GdiGradientFill succeeded\n" );
3852 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3853 tri[3].Vertex1 = tri[3].Vertex2 = tri[3].Vertex3 = 1;
3854 SetLastError( 0xdeadbeef );
3855 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3856 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3858 DeleteDC( hdc );
3859 DeleteObject( bmp );
3862 static void test_clipping(void)
3864 HBITMAP bmpDst;
3865 HBITMAP bmpSrc;
3866 HRGN hRgn;
3867 LPVOID bits;
3868 BOOL result;
3870 HDC hdcDst = CreateCompatibleDC( NULL );
3871 HDC hdcSrc = CreateCompatibleDC( NULL );
3873 BITMAPINFO bmpinfo={{0}};
3874 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3875 bmpinfo.bmiHeader.biWidth = 100;
3876 bmpinfo.bmiHeader.biHeight = 100;
3877 bmpinfo.bmiHeader.biPlanes = 1;
3878 bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3879 bmpinfo.bmiHeader.biCompression = BI_RGB;
3881 bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3882 ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3883 SelectObject( hdcDst, bmpDst );
3885 bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3886 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3887 SelectObject( hdcSrc, bmpSrc );
3889 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3890 ok(result, "BitBlt failed\n");
3892 hRgn = CreateRectRgn( 0,0,0,0 );
3893 SelectClipRgn( hdcDst, hRgn );
3895 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3896 ok(result, "BitBlt failed\n");
3898 DeleteObject( bmpDst );
3899 DeleteObject( bmpSrc );
3900 DeleteObject( hRgn );
3901 DeleteDC( hdcDst );
3902 DeleteDC( hdcSrc );
3905 static void test_32bit_ddb(void)
3907 char buffer[sizeof(BITMAPINFOHEADER) + sizeof(DWORD)];
3908 BITMAPINFO *biDst = (BITMAPINFO *)buffer;
3909 HBITMAP bmpSrc, bmpDst;
3910 HBITMAP oldSrc, oldDst;
3911 HDC hdcSrc, hdcDst, hdcScreen;
3912 HBRUSH brush;
3913 DWORD *dstBuffer, *data;
3914 DWORD colorSrc = 0x40201008;
3916 memset(biDst, 0, sizeof(BITMAPINFOHEADER));
3917 biDst->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3918 biDst->bmiHeader.biWidth = 1;
3919 biDst->bmiHeader.biHeight = -1;
3920 biDst->bmiHeader.biPlanes = 1;
3921 biDst->bmiHeader.biBitCount = 32;
3922 biDst->bmiHeader.biCompression = BI_RGB;
3924 hdcScreen = CreateCompatibleDC(0);
3925 if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3927 DeleteDC(hdcScreen);
3928 trace("Skipping 32-bit DDB test\n");
3929 return;
3932 hdcSrc = CreateCompatibleDC(hdcScreen);
3933 bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3934 oldSrc = SelectObject(hdcSrc, bmpSrc);
3936 hdcDst = CreateCompatibleDC(hdcScreen);
3937 bmpDst = CreateDIBSection(hdcDst, biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3938 oldDst = SelectObject(hdcDst, bmpDst);
3940 StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3941 ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3943 if (pGdiAlphaBlend)
3945 BLENDFUNCTION blend;
3946 BOOL ret;
3948 blend.BlendOp = AC_SRC_OVER;
3949 blend.BlendFlags = 0;
3950 blend.SourceConstantAlpha = 128;
3951 blend.AlphaFormat = 0;
3952 dstBuffer[0] = 0x80808080;
3953 ret = pGdiAlphaBlend( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, blend );
3954 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3955 ok(dstBuffer[0] == 0x60504844, "wrong color %x\n", dstBuffer[0]);
3956 blend.AlphaFormat = AC_SRC_ALPHA;
3957 dstBuffer[0] = 0x80808080;
3958 ret = pGdiAlphaBlend( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, blend );
3959 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3960 ok(dstBuffer[0] == 0x90807874, "wrong color %x\n", dstBuffer[0]);
3963 data = (DWORD *)biDst->bmiColors;
3964 data[0] = 0x20304050;
3965 brush = CreateDIBPatternBrushPt( biDst, DIB_RGB_COLORS );
3966 ok( brush != 0, "brush creation failed\n" );
3967 SelectObject( hdcSrc, brush );
3968 PatBlt( hdcSrc, 0, 0, 1, 1, PATCOPY );
3969 BitBlt( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, SRCCOPY );
3970 ok(dstBuffer[0] == data[0], "Expected color=%x, received color=%x\n", data[0], dstBuffer[0]);
3971 SelectObject( hdcSrc, GetStockObject(BLACK_BRUSH) );
3972 DeleteObject( brush );
3974 biDst->bmiHeader.biBitCount = 24;
3975 brush = CreateDIBPatternBrushPt( biDst, DIB_RGB_COLORS );
3976 ok( brush != 0, "brush creation failed\n" );
3977 SelectObject( hdcSrc, brush );
3978 PatBlt( hdcSrc, 0, 0, 1, 1, PATCOPY );
3979 BitBlt( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, SRCCOPY );
3980 ok(dstBuffer[0] == (data[0] & ~0xff000000),
3981 "Expected color=%x, received color=%x\n", data[0] & 0xff000000, dstBuffer[0]);
3982 SelectObject( hdcSrc, GetStockObject(BLACK_BRUSH) );
3983 DeleteObject( brush );
3985 /* Tidy up */
3986 SelectObject(hdcDst, oldDst);
3987 DeleteObject(bmpDst);
3988 DeleteDC(hdcDst);
3990 SelectObject(hdcSrc, oldSrc);
3991 DeleteObject(bmpSrc);
3992 DeleteDC(hdcSrc);
3994 DeleteDC(hdcScreen);
3998 * Used by test_GetDIBits_top_down to create the bitmap to test against.
4000 static void setup_picture(char *picture, int bpp)
4002 int i;
4004 switch(bpp)
4006 case 16:
4007 case 32:
4008 /*Set the first byte in each pixel to the index of that pixel.*/
4009 for (i = 0; i < 4; i++)
4010 picture[i * (bpp / 8)] = i;
4011 break;
4012 case 24:
4013 picture[0] = 0;
4014 picture[3] = 1;
4015 /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
4016 picture[8] = 2;
4017 picture[11] = 3;
4018 break;
4022 static void test_GetDIBits_top_down(int bpp)
4024 BITMAPINFO bi;
4025 HBITMAP bmptb, bmpbt;
4026 HDC hdc;
4027 int pictureOut[4];
4028 int *picture;
4029 int statusCode;
4031 memset( &bi, 0, sizeof(bi) );
4032 bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
4033 bi.bmiHeader.biWidth=2;
4034 bi.bmiHeader.biHeight=2;
4035 bi.bmiHeader.biPlanes=1;
4036 bi.bmiHeader.biBitCount=bpp;
4037 bi.bmiHeader.biCompression=BI_RGB;
4039 /*Get the device context for the screen.*/
4040 hdc = GetDC(NULL);
4041 ok(hdc != NULL, "Could not get a handle to a device context.\n");
4043 /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
4044 bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
4045 ok(bmpbt != NULL, "Could not create a DIB section.\n");
4046 /*Now that we have a pointer to the pixels, we write to them.*/
4047 setup_picture((char*)picture, bpp);
4048 /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
4049 bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
4050 bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
4051 ok(bmptb != NULL, "Could not create a DIB section.\n");
4052 /*Write to this top to bottom bitmap.*/
4053 setup_picture((char*)picture, bpp);
4055 bi.bmiHeader.biWidth = 1;
4057 bi.bmiHeader.biHeight = 2;
4058 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
4059 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4060 /*Check the first byte of the pixel.*/
4061 ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
4062 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
4063 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4064 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
4065 /*Check second scanline.*/
4066 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
4067 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4068 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
4069 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
4070 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4071 ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
4072 /*Check both scanlines.*/
4073 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
4074 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4075 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
4076 ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
4077 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
4078 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4079 ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
4080 ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
4082 /*Make destination bitmap top-down.*/
4083 bi.bmiHeader.biHeight = -2;
4084 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
4085 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4086 ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
4087 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
4088 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4089 ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
4090 /*Check second scanline.*/
4091 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
4092 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4093 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
4094 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
4095 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4096 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
4097 /*Check both scanlines.*/
4098 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
4099 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4100 ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
4101 ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
4102 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
4103 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4104 ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
4105 ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
4107 DeleteObject(bmpbt);
4108 DeleteObject(bmptb);
4111 static void test_GetSetDIBits_rtl(void)
4113 HDC hdc, hdc_mem;
4114 HBITMAP bitmap, orig_bitmap;
4115 BITMAPINFO info;
4116 int ret;
4117 DWORD bits_1[8 * 8], bits_2[8 * 8];
4119 if(!pSetLayout)
4121 win_skip("Don't have SetLayout\n");
4122 return;
4125 hdc = GetDC( NULL );
4126 hdc_mem = CreateCompatibleDC( hdc );
4127 pSetLayout( hdc_mem, LAYOUT_LTR );
4129 bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
4130 orig_bitmap = SelectObject( hdc_mem, bitmap );
4131 SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
4132 SelectObject( hdc_mem, orig_bitmap );
4134 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
4135 info.bmiHeader.biWidth = 8;
4136 info.bmiHeader.biHeight = 8;
4137 info.bmiHeader.biPlanes = 1;
4138 info.bmiHeader.biBitCount = 32;
4139 info.bmiHeader.biCompression = BI_RGB;
4141 /* First show that GetDIBits ignores the layout mode. */
4143 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
4144 ok(ret == 8, "got %d\n", ret);
4145 ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
4147 pSetLayout( hdc_mem, LAYOUT_RTL );
4149 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
4150 ok(ret == 8, "got %d\n", ret);
4152 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
4154 /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
4155 followed by a GetDIBits and show that the bits remain unchanged. */
4157 pSetLayout( hdc_mem, LAYOUT_LTR );
4159 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
4160 ok(ret == 8, "got %d\n", ret);
4161 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
4162 ok(ret == 8, "got %d\n", ret);
4163 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
4165 pSetLayout( hdc_mem, LAYOUT_RTL );
4167 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
4168 ok(ret == 8, "got %d\n", ret);
4169 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
4170 ok(ret == 8, "got %d\n", ret);
4171 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
4173 DeleteObject( bitmap );
4174 DeleteDC( hdc_mem );
4175 ReleaseDC( NULL, hdc );
4178 static void test_GetDIBits_scanlines(void)
4180 BITMAPINFO *info;
4181 DWORD *dib_bits;
4182 HDC hdc = GetDC( NULL );
4183 HBITMAP dib;
4184 DWORD data[128], inverted_bits[64];
4185 int i, ret;
4187 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4189 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4190 info->bmiHeader.biWidth = 8;
4191 info->bmiHeader.biHeight = 8;
4192 info->bmiHeader.biPlanes = 1;
4193 info->bmiHeader.biBitCount = 32;
4194 info->bmiHeader.biCompression = BI_RGB;
4196 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4198 for (i = 0; i < 64; i++)
4200 dib_bits[i] = i;
4201 inverted_bits[56 - (i & ~7) + (i & 7)] = i;
4204 /* b-u -> b-u */
4206 memset( data, 0xaa, sizeof(data) );
4208 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4209 ok( ret == 8, "got %d\n", ret );
4210 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4211 memset( data, 0xaa, sizeof(data) );
4213 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4214 ok( ret == 5, "got %d\n", ret );
4215 ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
4216 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4217 memset( data, 0xaa, sizeof(data) );
4219 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4220 ok( ret == 7, "got %d\n", ret );
4221 ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
4222 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4223 memset( data, 0xaa, sizeof(data) );
4225 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4226 ok( ret == 1, "got %d\n", ret );
4227 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4228 memset( data, 0xaa, sizeof(data) );
4230 info->bmiHeader.biHeight = 16;
4231 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4232 ok( ret == 5, "got %d\n", ret );
4233 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4234 ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
4235 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4236 memset( data, 0xaa, sizeof(data) );
4238 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
4239 ok( ret == 6, "got %d\n", ret );
4240 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4241 ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
4242 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4243 memset( data, 0xaa, sizeof(data) );
4245 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
4246 ok( ret == 0, "got %d\n", ret );
4247 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4248 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4249 memset( data, 0xaa, sizeof(data) );
4251 info->bmiHeader.biHeight = 5;
4252 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4253 ok( ret == 2, "got %d\n", ret );
4254 ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
4255 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4256 memset( data, 0xaa, sizeof(data) );
4258 /* b-u -> t-d */
4260 info->bmiHeader.biHeight = -8;
4261 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4262 ok( ret == 8, "got %d\n", ret );
4263 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4264 memset( data, 0xaa, sizeof(data) );
4266 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4267 ok( ret == 5, "got %d\n", ret );
4268 ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
4269 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4270 memset( data, 0xaa, sizeof(data) );
4272 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4273 ok( ret == 7, "got %d\n", ret );
4274 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
4275 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4276 memset( data, 0xaa, sizeof(data) );
4278 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4279 ok( ret == 4, "got %d\n", ret );
4280 ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
4281 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4282 memset( data, 0xaa, sizeof(data) );
4284 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
4285 ok( ret == 5, "got %d\n", ret );
4286 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
4287 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4288 memset( data, 0xaa, sizeof(data) );
4290 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
4291 ok( ret == 5, "got %d\n", ret );
4292 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
4293 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4294 memset( data, 0xaa, sizeof(data) );
4296 info->bmiHeader.biHeight = -16;
4297 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
4298 ok( ret == 8, "got %d\n", ret );
4299 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4300 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4301 memset( data, 0xaa, sizeof(data) );
4303 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4304 ok( ret == 5, "got %d\n", ret );
4305 ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
4306 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4307 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4308 memset( data, 0xaa, sizeof(data) );
4310 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4311 ok( ret == 8, "got %d\n", ret );
4312 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4313 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4314 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4315 memset( data, 0xaa, sizeof(data) );
4317 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4318 ok( ret == 8, "got %d\n", ret );
4319 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4320 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4321 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4322 memset( data, 0xaa, sizeof(data) );
4324 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4325 ok( ret == 7, "got %d\n", ret );
4326 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
4327 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4328 memset( data, 0xaa, sizeof(data) );
4330 ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
4331 ok( ret == 1, "got %d\n", ret );
4332 for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4333 memset( data, 0xaa, sizeof(data) );
4335 info->bmiHeader.biHeight = -5;
4336 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4337 ok( ret == 2, "got %d\n", ret );
4338 ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
4339 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4340 memset( data, 0xaa, sizeof(data) );
4342 DeleteObject( dib );
4344 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4345 info->bmiHeader.biWidth = 8;
4346 info->bmiHeader.biHeight = -8;
4347 info->bmiHeader.biPlanes = 1;
4348 info->bmiHeader.biBitCount = 32;
4349 info->bmiHeader.biCompression = BI_RGB;
4351 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4353 for (i = 0; i < 64; i++) dib_bits[i] = i;
4355 /* t-d -> t-d */
4357 info->bmiHeader.biHeight = -8;
4358 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4359 ok( ret == 8, "got %d\n", ret );
4360 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4361 memset( data, 0xaa, sizeof(data) );
4363 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4364 ok( ret == 5, "got %d\n", ret );
4365 ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
4366 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4367 memset( data, 0xaa, sizeof(data) );
4369 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4370 ok( ret == 7, "got %d\n", ret );
4371 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
4372 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4373 memset( data, 0xaa, sizeof(data) );
4375 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4376 ok( ret == 4, "got %d\n", ret );
4377 ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
4378 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4379 memset( data, 0xaa, sizeof(data) );
4381 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
4382 ok( ret == 5, "got %d\n", ret );
4383 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
4384 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4385 memset( data, 0xaa, sizeof(data) );
4387 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
4388 ok( ret == 5, "got %d\n", ret );
4389 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
4390 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4391 memset( data, 0xaa, sizeof(data) );
4393 info->bmiHeader.biHeight = -16;
4394 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
4395 ok( ret == 8, "got %d\n", ret );
4396 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4397 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4398 memset( data, 0xaa, sizeof(data) );
4400 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4401 ok( ret == 5, "got %d\n", ret );
4402 ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
4403 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4404 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4405 memset( data, 0xaa, sizeof(data) );
4407 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4408 ok( ret == 8, "got %d\n", ret );
4409 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4410 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4411 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4412 memset( data, 0xaa, sizeof(data) );
4414 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4415 ok( ret == 8, "got %d\n", ret );
4416 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4417 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4418 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4419 memset( data, 0xaa, sizeof(data) );
4421 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4422 ok( ret == 7, "got %d\n", ret );
4423 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
4424 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4425 memset( data, 0xaa, sizeof(data) );
4427 info->bmiHeader.biHeight = -5;
4428 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4429 ok( ret == 2, "got %d\n", ret );
4430 ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
4431 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4432 memset( data, 0xaa, sizeof(data) );
4435 /* t-d -> b-u */
4437 info->bmiHeader.biHeight = 8;
4439 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4440 ok( ret == 8, "got %d\n", ret );
4441 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4442 memset( data, 0xaa, sizeof(data) );
4444 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4445 ok( ret == 5, "got %d\n", ret );
4446 ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
4447 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4448 memset( data, 0xaa, sizeof(data) );
4450 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4451 ok( ret == 7, "got %d\n", ret );
4452 ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
4453 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4454 memset( data, 0xaa, sizeof(data) );
4456 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4457 ok( ret == 1, "got %d\n", ret );
4458 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4459 memset( data, 0xaa, sizeof(data) );
4461 info->bmiHeader.biHeight = 16;
4462 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4463 ok( ret == 5, "got %d\n", ret );
4464 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4465 ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
4466 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4467 memset( data, 0xaa, sizeof(data) );
4469 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
4470 ok( ret == 6, "got %d\n", ret );
4471 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4472 ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
4473 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4474 memset( data, 0xaa, sizeof(data) );
4476 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
4477 ok( ret == 0, "got %d\n", ret );
4478 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4479 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4480 memset( data, 0xaa, sizeof(data) );
4482 info->bmiHeader.biHeight = 5;
4483 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4484 ok( ret == 2, "got %d\n", ret );
4485 ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
4486 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4487 memset( data, 0xaa, sizeof(data) );
4489 DeleteObject( dib );
4491 ReleaseDC( NULL, hdc );
4492 HeapFree( GetProcessHeap(), 0, info );
4496 static void test_SetDIBits(void)
4498 char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
4499 LOGPALETTE *pal = (LOGPALETTE *)palbuf;
4500 PALETTEENTRY *palent = pal->palPalEntry;
4501 HPALETTE palette;
4502 BITMAPINFO *info;
4503 DWORD *dib_bits;
4504 HDC hdc = GetDC( NULL );
4505 DWORD data[128], inverted_data[128];
4506 HBITMAP dib;
4507 int i, ret;
4509 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4511 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4512 info->bmiHeader.biWidth = 8;
4513 info->bmiHeader.biHeight = 8;
4514 info->bmiHeader.biPlanes = 1;
4515 info->bmiHeader.biBitCount = 32;
4516 info->bmiHeader.biCompression = BI_RGB;
4518 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4519 memset( dib_bits, 0xaa, 64 * 4 );
4521 for (i = 0; i < 128; i++)
4523 data[i] = i;
4524 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4527 /* b-u -> b-u */
4529 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4530 ok( ret == 8, "got %d\n", ret );
4531 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4532 memset( dib_bits, 0xaa, 64 * 4 );
4534 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4535 ok( ret == 5, "got %d\n", ret );
4536 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4537 ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
4538 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4539 memset( dib_bits, 0xaa, 64 * 4 );
4541 /* top of dst is aligned with startscans down for the top of the src.
4542 Then starting from the bottom of src, lines rows are copied across. */
4544 info->bmiHeader.biHeight = 16;
4545 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4546 ok( ret == 12, "got %d\n", ret );
4547 ok( !memcmp( dib_bits, data + 56, 40 * 4 ), "bits differ\n");
4548 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4549 memset( dib_bits, 0xaa, 64 * 4 );
4551 info->bmiHeader.biHeight = 5;
4552 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4553 ok( ret == 2, "got %d\n", ret );
4554 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4555 ok( !memcmp( dib_bits + 32, data, 16 * 4 ), "bits differ\n");
4556 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4557 memset( dib_bits, 0xaa, 64 * 4 );
4559 /* t-d -> b-u */
4560 info->bmiHeader.biHeight = -8;
4561 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4562 ok( ret == 8, "got %d\n", ret );
4563 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4564 memset( dib_bits, 0xaa, 64 * 4 );
4566 /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
4567 we copy lines rows from the top of the src */
4569 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4570 ok( ret == 5, "got %d\n", ret );
4571 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4572 ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
4573 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4574 memset( dib_bits, 0xaa, 64 * 4 );
4576 info->bmiHeader.biHeight = -16;
4577 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4578 ok( ret == 12, "got %d\n", ret );
4579 ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
4580 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4581 memset( dib_bits, 0xaa, 64 * 4 );
4583 ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4584 ok( ret == 12, "got %d\n", ret );
4585 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4586 memset( dib_bits, 0xaa, 64 * 4 );
4588 ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4589 ok( ret == 12, "got %d\n", ret );
4590 ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
4591 memset( dib_bits, 0xaa, 64 * 4 );
4593 info->bmiHeader.biHeight = -5;
4594 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4595 ok( ret == 2, "got %d\n", ret );
4596 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4597 ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
4598 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4599 memset( dib_bits, 0xaa, 64 * 4 );
4601 DeleteObject( dib );
4603 info->bmiHeader.biHeight = -8;
4605 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4606 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4608 /* t-d -> t-d */
4610 /* like the t-d -> b-u case. */
4612 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4613 ok( ret == 8, "got %d\n", ret );
4614 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4615 memset( dib_bits, 0xaa, 64 * 4 );
4617 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4618 ok( ret == 5, "got %d\n", ret );
4619 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4620 ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
4621 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4622 memset( dib_bits, 0xaa, 64 * 4 );
4624 info->bmiHeader.biHeight = -16;
4625 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4626 ok( ret == 12, "got %d\n", ret );
4627 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4628 ok( !memcmp( dib_bits + 24, data, 40 * 4 ), "bits differ\n");
4629 memset( dib_bits, 0xaa, 64 * 4 );
4631 info->bmiHeader.biHeight = -5;
4632 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4633 ok( ret == 2, "got %d\n", ret );
4634 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4635 ok( !memcmp( dib_bits + 16, data, 16 * 4 ), "bits differ\n");
4636 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4637 memset( dib_bits, 0xaa, 64 * 4 );
4639 /* b-u -> t-d */
4640 /* like the b-u -> b-u case */
4642 info->bmiHeader.biHeight = 8;
4643 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4644 ok( ret == 8, "got %d\n", ret );
4645 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4646 memset( dib_bits, 0xaa, 64 * 4 );
4648 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4649 ok( ret == 5, "got %d\n", ret );
4650 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4651 ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
4652 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4653 memset( dib_bits, 0xaa, 64 * 4 );
4655 info->bmiHeader.biHeight = 16;
4656 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4657 ok( ret == 12, "got %d\n", ret );
4658 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4659 ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
4660 memset( dib_bits, 0xaa, 64 * 4 );
4662 info->bmiHeader.biHeight = 5;
4663 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4664 ok( ret == 2, "got %d\n", ret );
4665 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4666 ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
4667 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4668 memset( dib_bits, 0xaa, 64 * 4 );
4670 /* handling of partial color table */
4672 info->bmiHeader.biHeight = -8;
4673 info->bmiHeader.biBitCount = 8;
4674 info->bmiHeader.biClrUsed = 137;
4675 for (i = 0; i < 256; i++)
4677 info->bmiColors[i].rgbRed = 255 - i;
4678 info->bmiColors[i].rgbGreen = i * 2;
4679 info->bmiColors[i].rgbBlue = i;
4680 info->bmiColors[i].rgbReserved = 0;
4682 for (i = 0; i < 64; i++) ((BYTE *)data)[i] = i * 4 + 1;
4683 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4684 ok( ret == 8, "got %d\n", ret );
4685 for (i = 0; i < 64; i++)
4687 int idx = i * 4 + 1;
4688 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : (info->bmiColors[idx].rgbRed << 16 |
4689 info->bmiColors[idx].rgbGreen << 8 |
4690 info->bmiColors[idx].rgbBlue);
4691 ok( dib_bits[i] == expect, "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
4693 memset( dib_bits, 0xaa, 64 * 4 );
4695 /* handling of DIB_PAL_COLORS */
4697 pal->palVersion = 0x300;
4698 pal->palNumEntries = 137;
4699 info->bmiHeader.biClrUsed = 221;
4700 for (i = 0; i < 256; i++)
4702 palent[i].peRed = i * 2;
4703 palent[i].peGreen = 255 - i;
4704 palent[i].peBlue = i;
4706 palette = CreatePalette( pal );
4707 ok( palette != 0, "palette creation failed\n" );
4708 SelectPalette( hdc, palette, FALSE );
4709 for (i = 0; i < 256; i++) ((WORD *)info->bmiColors)[i] = 255 - i;
4710 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_PAL_COLORS );
4711 ok( ret == 8, "got %d\n", ret );
4712 for (i = 0; i < 64; i++)
4714 int idx = i * 4 + 1;
4715 int ent = (255 - idx) % pal->palNumEntries;
4716 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 :
4717 (palent[ent].peRed << 16 | palent[ent].peGreen << 8 | palent[ent].peBlue);
4718 ok( dib_bits[i] == expect || broken(dib_bits[i] == 0), /* various Windows versions get some values wrong */
4719 "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
4721 memset( dib_bits, 0xaa, 64 * 4 );
4723 ReleaseDC( NULL, hdc );
4724 DeleteObject( dib );
4725 DeleteObject( palette );
4726 HeapFree( GetProcessHeap(), 0, info );
4729 static void test_SetDIBits_RLE4(void)
4731 BITMAPINFO *info;
4732 DWORD *dib_bits;
4733 HDC hdc = GetDC( NULL );
4734 BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00, /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
4735 0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
4736 0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00, /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
4737 0x00, 0x02, 0x01, 0x02, 0x05, 0x87, /* dx=1, dy=2, 8, 7, 8, 7, 8 */
4738 0x00, 0x01 }; /* <eod> */
4739 HBITMAP dib;
4740 int i, ret;
4741 DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
4742 0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
4743 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4744 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4745 0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
4746 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4747 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4748 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4750 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4752 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4753 info->bmiHeader.biWidth = 8;
4754 info->bmiHeader.biHeight = 8;
4755 info->bmiHeader.biPlanes = 1;
4756 info->bmiHeader.biBitCount = 32;
4757 info->bmiHeader.biCompression = BI_RGB;
4759 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4760 memset( dib_bits, 0xaa, 64 * 4 );
4762 info->bmiHeader.biBitCount = 4;
4763 info->bmiHeader.biCompression = BI_RLE4;
4764 info->bmiHeader.biSizeImage = sizeof(rle4_data);
4766 for (i = 0; i < 16; i++)
4768 info->bmiColors[i].rgbRed = i;
4769 info->bmiColors[i].rgbGreen = i;
4770 info->bmiColors[i].rgbBlue = i;
4771 info->bmiColors[i].rgbReserved = 0;
4774 ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
4775 ok( ret == 8, "got %d\n", ret );
4776 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
4777 memset( dib_bits, 0xaa, 64 * 4 );
4779 DeleteObject( dib );
4780 ReleaseDC( NULL, hdc );
4781 HeapFree( GetProcessHeap(), 0, info );
4784 static void test_SetDIBits_RLE8(void)
4786 BITMAPINFO *info;
4787 DWORD *dib_bits;
4788 HDC hdc = GetDC( NULL );
4789 BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00, /* 2, 2, 2, f0, f0, f0, f0, <eol> */
4790 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
4791 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4792 0x00, 0x01 }; /* <eod> */
4793 HBITMAP dib;
4794 int i, ret;
4795 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4796 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4797 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4798 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4799 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4800 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4801 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4802 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4803 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4804 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4805 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4806 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4807 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4808 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4809 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4810 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4812 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4814 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4815 info->bmiHeader.biWidth = 8;
4816 info->bmiHeader.biHeight = 8;
4817 info->bmiHeader.biPlanes = 1;
4818 info->bmiHeader.biBitCount = 32;
4819 info->bmiHeader.biCompression = BI_RGB;
4821 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4822 memset( dib_bits, 0xaa, 64 * 4 );
4824 info->bmiHeader.biBitCount = 8;
4825 info->bmiHeader.biCompression = BI_RLE8;
4826 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4828 for (i = 0; i < 256; i++)
4830 info->bmiColors[i].rgbRed = i;
4831 info->bmiColors[i].rgbGreen = i;
4832 info->bmiColors[i].rgbBlue = i;
4833 info->bmiColors[i].rgbReserved = 0;
4836 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4837 ok( ret == 8, "got %d\n", ret );
4838 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4839 memset( dib_bits, 0xaa, 64 * 4 );
4841 /* startscan and lines are ignored, unless lines == 0 */
4842 ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4843 ok( ret == 8, "got %d\n", ret );
4844 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4845 memset( dib_bits, 0xaa, 64 * 4 );
4847 ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4848 ok( ret == 8, "got %d\n", ret );
4849 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4850 memset( dib_bits, 0xaa, 64 * 4 );
4852 ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4853 ok( ret == 0, "got %d\n", ret );
4854 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4855 memset( dib_bits, 0xaa, 64 * 4 );
4857 /* reduce width to 4, left-hand side of dst is touched. */
4858 info->bmiHeader.biWidth = 4;
4859 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4860 ok( ret == 8, "got %d\n", ret );
4861 for (i = 0; i < 64; i++)
4863 DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4864 ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4866 memset( dib_bits, 0xaa, 64 * 4 );
4868 /* Show that the top lines are aligned by adjusting the height of the src */
4870 /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4871 info->bmiHeader.biWidth = 8;
4872 info->bmiHeader.biHeight = 4;
4873 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4874 ok( ret == 4, "got %d\n", ret );
4875 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4876 ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4877 memset( dib_bits, 0xaa, 64 * 4 );
4879 /* increase the height to 9 -> everything moves down one row. */
4880 info->bmiHeader.biHeight = 9;
4881 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4882 ok( ret == 9, "got %d\n", ret );
4883 ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4884 for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4885 memset( dib_bits, 0xaa, 64 * 4 );
4887 /* top-down compressed dibs are invalid */
4888 info->bmiHeader.biHeight = -8;
4889 SetLastError( 0xdeadbeef );
4890 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4891 ok( ret == 0, "got %d\n", ret );
4892 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4893 DeleteObject( dib );
4895 /* top-down dst */
4897 info->bmiHeader.biHeight = -8;
4898 info->bmiHeader.biBitCount = 32;
4899 info->bmiHeader.biCompression = BI_RGB;
4900 info->bmiHeader.biSizeImage = 0;
4902 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4903 memset( dib_bits, 0xaa, 16 * 16 * 4 );
4905 info->bmiHeader.biHeight = 8;
4906 info->bmiHeader.biBitCount = 8;
4907 info->bmiHeader.biCompression = BI_RLE8;
4908 info->bmiHeader.biSizeImage = sizeof(rle8_data);
4910 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4911 ok( ret == 8, "got %d\n", ret );
4912 ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4913 memset( dib_bits, 0xaa, 64 * 4 );
4915 info->bmiHeader.biHeight = 4;
4916 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4917 ok( ret == 4, "got %d\n", ret );
4918 ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4919 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4920 memset( dib_bits, 0xaa, 64 * 4 );
4922 info->bmiHeader.biHeight = 9;
4923 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4924 ok( ret == 9, "got %d\n", ret );
4925 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4926 ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4927 memset( dib_bits, 0xaa, 64 * 4 );
4929 DeleteObject( dib );
4930 ReleaseDC( NULL, hdc );
4931 HeapFree( GetProcessHeap(), 0, info );
4934 static void test_SetDIBitsToDevice(void)
4936 char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
4937 LOGPALETTE *pal = (LOGPALETTE *)palbuf;
4938 PALETTEENTRY *palent = pal->palPalEntry;
4939 HPALETTE palette;
4940 BITMAPINFO *info;
4941 DWORD *dib_bits;
4942 HDC hdc = CreateCompatibleDC( 0 );
4943 DWORD data[128], inverted_data[128];
4944 HBITMAP dib;
4945 int i, ret;
4947 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4949 info->bmiHeader.biSize = sizeof(info->bmiHeader);
4950 info->bmiHeader.biWidth = 8;
4951 info->bmiHeader.biHeight = 8;
4952 info->bmiHeader.biPlanes = 1;
4953 info->bmiHeader.biBitCount = 32;
4954 info->bmiHeader.biCompression = BI_RGB;
4956 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4957 memset( dib_bits, 0xaa, 64 * 4 );
4958 SelectObject( hdc, dib );
4960 for (i = 0; i < 128; i++)
4962 data[i] = i;
4963 inverted_data[120 - (i & ~7) + (i & 7)] = i;
4966 /* b-u -> b-u */
4968 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4969 ok( ret == 8, "got %d\n", ret );
4970 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4971 memset( dib_bits, 0xaa, 64 * 4 );
4973 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4974 ok( ret == 5, "got %d\n", ret );
4975 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4976 for (i = 8; i < 48; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4977 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4978 memset( dib_bits, 0xaa, 64 * 4 );
4980 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 3, 1, 5, data, info, DIB_RGB_COLORS );
4981 ok( ret == 5, "got %d\n", ret );
4982 for (i = 0; i < 24; i++) ok( dib_bits[i] == data[i + 16], "%d: got %08x\n", i, dib_bits[i] );
4983 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4984 memset( dib_bits, 0xaa, 64 * 4 );
4986 info->bmiHeader.biHeight = 16;
4987 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4988 ok( ret == 7, "got %d\n", ret );
4989 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4990 for (i = 8; i < 64; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4991 memset( dib_bits, 0xaa, 64 * 4 );
4993 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 8, 0, 6, 1, 12, data, info, DIB_RGB_COLORS );
4994 ok( ret == 12, "got %d\n", ret );
4995 for (i = 0; i < 40; i++) ok( dib_bits[i] == data[i + 56], "%d: got %08x\n", i, dib_bits[i] );
4996 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4997 memset( dib_bits, 0xaa, 64 * 4 );
4999 ret = SetDIBitsToDevice( hdc, 0, -4, 8, 8, 0, 3, 1, 12, data, info, DIB_RGB_COLORS );
5000 ok( ret == 10, "got %d\n", ret );
5001 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5002 for (i = 32; i < 64; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
5003 memset( dib_bits, 0xaa, 64 * 4 );
5005 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, -3, 1, 12, data, info, DIB_RGB_COLORS );
5006 ok( ret == 4, "got %d\n", ret );
5007 for (i = 0; i < 32; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
5008 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5009 memset( dib_bits, 0xaa, 64 * 4 );
5011 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 5, 0, -2, 1, 12, data, info, DIB_RGB_COLORS );
5012 ok( ret == 2, "got %d\n", ret );
5013 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5014 for (i = 32; i < 48; i++) ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
5015 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5016 memset( dib_bits, 0xaa, 64 * 4 );
5018 info->bmiHeader.biHeight = 5;
5019 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 2, 2, data, info, DIB_RGB_COLORS );
5020 ok( ret == 2, "got %d\n", ret );
5021 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5022 for (i = 16; i < 32; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
5023 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5024 memset( dib_bits, 0xaa, 64 * 4 );
5026 ret = SetDIBitsToDevice( hdc, 3, 3, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
5027 ok( ret == 3, "got %d\n", ret );
5028 for (i = 0; i < 64; i++)
5029 if (i == 27 || i == 28 || i == 35 || i == 36)
5030 ok( dib_bits[i] == data[i - 18], "%d: got %08x\n", i, dib_bits[i] );
5031 else
5032 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5033 memset( dib_bits, 0xaa, 64 * 4 );
5035 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5036 ok( ret == 5, "got %d\n", ret );
5037 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5038 memset( dib_bits, 0xaa, 64 * 4 );
5040 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
5041 ok( ret == 0, "got %d\n", ret );
5042 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5043 memset( dib_bits, 0xaa, 64 * 4 );
5045 SetMapMode( hdc, MM_ANISOTROPIC );
5046 SetWindowExtEx( hdc, 3, 3, NULL );
5047 ret = SetDIBitsToDevice( hdc, 2, 2, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
5048 ok( ret == 3, "got %d\n", ret );
5049 for (i = 0; i < 64; i++)
5050 if (i == 41 || i == 42 || i == 49 || i == 50)
5051 ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
5052 else
5053 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5054 memset( dib_bits, 0xaa, 64 * 4 );
5056 SetWindowExtEx( hdc, -1, -1, NULL );
5057 ret = SetDIBitsToDevice( hdc, 2, 2, 4, 4, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
5058 ok( ret == 4, "got %d\n", ret );
5059 for (i = 0; i < 64; i++)
5060 if (i == 48 || i == 49 || i == 56 || i == 57)
5061 ok( dib_bits[i] == data[i - 37], "%d: got %08x\n", i, dib_bits[i] );
5062 else
5063 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5064 memset( dib_bits, 0xaa, 64 * 4 );
5065 SetMapMode( hdc, MM_TEXT );
5067 if (pSetLayout)
5069 pSetLayout( hdc, LAYOUT_RTL );
5070 ret = SetDIBitsToDevice( hdc, 1, 2, 3, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
5071 ok( ret == 3, "got %d\n", ret );
5072 for (i = 0; i < 64; i++)
5073 if (i == 36 || i == 37 || i == 38 || i == 44 || i == 45 || i == 46)
5074 ok( dib_bits[i] == data[i - 27], "%d: got %08x\n", i, dib_bits[i] );
5075 else
5076 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5077 memset( dib_bits, 0xaa, 64 * 4 );
5078 pSetLayout( hdc, LAYOUT_LTR );
5081 /* t-d -> b-u */
5082 info->bmiHeader.biHeight = -8;
5083 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5084 ok( ret == 8, "got %d\n", ret );
5085 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
5086 memset( dib_bits, 0xaa, 64 * 4 );
5088 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
5089 ok( ret == 5, "got %d\n", ret );
5090 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5091 for (i = 8; i < 48; i++) ok( dib_bits[i] == inverted_data[i + 80], "%d: got %08x\n", i, dib_bits[i] );
5092 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5093 memset( dib_bits, 0xaa, 64 * 4 );
5095 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 4, 1, 5, data, info, DIB_RGB_COLORS );
5096 ok( ret == 5, "got %d\n", ret );
5097 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
5098 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5099 memset( dib_bits, 0xaa, 64 * 4 );
5101 info->bmiHeader.biHeight = -16;
5102 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
5103 ok( ret == 12, "got %d\n", ret );
5104 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5105 for (i = 8; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 24], "%d: got %08x\n", i, dib_bits[i] );
5106 memset( dib_bits, 0xaa, 64 * 4 );
5108 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, 7, 1, 12, data, info, DIB_RGB_COLORS );
5109 ok( ret == 12, "got %d\n", ret );
5110 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
5111 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5112 memset( dib_bits, 0xaa, 64 * 4 );
5114 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 4, 12, data, info, DIB_RGB_COLORS );
5115 ok( ret == 12, "got %d\n", ret );
5116 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5117 for (i = 32; i < 64; i++) ok( dib_bits[i] == inverted_data[i], "%d: got %08x\n", i, dib_bits[i] );
5118 memset( dib_bits, 0xaa, 64 * 4 );
5120 ret = SetDIBitsToDevice( hdc, 0, -3, 8, 8, 0, 2, 4, 12, data, info, DIB_RGB_COLORS );
5121 ok( ret == 12, "got %d\n", ret );
5122 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5123 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5124 memset( dib_bits, 0xaa, 64 * 4 );
5126 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, -2, 4, 12, data, info, DIB_RGB_COLORS );
5127 ok( ret == 12, "got %d\n", ret );
5128 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5129 for (i = 24; i < 40; i++) ok( dib_bits[i] == inverted_data[i + 8], "%d: got %08x\n", i, dib_bits[i] );
5130 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5131 memset( dib_bits, 0xaa, 64 * 4 );
5133 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 5, 12, data, info, DIB_RGB_COLORS );
5134 ok( ret == 12, "got %d\n", ret );
5135 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5136 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5137 memset( dib_bits, 0xaa, 64 * 4 );
5139 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
5140 ok( ret == 12, "got %d\n", ret );
5141 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5142 memset( dib_bits, 0xaa, 64 * 4 );
5144 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -2, -4, 0, 12, data, info, DIB_RGB_COLORS );
5145 ok( ret == 12, "got %d\n", ret );
5146 for (i = 0; i < 64; i++)
5147 if (i == 31 || i == 39 || i == 47 || i == 55 || i == 63)
5148 ok( dib_bits[i] == inverted_data[i + 1], "%d: got %08x\n", i, dib_bits[i] );
5149 else
5150 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5151 memset( dib_bits, 0xaa, 64 * 4 );
5153 info->bmiHeader.biHeight = -5;
5154 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
5155 ok( ret == 2, "got %d\n", ret );
5156 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5157 for (i = 8; i < 24; i++) ok( dib_bits[i] == inverted_data[i + 104], "%d: got %08x\n", i, dib_bits[i] );
5158 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5159 memset( dib_bits, 0xaa, 64 * 4 );
5161 ret = SetDIBitsToDevice( hdc, 5, 4, 2, 2, 6, 3, 1, 5, data, info, DIB_RGB_COLORS );
5162 ok( ret == 5, "got %d\n", ret );
5163 for (i = 0; i < 64; i++)
5164 if (i == 21 || i == 22 || i == 29 || i == 30)
5165 ok( dib_bits[i] == inverted_data[i + 89], "%d: got %08x\n", i, dib_bits[i] );
5166 else
5167 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5168 memset( dib_bits, 0xaa, 64 * 4 );
5170 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5171 ok( ret == 5, "got %d\n", ret );
5172 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5173 memset( dib_bits, 0xaa, 64 * 4 );
5175 info->bmiHeader.biHeight = -8;
5177 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5178 DeleteObject( SelectObject( hdc, dib ));
5179 memset( dib_bits, 0xaa, 16 * 16 * 4 );
5181 /* t-d -> t-d */
5183 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5184 ok( ret == 8, "got %d\n", ret );
5185 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
5186 memset( dib_bits, 0xaa, 64 * 4 );
5188 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
5189 ok( ret == 5, "got %d\n", ret );
5190 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5191 for (i = 16; i < 56; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
5192 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5193 memset( dib_bits, 0xaa, 64 * 4 );
5195 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 3, 0, 2, 1, 5, data, info, DIB_RGB_COLORS );
5196 ok( ret == 5, "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 < 48; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
5199 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5200 memset( dib_bits, 0xaa, 64 * 4 );
5202 info->bmiHeader.biHeight = -16;
5203 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
5204 ok( ret == 12, "got %d\n", ret );
5205 for (i = 0; i < 56; i++) ok( dib_bits[i] == data[i + 40], "%d: got %08x\n", i, dib_bits[i] );
5206 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5207 memset( dib_bits, 0xaa, 64 * 4 );
5209 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -1, -8, 0, 12, data, info, DIB_RGB_COLORS );
5210 ok( ret == 12, "got %d\n", ret );
5211 for (i = 0; i < 64; i++)
5212 if (i == 6 || i == 7)
5213 ok( dib_bits[i] == data[i + 82], "%d: got %08x\n", i, dib_bits[i] );
5214 else
5215 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5216 memset( dib_bits, 0xaa, 64 * 4 );
5218 info->bmiHeader.biHeight = -5;
5219 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
5220 ok( ret == 2, "got %d\n", ret );
5221 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5222 for (i = 40; i < 56; i++) ok( dib_bits[i] == data[i - 40], "%d: got %08x\n", i, dib_bits[i] );
5223 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5224 memset( dib_bits, 0xaa, 64 * 4 );
5226 ret = SetDIBitsToDevice( hdc, 7, 2, 8, 8, 1, 0, 0, 5, data, info, DIB_RGB_COLORS );
5227 ok( ret == 5, "got %d\n", ret );
5228 for (i = 0; i < 64; i++)
5229 if (i == 47 || i == 55 || i == 63)
5230 ok( dib_bits[i] == data[i - 46], "%d: got %08x\n", i, dib_bits[i] );
5231 else
5232 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5233 memset( dib_bits, 0xaa, 64 * 4 );
5235 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5236 ok( ret == 5, "got %d\n", ret );
5237 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5238 memset( dib_bits, 0xaa, 64 * 4 );
5240 /* b-u -> t-d */
5242 info->bmiHeader.biHeight = 8;
5243 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5244 ok( ret == 8, "got %d\n", ret );
5245 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
5246 memset( dib_bits, 0xaa, 64 * 4 );
5248 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
5249 ok( ret == 5, "got %d\n", ret );
5250 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5251 for (i = 16; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
5252 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5253 memset( dib_bits, 0xaa, 64 * 4 );
5255 info->bmiHeader.biHeight = 16;
5256 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
5257 ok( ret == 7, "got %d\n", ret );
5258 for (i = 0; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
5259 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5260 memset( dib_bits, 0xaa, 64 * 4 );
5262 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, 0, -4, 1, 12, data, info, DIB_RGB_COLORS );
5263 ok( ret == 3, "got %d\n", ret );
5264 for (i = 0; i < 64; i++)
5265 if ((i >= 36 && i <= 39) || (i >= 44 && i <= 47) || (i >= 52 && i <= 55))
5266 ok( dib_bits[i] == inverted_data[i + 68], "%d: got %08x\n", i, dib_bits[i] );
5267 else
5268 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5269 memset( dib_bits, 0xaa, 64 * 4 );
5271 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, -30, -30, 1, 12, data, info, DIB_RGB_COLORS );
5272 ok( ret == 0, "got %d\n", ret );
5273 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5274 memset( dib_bits, 0xaa, 64 * 4 );
5276 ret = SetDIBitsToDevice( hdc, 5, -5, 8, 16, -2, -4, 4, 12, data, info, DIB_RGB_COLORS );
5277 ok( ret == 8, "got %d\n", ret );
5278 for (i = 0; i < 64; i++)
5279 if (i == 7 || i == 15 || i == 23)
5280 ok( dib_bits[i] == inverted_data[i + 97], "%d: got %08x\n", i, dib_bits[i] );
5281 else
5282 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5283 memset( dib_bits, 0xaa, 64 * 4 );
5285 info->bmiHeader.biHeight = 5;
5286 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
5287 ok( ret == 2, "got %d\n", ret );
5288 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5289 for (i = 40; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
5290 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5291 memset( dib_bits, 0xaa, 64 * 4 );
5293 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5294 ok( ret == 5, "got %d\n", ret );
5295 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5296 memset( dib_bits, 0xaa, 64 * 4 );
5298 /* handling of partial color table */
5300 info->bmiHeader.biHeight = -8;
5301 info->bmiHeader.biBitCount = 8;
5302 info->bmiHeader.biClrUsed = 137;
5303 for (i = 0; i < 256; i++)
5305 info->bmiColors[i].rgbRed = 255 - i;
5306 info->bmiColors[i].rgbGreen = i * 2;
5307 info->bmiColors[i].rgbBlue = i;
5308 info->bmiColors[i].rgbReserved = 0;
5310 for (i = 0; i < 64; i++) ((BYTE *)data)[i] = i * 4 + 1;
5311 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5312 ok( ret == 8, "got %d\n", ret );
5313 for (i = 0; i < 64; i++)
5315 int idx = i * 4 + 1;
5316 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : (info->bmiColors[idx].rgbRed << 16 |
5317 info->bmiColors[idx].rgbGreen << 8 |
5318 info->bmiColors[idx].rgbBlue);
5319 ok( dib_bits[i] == expect, "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
5321 memset( dib_bits, 0xaa, 64 * 4 );
5323 /* handling of DIB_PAL_COLORS */
5325 pal->palVersion = 0x300;
5326 pal->palNumEntries = 137;
5327 info->bmiHeader.biClrUsed = 221;
5328 for (i = 0; i < 256; i++)
5330 palent[i].peRed = i * 2;
5331 palent[i].peGreen = 255 - i;
5332 palent[i].peBlue = i;
5334 palette = CreatePalette( pal );
5335 ok( palette != 0, "palette creation failed\n" );
5336 SelectPalette( hdc, palette, FALSE );
5337 for (i = 0; i < 256; i++) ((WORD *)info->bmiColors)[i] = 255 - i;
5338 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_PAL_COLORS );
5339 ok( ret == 8, "got %d\n", ret );
5340 for (i = 0; i < 64; i++)
5342 int idx = i * 4 + 1;
5343 int ent = (255 - idx) % pal->palNumEntries;
5344 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 :
5345 (palent[ent].peRed << 16 | palent[ent].peGreen << 8 | palent[ent].peBlue);
5346 ok( dib_bits[i] == expect || broken(dib_bits[i] == 0),
5347 "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
5349 memset( dib_bits, 0xaa, 64 * 4 );
5351 DeleteDC( hdc );
5352 DeleteObject( dib );
5353 DeleteObject( palette );
5354 HeapFree( GetProcessHeap(), 0, info );
5357 static void test_SetDIBitsToDevice_RLE8(void)
5359 BITMAPINFO *info;
5360 DWORD *dib_bits;
5361 HDC hdc = CreateCompatibleDC( 0 );
5362 BYTE rle8_data[20] = { 0x04, 0x02, 0x03, 0xf0, 0x00, 0x00, /* 2, 2, 2, 2, f0, f0, f0, <eol> */
5363 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */
5364 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */
5365 0x00, 0x01 }; /* <eod> */
5366 HBITMAP dib;
5367 int i, ret;
5368 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
5369 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5370 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5371 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
5372 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5373 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5374 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5375 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
5376 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5377 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5378 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5379 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5380 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
5381 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5382 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5383 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
5385 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
5387 info->bmiHeader.biSize = sizeof(info->bmiHeader);
5388 info->bmiHeader.biWidth = 8;
5389 info->bmiHeader.biHeight = 8;
5390 info->bmiHeader.biPlanes = 1;
5391 info->bmiHeader.biBitCount = 32;
5392 info->bmiHeader.biCompression = BI_RGB;
5394 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5395 memset( dib_bits, 0xaa, 64 * 4 );
5396 SelectObject( hdc, dib );
5398 info->bmiHeader.biBitCount = 8;
5399 info->bmiHeader.biCompression = BI_RLE8;
5400 info->bmiHeader.biSizeImage = sizeof(rle8_data);
5402 for (i = 0; i < 256; i++)
5404 info->bmiColors[i].rgbRed = i;
5405 info->bmiColors[i].rgbGreen = i;
5406 info->bmiColors[i].rgbBlue = i;
5407 info->bmiColors[i].rgbReserved = 0;
5410 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5411 ok( ret == 8, "got %d\n", ret );
5412 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5413 memset( dib_bits, 0xaa, 64 * 4 );
5415 /* startscan and lines are ignored, unless lines == 0 */
5416 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 8, rle8_data, info, DIB_RGB_COLORS );
5417 ok( ret == 8, "got %d\n", ret );
5418 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5419 memset( dib_bits, 0xaa, 64 * 4 );
5421 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 1, rle8_data, info, DIB_RGB_COLORS );
5422 ok( ret == 8, "got %d\n", ret );
5423 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5424 memset( dib_bits, 0xaa, 64 * 4 );
5426 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 0, rle8_data, info, DIB_RGB_COLORS );
5427 ok( ret == 0, "got %d\n", ret );
5428 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5429 memset( dib_bits, 0xaa, 64 * 4 );
5431 info->bmiHeader.biWidth = 2;
5432 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5433 ok( ret == 8, "got %d\n", ret );
5434 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5435 memset( dib_bits, 0xaa, 64 * 4 );
5437 info->bmiHeader.biWidth = 8;
5438 info->bmiHeader.biHeight = 2;
5439 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5440 ok( ret == 2, "got %d\n", ret );
5441 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5442 memset( dib_bits, 0xaa, 64 * 4 );
5444 info->bmiHeader.biHeight = 9;
5445 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5446 ok( ret == 9, "got %d\n", ret );
5447 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5448 memset( dib_bits, 0xaa, 64 * 4 );
5450 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5451 ok( ret == 9, "got %d\n", ret );
5452 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5453 memset( dib_bits, 0xaa, 64 * 4 );
5455 info->bmiHeader.biHeight = 8;
5456 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 9, rle8_data, info, DIB_RGB_COLORS );
5457 ok( ret == 8, "got %d\n", ret );
5458 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5459 memset( dib_bits, 0xaa, 64 * 4 );
5461 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5462 ok( ret == 8, "got %d\n", ret );
5463 for (i = 0; i < 40; i++) ok( dib_bits[i] == bottom_up[i + 24], "%d: got %08x\n", i, dib_bits[i] );
5464 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5465 memset( dib_bits, 0xaa, 64 * 4 );
5467 ret = SetDIBitsToDevice( hdc, 0, 3, 4, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5468 ok( ret == 8, "got %d\n", ret );
5469 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5470 for (i = 8; i < 40; i++)
5471 if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5472 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5473 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5474 memset( dib_bits, 0xaa, 64 * 4 );
5476 ret = SetDIBitsToDevice( hdc, 3, 3, 8, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5477 ok( ret == 8, "got %d\n", ret );
5478 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5479 for (i = 8; i < 40; i++)
5480 if ((i & 7) < 3) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5481 else ok( dib_bits[i] == bottom_up[i - 11], "%d: got %08x\n", i, dib_bits[i] );
5482 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5483 memset( dib_bits, 0xaa, 64 * 4 );
5485 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 4, 2, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5486 ok( ret == 8, "got %d\n", ret );
5487 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5488 for (i = 8; i < 40; i++)
5489 if ((i & 7) < 2) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5490 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5491 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5492 memset( dib_bits, 0xaa, 64 * 4 );
5494 info->bmiHeader.biWidth = 37;
5495 info->bmiHeader.biHeight = 37;
5496 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
5497 ok( ret == 37, "got %d\n", ret );
5498 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5499 for (i = 24; i < 64; i++)
5500 if (i == 52) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
5501 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5502 else ok( dib_bits[i] == bottom_up[i - 20], "%d: got %08x\n", i, dib_bits[i] );
5503 memset( dib_bits, 0xaa, 64 * 4 );
5505 /* top-down compressed dibs are invalid */
5506 info->bmiHeader.biWidth = 8;
5507 info->bmiHeader.biHeight = -8;
5508 SetLastError( 0xdeadbeef );
5509 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5510 ok( ret == 0, "got %d\n", ret );
5511 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
5513 /* top-down dst */
5515 info->bmiHeader.biHeight = -8;
5516 info->bmiHeader.biBitCount = 32;
5517 info->bmiHeader.biCompression = BI_RGB;
5518 info->bmiHeader.biSizeImage = 0;
5520 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5521 memset( dib_bits, 0xaa, 16 * 16 * 4 );
5522 DeleteObject( SelectObject( hdc, dib ));
5524 info->bmiHeader.biHeight = 8;
5525 info->bmiHeader.biBitCount = 8;
5526 info->bmiHeader.biCompression = BI_RLE8;
5527 info->bmiHeader.biSizeImage = sizeof(rle8_data);
5529 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5530 ok( ret == 8, "got %d\n", ret );
5531 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5532 memset( dib_bits, 0xaa, 64 * 4 );
5534 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5535 ok( ret == 8, "got %d\n", ret );
5536 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5537 memset( dib_bits, 0xaa, 64 * 4 );
5539 info->bmiHeader.biHeight = 4;
5540 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5541 ok( ret == 4, "got %d\n", ret );
5542 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5543 memset( dib_bits, 0xaa, 64 * 4 );
5545 info->bmiHeader.biHeight = 9;
5546 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5547 ok( ret == 9, "got %d\n", ret );
5548 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5549 memset( dib_bits, 0xaa, 64 * 4 );
5551 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5552 ok( ret == 9, "got %d\n", ret );
5553 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5554 memset( dib_bits, 0xaa, 64 * 4 );
5556 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 6, 2, 2, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5557 ok( ret == 9, "got %d\n", ret );
5558 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5559 for (i = 24; i < 64; i++) ok( dib_bits[i] == top_down[i - 24], "%d: got %08x\n", i, dib_bits[i] );
5560 memset( dib_bits, 0xaa, 64 * 4 );
5562 info->bmiHeader.biWidth = 37;
5563 info->bmiHeader.biHeight = 37;
5564 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
5565 ok( ret == 37, "got %d\n", ret );
5566 for (i = 0; i < 40; i++)
5567 if (i == 12) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
5568 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5569 else ok( dib_bits[i] == top_down[i + 28], "%d: got %08x\n", i, dib_bits[i] );
5570 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5571 memset( dib_bits, 0xaa, 64 * 4 );
5573 DeleteDC( hdc );
5574 DeleteObject( dib );
5575 HeapFree( GetProcessHeap(), 0, info );
5578 START_TEST(bitmap)
5580 HMODULE hdll;
5582 hdll = GetModuleHandle("gdi32.dll");
5583 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
5584 pGdiGradientFill = (void*)GetProcAddress(hdll, "GdiGradientFill");
5585 pSetLayout = (void*)GetProcAddress(hdll, "SetLayout");
5587 test_createdibitmap();
5588 test_dibsections();
5589 test_dib_formats();
5590 test_mono_dibsection();
5591 test_bitmap();
5592 test_mono_bitmap();
5593 test_bmBits();
5594 test_GetDIBits_selected_DIB(1);
5595 test_GetDIBits_selected_DIB(4);
5596 test_GetDIBits_selected_DIB(8);
5597 test_GetDIBits_selected_DDB(TRUE);
5598 test_GetDIBits_selected_DDB(FALSE);
5599 test_GetDIBits();
5600 test_GetDIBits_BI_BITFIELDS();
5601 test_select_object();
5602 test_CreateBitmap();
5603 test_BitBlt();
5604 test_StretchBlt();
5605 test_StretchDIBits();
5606 test_GdiAlphaBlend();
5607 test_GdiGradientFill();
5608 test_32bit_ddb();
5609 test_bitmapinfoheadersize();
5610 test_get16dibits();
5611 test_clipping();
5612 test_GetDIBits_top_down(16);
5613 test_GetDIBits_top_down(24);
5614 test_GetDIBits_top_down(32);
5615 test_GetSetDIBits_rtl();
5616 test_GetDIBits_scanlines();
5617 test_SetDIBits();
5618 test_SetDIBits_RLE4();
5619 test_SetDIBits_RLE8();
5620 test_SetDIBitsToDevice();
5621 test_SetDIBitsToDevice_RLE8();