push 88671f85dcf7a7cd89c63d6e9f34ad6b6ad2ae64
[wine/hacks.git] / dlls / gdi32 / tests / bitmap.c
blobc31d367b0d980647ca00cd217f6d6543455fb77c
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);
37 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
39 static BOOL is_win9x;
41 static INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp )
43 switch(bpp)
45 case 1:
46 return 2 * ((bmWidth+15) >> 4);
48 case 24:
49 bmWidth *= 3; /* fall through */
50 case 8:
51 return bmWidth + (bmWidth & 1);
53 case 32:
54 return bmWidth * 4;
56 case 16:
57 case 15:
58 return bmWidth * 2;
60 case 4:
61 return 2 * ((bmWidth+3) >> 2);
63 default:
64 trace("Unknown depth %d, please report.\n", bpp );
65 assert(0);
67 return -1;
70 static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHEADER *bmih)
72 BITMAP bm;
73 INT ret, width_bytes;
74 char buf[512], buf_cmp[512];
76 ret = GetObject(hbm, sizeof(bm), &bm);
77 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
79 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
80 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
81 ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
82 width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
83 ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
84 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
85 ok(bm.bmBitsPixel == expected_depth, "wrong bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, expected_depth);
86 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
88 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
89 assert(sizeof(buf) == sizeof(buf_cmp));
91 ret = GetBitmapBits(hbm, 0, NULL);
92 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
94 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
95 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
97 memset(buf, 0xAA, sizeof(buf));
98 ret = GetBitmapBits(hbm, sizeof(buf), buf);
99 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
100 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
102 /* test various buffer sizes for GetObject */
103 ret = GetObject(hbm, 0, NULL);
104 ok(ret == sizeof(bm), "wrong size %d\n", ret);
106 ret = GetObject(hbm, sizeof(bm) * 2, &bm);
107 ok(ret == sizeof(bm), "wrong size %d\n", ret);
109 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
110 ok(ret == 0, "%d != 0\n", ret);
112 ret = GetObject(hbm, 0, &bm);
113 ok(ret == 0, "%d != 0\n", ret);
115 ret = GetObject(hbm, 1, &bm);
116 ok(ret == 0, "%d != 0\n", ret);
119 static void test_createdibitmap(void)
121 HDC hdc, hdcmem;
122 BITMAPINFOHEADER bmih;
123 BITMAPINFO bm;
124 HBITMAP hbm, hbm_colour, hbm_old;
125 INT screen_depth;
126 DWORD pixel;
128 hdc = GetDC(0);
129 screen_depth = GetDeviceCaps(hdc, BITSPIXEL);
130 memset(&bmih, 0, sizeof(bmih));
131 bmih.biSize = sizeof(bmih);
132 bmih.biWidth = 10;
133 bmih.biHeight = 10;
134 bmih.biPlanes = 1;
135 bmih.biBitCount = 32;
136 bmih.biCompression = BI_RGB;
138 /* First create an un-initialised bitmap. The depth of the bitmap
139 should match that of the hdc and not that supplied in bmih.
142 /* First try 32 bits */
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 16 */
149 bmih.biBitCount = 16;
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 /* Then 1 */
156 bmih.biBitCount = 1;
157 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
158 ok(hbm != NULL, "CreateDIBitmap failed\n");
159 test_bitmap_info(hbm, screen_depth, &bmih);
160 DeleteObject(hbm);
162 /* Now with a monochrome dc we expect a monochrome bitmap */
163 hdcmem = CreateCompatibleDC(hdc);
165 /* First try 32 bits */
166 bmih.biBitCount = 32;
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 16 */
173 bmih.biBitCount = 16;
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 /* Then 1 */
180 bmih.biBitCount = 1;
181 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
182 ok(hbm != NULL, "CreateDIBitmap failed\n");
183 test_bitmap_info(hbm, 1, &bmih);
184 DeleteObject(hbm);
186 /* Now select a polychrome bitmap into the dc and we expect
187 screen_depth bitmaps again */
188 hbm_colour = CreateCompatibleBitmap(hdc, bmih.biWidth, bmih.biHeight);
189 test_bitmap_info(hbm_colour, screen_depth, &bmih);
190 hbm_old = SelectObject(hdcmem, hbm_colour);
192 /* First try 32 bits */
193 bmih.biBitCount = 32;
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 16 */
200 bmih.biBitCount = 16;
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 /* Then 1 */
207 bmih.biBitCount = 1;
208 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
209 ok(hbm != NULL, "CreateDIBitmap failed\n");
210 test_bitmap_info(hbm, screen_depth, &bmih);
211 DeleteObject(hbm);
213 SelectObject(hdcmem, hbm_old);
214 DeleteObject(hbm_colour);
215 DeleteDC(hdcmem);
217 /* If hdc == 0 then we get a 1 bpp bitmap */
218 if (!is_win9x) {
219 bmih.biBitCount = 32;
220 hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0);
221 ok(hbm != NULL, "CreateDIBitmap failed\n");
222 test_bitmap_info(hbm, 1, &bmih);
223 DeleteObject(hbm);
226 /* Test how formats are converted */
227 pixel = 0xffffffff;
228 bmih.biBitCount = 1;
229 bmih.biWidth = 1;
230 bmih.biHeight = 1;
232 memset(&bm, 0, sizeof(bm));
233 bm.bmiHeader.biSize = sizeof(bm.bmiHeader);
234 bm.bmiHeader.biWidth = 1;
235 bm.bmiHeader.biHeight = 1;
236 bm.bmiHeader.biPlanes = 1;
237 bm.bmiHeader.biBitCount= 24;
238 bm.bmiHeader.biCompression= BI_RGB;
239 bm.bmiHeader.biSizeImage = 0;
240 hbm = CreateDIBitmap(hdc, &bmih, CBM_INIT, &pixel, &bm, DIB_RGB_COLORS);
241 ok(hbm != NULL, "CreateDIBitmap failed\n");
243 pixel = 0xdeadbeef;
244 bm.bmiHeader.biBitCount= 32;
245 GetDIBits(hdc, hbm, 0, 1, &pixel, &bm, DIB_RGB_COLORS);
246 ok(pixel == 0x00ffffff, "Reading a 32 bit pixel from a DDB returned %08x\n", pixel);
247 DeleteObject(hbm);
249 ReleaseDC(0, hdc);
252 static INT DIB_GetWidthBytes( int width, int bpp )
254 int words;
256 switch (bpp)
258 case 1: words = (width + 31) / 32; break;
259 case 4: words = (width + 7) / 8; break;
260 case 8: words = (width + 3) / 4; break;
261 case 15:
262 case 16: words = (width + 1) / 2; break;
263 case 24: words = (width * 3 + 3)/4; break;
264 case 32: words = width; break;
266 default:
267 words=0;
268 trace("Unknown depth %d, please report.\n", bpp );
269 assert(0);
270 break;
272 return 4 * words;
275 static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
277 BITMAP bm;
278 DIBSECTION ds;
279 INT ret, width_bytes;
280 BYTE *buf;
282 ret = GetObject(hbm, sizeof(bm), &bm);
283 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
285 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
286 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
287 ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
288 width_bytes = DIB_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
289 ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
290 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
291 ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount);
292 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
294 buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);
296 width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
298 /* GetBitmapBits returns not 32-bit aligned data */
299 ret = GetBitmapBits(hbm, 0, NULL);
300 ok(ret == width_bytes * bm.bmHeight, "%d != %d\n", ret, width_bytes * bm.bmHeight);
302 memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
303 ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
304 ok(ret == width_bytes * bm.bmHeight, "%d != %d\n", ret, width_bytes * bm.bmHeight);
306 HeapFree(GetProcessHeap(), 0, buf);
308 /* test various buffer sizes for GetObject */
309 memset(&ds, 0xAA, sizeof(ds));
310 ret = GetObject(hbm, sizeof(bm) * 2, &bm);
311 ok(ret == sizeof(bm), "wrong size %d\n", ret);
312 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
313 ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
314 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
316 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
317 ok(ret == 0, "%d != 0\n", ret);
319 ret = GetObject(hbm, 0, &bm);
320 ok(ret == 0, "%d != 0\n", ret);
322 ret = GetObject(hbm, 1, &bm);
323 ok(ret == 0, "%d != 0\n", ret);
325 /* test various buffer sizes for GetObject */
326 ret = GetObject(hbm, 0, NULL);
327 ok(ret == sizeof(bm), "wrong size %d\n", ret);
329 memset(&ds, 0xAA, sizeof(ds));
330 ret = GetObject(hbm, sizeof(ds) * 2, &ds);
331 ok(ret == sizeof(ds), "wrong size %d\n", ret);
333 ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
334 ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%u != %u\n",
335 ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
336 ok(bmih->biSizeImage == 0, "%u != 0\n", bmih->biSizeImage);
337 ds.dsBmih.biSizeImage = 0;
339 ok(ds.dsBmih.biSize == bmih->biSize, "%u != %u\n", ds.dsBmih.biSize, bmih->biSize);
340 ok(ds.dsBmih.biWidth == bmih->biWidth, "%u != %u\n", ds.dsBmih.biWidth, bmih->biWidth);
341 ok(ds.dsBmih.biHeight == bmih->biHeight, "%u != %u\n", ds.dsBmih.biHeight, bmih->biHeight);
342 ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes);
343 ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount);
344 ok(ds.dsBmih.biCompression == bmih->biCompression, "%u != %u\n", ds.dsBmih.biCompression, bmih->biCompression);
345 ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%u != %u\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
346 ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%u != %u\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
347 ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%u != %u\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);
349 memset(&ds, 0xAA, sizeof(ds));
350 ret = GetObject(hbm, sizeof(ds) - 4, &ds);
351 ok(ret == sizeof(ds.dsBm), "wrong size %d\n", ret);
352 ok(ds.dsBm.bmWidth == bmih->biWidth, "%u != %u\n", ds.dsBmih.biWidth, bmih->biWidth);
353 ok(ds.dsBm.bmHeight == bmih->biHeight, "%u != %u\n", ds.dsBmih.biHeight, bmih->biHeight);
354 ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);
356 ret = GetObject(hbm, 0, &ds);
357 ok(ret == 0, "%d != 0\n", ret);
359 ret = GetObject(hbm, 1, &ds);
360 ok(ret == 0, "%d != 0\n", ret);
363 #define test_color_todo(got, exp, txt, todo) \
364 if (!todo && got != exp && screen_depth < 24) { \
365 todo_wine ok(0, #txt " failed at %d-bit screen depth: got 0x%06x expected 0x%06x - skipping DIB tests\n", \
366 screen_depth, (UINT)got, (UINT)exp); \
367 return; \
368 } else if (todo) todo_wine { ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp); } \
369 else ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp) \
371 #define test_color(hdc, color, exp, todo_setp, todo_getp) \
373 COLORREF c; \
374 c = SetPixel(hdc, 0, 0, color); \
375 if (!is_win9x) { test_color_todo(c, exp, SetPixel, todo_setp); } \
376 c = GetPixel(hdc, 0, 0); \
377 test_color_todo(c, exp, GetPixel, todo_getp); \
380 static void test_dibsections(void)
382 HDC hdc, hdcmem, hdcmem2;
383 HBITMAP hdib, oldbm, hdib2, oldbm2;
384 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
385 char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
386 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
387 BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
388 HBITMAP hcoredib;
389 char coreBits[256];
390 BYTE *bits;
391 RGBQUAD rgb[256];
392 int ret;
393 char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
394 LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
395 WORD *index;
396 DWORD *bits32;
397 HPALETTE hpal, oldpal;
398 DIBSECTION dibsec;
399 COLORREF c0, c1;
400 int i;
401 int screen_depth;
402 MEMORY_BASIC_INFORMATION info;
404 hdc = GetDC(0);
405 screen_depth = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
407 memset(pbmi, 0, sizeof(bmibuf));
408 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
409 pbmi->bmiHeader.biHeight = 100;
410 pbmi->bmiHeader.biWidth = 512;
411 pbmi->bmiHeader.biBitCount = 24;
412 pbmi->bmiHeader.biPlanes = 1;
413 pbmi->bmiHeader.biCompression = BI_RGB;
415 SetLastError(0xdeadbeef);
416 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
417 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
418 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
419 ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
421 /* test the DIB memory */
422 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
423 "VirtualQuery failed\n");
424 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
425 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
426 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
427 ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
428 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
429 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
430 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
432 test_dib_info(hdib, bits, &pbmi->bmiHeader);
433 DeleteObject(hdib);
435 pbmi->bmiHeader.biBitCount = 8;
436 pbmi->bmiHeader.biCompression = BI_RLE8;
437 SetLastError(0xdeadbeef);
438 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
439 ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
440 ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
442 pbmi->bmiHeader.biBitCount = 16;
443 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
444 ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
445 ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
446 ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
447 SetLastError(0xdeadbeef);
448 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
449 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
451 /* test the DIB memory */
452 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
453 "VirtualQuery failed\n");
454 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
455 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
456 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
457 ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
458 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
459 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
460 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
462 test_dib_info(hdib, bits, &pbmi->bmiHeader);
463 DeleteObject(hdib);
465 memset(pbmi, 0, sizeof(bmibuf));
466 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
467 pbmi->bmiHeader.biHeight = 16;
468 pbmi->bmiHeader.biWidth = 16;
469 pbmi->bmiHeader.biBitCount = 1;
470 pbmi->bmiHeader.biPlanes = 1;
471 pbmi->bmiHeader.biCompression = BI_RGB;
472 pbmi->bmiColors[0].rgbRed = 0xff;
473 pbmi->bmiColors[0].rgbGreen = 0;
474 pbmi->bmiColors[0].rgbBlue = 0;
475 pbmi->bmiColors[1].rgbRed = 0;
476 pbmi->bmiColors[1].rgbGreen = 0;
477 pbmi->bmiColors[1].rgbBlue = 0xff;
479 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
480 ok(hdib != NULL, "CreateDIBSection failed\n");
481 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
482 ok(dibsec.dsBmih.biClrUsed == 2,
483 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
485 /* Test if the old BITMAPCOREINFO structure is supported */
487 pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
488 pbci->bmciHeader.bcBitCount = 0;
490 if (!is_win9x) {
491 ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
492 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
493 ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
494 && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
495 "GetDIBits did't fill in the BITMAPCOREHEADER structure properly\n");
497 ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
498 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
499 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
500 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
501 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
502 "The color table has not been translated to the old BITMAPCOREINFO format\n");
504 hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
505 ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
507 ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
508 ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
509 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
510 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
511 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
512 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
513 "The color table has not been translated to the old BITMAPCOREINFO format\n");
515 DeleteObject(hcoredib);
518 hdcmem = CreateCompatibleDC(hdc);
519 oldbm = SelectObject(hdcmem, hdib);
521 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
522 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
523 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
524 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
525 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
526 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
528 c0 = RGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen, pbmi->bmiColors[0].rgbBlue);
529 c1 = RGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen, pbmi->bmiColors[1].rgbBlue);
531 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
532 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
533 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
534 test_color(hdcmem, PALETTEINDEX(0), c0, 1, 1);
535 test_color(hdcmem, PALETTEINDEX(1), c0, 1, 1);
536 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
537 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen,
538 pbmi->bmiColors[0].rgbBlue), c0, 1, 1);
539 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen,
540 pbmi->bmiColors[1].rgbBlue), c1, 1, 1);
541 test_color(hdcmem, PALETTERGB(0, 0, 0), c0, 1, 1);
542 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
543 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1, 1, 1);
545 SelectObject(hdcmem, oldbm);
546 DeleteObject(hdib);
548 pbmi->bmiColors[0].rgbRed = 0xff;
549 pbmi->bmiColors[0].rgbGreen = 0xff;
550 pbmi->bmiColors[0].rgbBlue = 0xff;
551 pbmi->bmiColors[1].rgbRed = 0;
552 pbmi->bmiColors[1].rgbGreen = 0;
553 pbmi->bmiColors[1].rgbBlue = 0;
555 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
556 ok(hdib != NULL, "CreateDIBSection failed\n");
558 test_dib_info(hdib, bits, &pbmi->bmiHeader);
560 oldbm = SelectObject(hdcmem, hdib);
562 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
563 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
564 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
565 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
566 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
567 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
569 SelectObject(hdcmem, oldbm);
570 test_dib_info(hdib, bits, &pbmi->bmiHeader);
571 DeleteObject(hdib);
573 pbmi->bmiHeader.biBitCount = 4;
574 for (i = 0; i < 16; i++) {
575 pbmi->bmiColors[i].rgbRed = i;
576 pbmi->bmiColors[i].rgbGreen = 16-i;
577 pbmi->bmiColors[i].rgbBlue = 0;
579 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
580 ok(hdib != NULL, "CreateDIBSection failed\n");
581 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
582 ok(dibsec.dsBmih.biClrUsed == 16,
583 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
584 test_dib_info(hdib, bits, &pbmi->bmiHeader);
585 DeleteObject(hdib);
587 pbmi->bmiHeader.biBitCount = 8;
589 for (i = 0; i < 128; i++) {
590 pbmi->bmiColors[i].rgbRed = 255 - i * 2;
591 pbmi->bmiColors[i].rgbGreen = i * 2;
592 pbmi->bmiColors[i].rgbBlue = 0;
593 pbmi->bmiColors[255 - i].rgbRed = 0;
594 pbmi->bmiColors[255 - i].rgbGreen = i * 2;
595 pbmi->bmiColors[255 - i].rgbBlue = 255 - i * 2;
597 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
598 ok(hdib != NULL, "CreateDIBSection failed\n");
599 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
600 ok(dibsec.dsBmih.biClrUsed == 256,
601 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
603 oldbm = SelectObject(hdcmem, hdib);
605 for (i = 0; i < 256; i++) {
606 test_color(hdcmem, DIBINDEX(i),
607 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
608 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue),
609 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
612 SelectObject(hdcmem, oldbm);
613 test_dib_info(hdib, bits, &pbmi->bmiHeader);
614 DeleteObject(hdib);
616 pbmi->bmiHeader.biBitCount = 1;
618 /* Now create a palette and a palette indexed dib section */
619 memset(plogpal, 0, sizeof(logpalbuf));
620 plogpal->palVersion = 0x300;
621 plogpal->palNumEntries = 2;
622 plogpal->palPalEntry[0].peRed = 0xff;
623 plogpal->palPalEntry[0].peBlue = 0xff;
624 plogpal->palPalEntry[1].peGreen = 0xff;
626 index = (WORD*)pbmi->bmiColors;
627 *index++ = 0;
628 *index = 1;
629 hpal = CreatePalette(plogpal);
630 ok(hpal != NULL, "CreatePalette failed\n");
631 oldpal = SelectPalette(hdc, hpal, TRUE);
632 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
633 ok(hdib != NULL, "CreateDIBSection failed\n");
634 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
635 ok(dibsec.dsBmih.biClrUsed == 2,
636 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
638 /* The colour table has already been grabbed from the dc, so we select back the
639 old palette */
641 SelectPalette(hdc, oldpal, TRUE);
642 oldbm = SelectObject(hdcmem, hdib);
643 oldpal = SelectPalette(hdcmem, hpal, TRUE);
645 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
646 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
647 ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
648 rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
649 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
650 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
651 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
653 c0 = RGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen, plogpal->palPalEntry[0].peBlue);
654 c1 = RGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen, plogpal->palPalEntry[1].peBlue);
656 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
657 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
658 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
659 test_color(hdcmem, PALETTEINDEX(0), c0, 0, 1);
660 test_color(hdcmem, PALETTEINDEX(1), c1, 0, 1);
661 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
662 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen,
663 plogpal->palPalEntry[0].peBlue), c0, 1, 1);
664 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen,
665 plogpal->palPalEntry[1].peBlue), c1, 1, 1);
666 test_color(hdcmem, PALETTERGB(0, 0, 0), c1, 1, 1);
667 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
668 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0, 1, 1);
669 test_color(hdcmem, PALETTERGB(0, 1, 0), c1, 1, 1);
670 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1, 1, 1);
671 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0, 1, 1);
673 /* Bottom and 2nd row from top green, everything else magenta */
674 bits[0] = bits[1] = 0xff;
675 bits[13 * 4] = bits[13*4 + 1] = 0xff;
677 test_dib_info(hdib, bits, &pbmi->bmiHeader);
679 pbmi->bmiHeader.biBitCount = 32;
681 hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
682 ok(hdib2 != NULL, "CreateDIBSection failed\n");
683 hdcmem2 = CreateCompatibleDC(hdc);
684 oldbm2 = SelectObject(hdcmem2, hdib2);
686 BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
688 ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
689 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
691 SelectObject(hdcmem2, oldbm2);
692 test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
693 DeleteObject(hdib2);
695 SelectObject(hdcmem, oldbm);
696 SelectObject(hdcmem, oldpal);
697 DeleteObject(hdib);
698 DeleteObject(hpal);
701 pbmi->bmiHeader.biBitCount = 8;
703 memset(plogpal, 0, sizeof(logpalbuf));
704 plogpal->palVersion = 0x300;
705 plogpal->palNumEntries = 256;
707 for (i = 0; i < 128; i++) {
708 plogpal->palPalEntry[i].peRed = 255 - i * 2;
709 plogpal->palPalEntry[i].peBlue = i * 2;
710 plogpal->palPalEntry[i].peGreen = 0;
711 plogpal->palPalEntry[255 - i].peRed = 0;
712 plogpal->palPalEntry[255 - i].peGreen = i * 2;
713 plogpal->palPalEntry[255 - i].peBlue = 255 - i * 2;
716 index = (WORD*)pbmi->bmiColors;
717 for (i = 0; i < 256; i++) {
718 *index++ = i;
721 hpal = CreatePalette(plogpal);
722 ok(hpal != NULL, "CreatePalette failed\n");
723 oldpal = SelectPalette(hdc, hpal, TRUE);
724 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
725 ok(hdib != NULL, "CreateDIBSection failed\n");
726 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
727 ok(dibsec.dsBmih.biClrUsed == 256,
728 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
730 test_dib_info(hdib, bits, &pbmi->bmiHeader);
732 SelectPalette(hdc, oldpal, TRUE);
733 oldbm = SelectObject(hdcmem, hdib);
734 oldpal = SelectPalette(hdcmem, hpal, TRUE);
736 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
737 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
738 for (i = 0; i < 256; i++) {
739 ok(rgb[i].rgbRed == plogpal->palPalEntry[i].peRed &&
740 rgb[i].rgbBlue == plogpal->palPalEntry[i].peBlue &&
741 rgb[i].rgbGreen == plogpal->palPalEntry[i].peGreen,
742 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
743 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
746 for (i = 0; i < 256; i++) {
747 test_color(hdcmem, DIBINDEX(i),
748 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
749 test_color(hdcmem, PALETTEINDEX(i),
750 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
751 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue),
752 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
755 SelectPalette(hdcmem, oldpal, TRUE);
756 SelectObject(hdcmem, oldbm);
757 DeleteObject(hdib);
758 DeleteObject(hpal);
761 DeleteDC(hdcmem);
762 ReleaseDC(0, hdc);
765 static void test_mono_dibsection(void)
767 HDC hdc, memdc;
768 HBITMAP old_bm, mono_ds;
769 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
770 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
771 BYTE bits[10 * 4];
772 BYTE *ds_bits;
773 int num;
775 hdc = GetDC(0);
777 memdc = CreateCompatibleDC(hdc);
779 memset(pbmi, 0, sizeof(bmibuf));
780 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
781 pbmi->bmiHeader.biHeight = 10;
782 pbmi->bmiHeader.biWidth = 10;
783 pbmi->bmiHeader.biBitCount = 1;
784 pbmi->bmiHeader.biPlanes = 1;
785 pbmi->bmiHeader.biCompression = BI_RGB;
786 pbmi->bmiColors[0].rgbRed = 0xff;
787 pbmi->bmiColors[0].rgbGreen = 0xff;
788 pbmi->bmiColors[0].rgbBlue = 0xff;
789 pbmi->bmiColors[1].rgbRed = 0x0;
790 pbmi->bmiColors[1].rgbGreen = 0x0;
791 pbmi->bmiColors[1].rgbBlue = 0x0;
794 * First dib section is 'inverted' ie color[0] is white, color[1] is black
797 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
798 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
799 old_bm = SelectObject(memdc, mono_ds);
801 /* black border, white interior */
802 Rectangle(memdc, 0, 0, 10, 10);
803 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
804 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
806 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
808 memset(bits, 0, sizeof(bits));
809 bits[0] = 0xaa;
811 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
812 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
814 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
816 pbmi->bmiColors[0].rgbRed = 0x0;
817 pbmi->bmiColors[0].rgbGreen = 0x0;
818 pbmi->bmiColors[0].rgbBlue = 0x0;
819 pbmi->bmiColors[1].rgbRed = 0xff;
820 pbmi->bmiColors[1].rgbGreen = 0xff;
821 pbmi->bmiColors[1].rgbBlue = 0xff;
823 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
824 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
826 SelectObject(memdc, old_bm);
827 DeleteObject(mono_ds);
830 * Next dib section is 'normal' ie color[0] is black, color[1] is white
833 pbmi->bmiColors[0].rgbRed = 0x0;
834 pbmi->bmiColors[0].rgbGreen = 0x0;
835 pbmi->bmiColors[0].rgbBlue = 0x0;
836 pbmi->bmiColors[1].rgbRed = 0xff;
837 pbmi->bmiColors[1].rgbGreen = 0xff;
838 pbmi->bmiColors[1].rgbBlue = 0xff;
840 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
841 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
842 old_bm = SelectObject(memdc, mono_ds);
844 /* black border, white interior */
845 Rectangle(memdc, 0, 0, 10, 10);
846 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
847 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
849 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
851 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
852 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
854 /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
856 pbmi->bmiColors[0].rgbRed = 0xff;
857 pbmi->bmiColors[0].rgbGreen = 0xff;
858 pbmi->bmiColors[0].rgbBlue = 0xff;
859 pbmi->bmiColors[1].rgbRed = 0x0;
860 pbmi->bmiColors[1].rgbGreen = 0x0;
861 pbmi->bmiColors[1].rgbBlue = 0x0;
863 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
864 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
867 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
870 pbmi->bmiColors[0].rgbRed = 0xff;
871 pbmi->bmiColors[0].rgbGreen = 0xff;
872 pbmi->bmiColors[0].rgbBlue = 0xff;
873 pbmi->bmiColors[1].rgbRed = 0x0;
874 pbmi->bmiColors[1].rgbGreen = 0x0;
875 pbmi->bmiColors[1].rgbBlue = 0x0;
876 num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors);
877 ok(num == 2, "num = %d\n", num);
879 /* black border, white interior */
880 Rectangle(memdc, 0, 0, 10, 10);
881 todo_wine {
882 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
883 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
885 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
887 memset(bits, 0, sizeof(bits));
888 bits[0] = 0xaa;
890 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
891 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
893 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
895 pbmi->bmiColors[0].rgbRed = 0x0;
896 pbmi->bmiColors[0].rgbGreen = 0x0;
897 pbmi->bmiColors[0].rgbBlue = 0x0;
898 pbmi->bmiColors[1].rgbRed = 0xff;
899 pbmi->bmiColors[1].rgbGreen = 0xff;
900 pbmi->bmiColors[1].rgbBlue = 0xff;
902 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
903 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
905 SelectObject(memdc, old_bm);
906 DeleteObject(mono_ds);
909 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
912 pbmi->bmiColors[0].rgbRed = 0xff;
913 pbmi->bmiColors[0].rgbGreen = 0x0;
914 pbmi->bmiColors[0].rgbBlue = 0x0;
915 pbmi->bmiColors[1].rgbRed = 0xfe;
916 pbmi->bmiColors[1].rgbGreen = 0x0;
917 pbmi->bmiColors[1].rgbBlue = 0x0;
919 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
920 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
921 old_bm = SelectObject(memdc, mono_ds);
923 /* black border, white interior */
924 Rectangle(memdc, 0, 0, 10, 10);
925 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
926 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
928 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
930 pbmi->bmiColors[0].rgbRed = 0x0;
931 pbmi->bmiColors[0].rgbGreen = 0x0;
932 pbmi->bmiColors[0].rgbBlue = 0x0;
933 pbmi->bmiColors[1].rgbRed = 0xff;
934 pbmi->bmiColors[1].rgbGreen = 0xff;
935 pbmi->bmiColors[1].rgbBlue = 0xff;
937 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
938 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
940 /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
942 pbmi->bmiColors[0].rgbRed = 0xff;
943 pbmi->bmiColors[0].rgbGreen = 0xff;
944 pbmi->bmiColors[0].rgbBlue = 0xff;
945 pbmi->bmiColors[1].rgbRed = 0x0;
946 pbmi->bmiColors[1].rgbGreen = 0x0;
947 pbmi->bmiColors[1].rgbBlue = 0x0;
949 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
950 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
952 SelectObject(memdc, old_bm);
953 DeleteObject(mono_ds);
955 DeleteDC(memdc);
956 ReleaseDC(0, hdc);
959 static void test_bitmap(void)
961 char buf[256], buf_cmp[256];
962 HBITMAP hbmp, hbmp_old;
963 HDC hdc;
964 BITMAP bm;
965 INT ret;
967 hdc = CreateCompatibleDC(0);
968 assert(hdc != 0);
970 SetLastError(0xdeadbeef);
971 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
972 ok(hbmp != 0, "CreateBitmap should not fail\n");
973 DeleteObject(hbmp);
975 SetLastError(0xdeadbeef);
976 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
977 ok(!hbmp, "CreateBitmap should fail\n");
978 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY,
979 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
981 SetLastError(0xdeadbeef);
982 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
983 ok(!hbmp, "CreateBitmap should fail\n");
984 ok(GetLastError() == ERROR_INVALID_PARAMETER,
985 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
987 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
988 assert(hbmp != NULL);
990 ret = GetObject(hbmp, sizeof(bm), &bm);
991 ok(ret == sizeof(bm), "wrong size %d\n", ret);
993 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
994 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
995 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
996 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
997 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
998 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
999 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1001 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1002 assert(sizeof(buf) == sizeof(buf_cmp));
1004 ret = GetBitmapBits(hbmp, 0, NULL);
1005 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1007 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1008 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1010 memset(buf, 0xAA, sizeof(buf));
1011 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1012 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1013 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1015 hbmp_old = SelectObject(hdc, hbmp);
1017 ret = GetObject(hbmp, sizeof(bm), &bm);
1018 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1020 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1021 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1022 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1023 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1024 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1025 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1026 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1028 memset(buf, 0xAA, sizeof(buf));
1029 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1030 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1031 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1033 hbmp_old = SelectObject(hdc, hbmp_old);
1034 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1036 /* test various buffer sizes for GetObject */
1037 ret = GetObject(hbmp, sizeof(bm) * 2, &bm);
1038 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1040 ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1041 ok(ret == 0, "%d != 0\n", ret);
1043 ret = GetObject(hbmp, 0, &bm);
1044 ok(ret == 0, "%d != 0\n", ret);
1046 ret = GetObject(hbmp, 1, &bm);
1047 ok(ret == 0, "%d != 0\n", ret);
1049 DeleteObject(hbmp);
1050 DeleteDC(hdc);
1053 static void test_bmBits(void)
1055 BYTE bits[4];
1056 HBITMAP hbmp;
1057 BITMAP bmp;
1059 memset(bits, 0, sizeof(bits));
1060 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1061 ok(hbmp != NULL, "CreateBitmap failed\n");
1063 memset(&bmp, 0xFF, sizeof(bmp));
1064 ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1065 "GetObject failed or returned a wrong structure size\n");
1066 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1068 DeleteObject(hbmp);
1071 static void test_GetDIBits_selected_DIB(UINT bpp)
1073 HBITMAP dib;
1074 BITMAPINFO * info;
1075 BITMAPINFO * info2;
1076 void * bits;
1077 void * bits2;
1078 UINT dib_size;
1079 HDC dib_dc, dc;
1080 HBITMAP old_bmp;
1081 BOOL equalContents;
1082 UINT i;
1083 int res;
1085 /* Create a DIB section with a color table */
1087 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD));
1088 info2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD));
1089 assert(info);
1090 assert(info2);
1092 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1094 /* Choose width and height such that the row length (in bytes)
1095 is a multiple of 4 (makes things easier) */
1096 info->bmiHeader.biWidth = 32;
1097 info->bmiHeader.biHeight = 32;
1098 info->bmiHeader.biPlanes = 1;
1099 info->bmiHeader.biBitCount = bpp;
1100 info->bmiHeader.biCompression = BI_RGB;
1102 for (i=0; i < (1u << bpp); i++)
1104 BYTE c = i * (1 << (8 - bpp));
1105 info->bmiColors[i].rgbRed = c;
1106 info->bmiColors[i].rgbGreen = c;
1107 info->bmiColors[i].rgbBlue = c;
1108 info->bmiColors[i].rgbReserved = 0;
1111 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1112 assert(dib);
1113 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1115 /* Set the bits of the DIB section */
1116 for (i=0; i < dib_size; i++)
1118 ((BYTE *)bits)[i] = i % 256;
1121 /* Select the DIB into a DC */
1122 dib_dc = CreateCompatibleDC(NULL);
1123 old_bmp = (HBITMAP) SelectObject(dib_dc, dib);
1124 dc = CreateCompatibleDC(NULL);
1125 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib_size);
1126 assert(bits2);
1128 /* Copy the DIB attributes but not the color table */
1129 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1131 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1132 ok(res, "GetDIBits failed\n");
1134 /* Compare the color table and the bits */
1135 equalContents = TRUE;
1136 for (i=0; i < (1u << bpp); i++)
1138 if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed)
1139 || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen)
1140 || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue)
1141 || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved))
1143 equalContents = FALSE;
1144 break;
1147 ok(equalContents, "GetDIBits with DIB selected in DC: Invalid DIB color table\n");
1149 equalContents = TRUE;
1150 for (i=0; i < dib_size / sizeof(DWORD); i++)
1152 if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i])
1154 equalContents = FALSE;
1155 break;
1158 if (bpp != 1)
1159 ok(equalContents, "GetDIBits with %d bpp DIB selected in DC: Invalid DIB bits\n",bpp);
1160 else
1161 todo_wine ok(equalContents, "GetDIBits with %d bpp DIB selected in DC: Invalid DIB bits\n",bpp);
1163 HeapFree(GetProcessHeap(), 0, bits2);
1164 DeleteDC(dc);
1166 SelectObject(dib_dc, old_bmp);
1167 DeleteDC(dib_dc);
1168 DeleteObject(dib);
1170 HeapFree(GetProcessHeap(), 0, info2);
1171 HeapFree(GetProcessHeap(), 0, info);
1174 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1176 HBITMAP ddb;
1177 BITMAPINFO * info;
1178 BITMAPINFO * info2;
1179 void * bits;
1180 void * bits2;
1181 HDC ddb_dc, dc;
1182 HBITMAP old_bmp;
1183 BOOL equalContents;
1184 UINT width, height;
1185 UINT bpp;
1186 UINT i, j;
1187 int res;
1189 width = height = 16;
1191 /* Create a DDB (device-dependent bitmap) */
1192 if (monochrome)
1194 bpp = 1;
1195 ddb = CreateBitmap(width, height, 1, 1, NULL);
1197 else
1199 HDC screen_dc = GetDC(NULL);
1200 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1201 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1202 ReleaseDC(NULL, screen_dc);
1205 /* Set the pixels */
1206 ddb_dc = CreateCompatibleDC(NULL);
1207 old_bmp = (HBITMAP) SelectObject(ddb_dc, ddb);
1208 for (i = 0; i < width; i++)
1210 for (j=0; j < height; j++)
1212 BYTE c = (i * width + j) % 256;
1213 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1216 SelectObject(ddb_dc, old_bmp);
1218 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1219 info2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1220 assert(info);
1221 assert(info2);
1223 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1224 info->bmiHeader.biWidth = width;
1225 info->bmiHeader.biHeight = height;
1226 info->bmiHeader.biPlanes = 1;
1227 info->bmiHeader.biBitCount = bpp;
1228 info->bmiHeader.biCompression = BI_RGB;
1230 dc = CreateCompatibleDC(NULL);
1232 /* Fill in biSizeImage */
1233 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1234 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1236 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1237 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1238 assert(bits);
1239 assert(bits2);
1241 /* Get the bits */
1242 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1243 ok(res, "GetDIBits failed\n");
1245 /* Copy the DIB attributes but not the color table */
1246 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1248 /* Select the DDB into another DC */
1249 old_bmp = (HBITMAP) SelectObject(ddb_dc, ddb);
1251 /* Get the bits */
1252 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1253 ok(res, "GetDIBits failed\n");
1255 /* Compare the color table and the bits */
1256 if (bpp <= 8)
1258 equalContents = TRUE;
1259 for (i=0; i < (1u << bpp); i++)
1261 if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed)
1262 || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen)
1263 || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue)
1264 || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved))
1266 equalContents = FALSE;
1267 break;
1270 ok(equalContents, "GetDIBits with DDB selected in DC: Got a different color table\n");
1273 equalContents = TRUE;
1274 for (i=0; i < info->bmiHeader.biSizeImage / sizeof(DWORD); i++)
1276 if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i])
1278 equalContents = FALSE;
1281 ok(equalContents, "GetDIBits with DDB selected in DC: Got different DIB bits\n");
1283 HeapFree(GetProcessHeap(), 0, bits2);
1284 HeapFree(GetProcessHeap(), 0, bits);
1285 DeleteDC(dc);
1287 SelectObject(ddb_dc, old_bmp);
1288 DeleteDC(ddb_dc);
1289 DeleteObject(ddb);
1291 HeapFree(GetProcessHeap(), 0, info2);
1292 HeapFree(GetProcessHeap(), 0, info);
1295 static void test_GetDIBits(void)
1297 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1298 static const BYTE bmp_bits_1[16 * 2] =
1300 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1301 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1302 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1303 0xff,0xff, 0,0, 0xff,0xff, 0,0
1305 /* 4-bytes aligned 1-bit DIB data: 16x16 */
1306 static const BYTE dib_bits_1[16 * 4] =
1308 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1309 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1310 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1311 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1313 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1314 static const BYTE bmp_bits_24[16 * 16*3] =
1316 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1317 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1318 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1319 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1320 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1321 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1322 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1323 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1324 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1325 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1326 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1327 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1328 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1329 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1330 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1331 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1332 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1333 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1334 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1335 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1336 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1337 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1338 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1339 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1340 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1341 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1342 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1343 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1344 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1345 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1346 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1347 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1349 /* 4-bytes aligned 24-bit DIB data: 16x16 */
1350 static const BYTE dib_bits_24[16 * 16*3] =
1352 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1353 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1354 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1355 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1356 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1357 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1358 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1359 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1360 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1361 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1362 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1363 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1364 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1365 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1366 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1367 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1368 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1369 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1370 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1371 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1372 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1373 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1374 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1375 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1376 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1377 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1378 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1379 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1380 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1381 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1382 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1383 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1385 HBITMAP hbmp;
1386 BITMAP bm;
1387 HDC hdc;
1388 int i, bytes, lines;
1389 BYTE buf[1024];
1390 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1391 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1393 hdc = GetDC(0);
1395 /* 1-bit source bitmap data */
1396 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1397 ok(hbmp != 0, "CreateBitmap failed\n");
1399 memset(&bm, 0xAA, sizeof(bm));
1400 bytes = GetObject(hbmp, sizeof(bm), &bm);
1401 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1402 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1403 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1404 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1405 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1406 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1407 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1408 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1410 bytes = GetBitmapBits(hbmp, 0, NULL);
1411 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1412 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1413 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1414 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1416 /* retrieve 1-bit DIB data */
1417 memset(bi, 0, sizeof(*bi));
1418 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1419 bi->bmiHeader.biWidth = bm.bmWidth;
1420 bi->bmiHeader.biHeight = bm.bmHeight;
1421 bi->bmiHeader.biPlanes = 1;
1422 bi->bmiHeader.biBitCount = 1;
1423 bi->bmiHeader.biCompression = BI_RGB;
1424 bi->bmiHeader.biSizeImage = 0;
1425 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1426 SetLastError(0xdeadbeef);
1427 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1428 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1429 ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
1430 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1432 memset(buf, 0xAA, sizeof(buf));
1433 SetLastError(0xdeadbeef);
1434 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1435 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1436 lines, bm.bmHeight, GetLastError());
1437 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1439 /* the color table consists of black and white */
1440 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1441 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1442 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1443 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1444 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1445 todo_wine
1446 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1447 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1448 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1449 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1450 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1451 for (i = 2; i < 256; i++)
1453 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1454 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1455 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1456 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1457 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1460 /* returned bits are DWORD aligned and upside down */
1461 todo_wine
1462 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1464 /* retrieve 24-bit DIB data */
1465 memset(bi, 0, sizeof(*bi));
1466 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1467 bi->bmiHeader.biWidth = bm.bmWidth;
1468 bi->bmiHeader.biHeight = bm.bmHeight;
1469 bi->bmiHeader.biPlanes = 1;
1470 bi->bmiHeader.biBitCount = 24;
1471 bi->bmiHeader.biCompression = BI_RGB;
1472 bi->bmiHeader.biSizeImage = 0;
1473 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1474 memset(buf, 0xAA, sizeof(buf));
1475 SetLastError(0xdeadbeef);
1476 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1477 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1478 lines, bm.bmHeight, GetLastError());
1479 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1481 /* the color table doesn't exist for 24-bit images */
1482 for (i = 0; i < 256; i++)
1484 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1485 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1486 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1487 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1488 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1491 /* returned bits are DWORD aligned and upside down */
1492 todo_wine
1493 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1494 DeleteObject(hbmp);
1496 /* 24-bit source bitmap data */
1497 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1498 ok(hbmp != 0, "CreateBitmap failed\n");
1499 SetLastError(0xdeadbeef);
1500 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1501 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1502 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1503 lines, bm.bmHeight, GetLastError());
1505 memset(&bm, 0xAA, sizeof(bm));
1506 bytes = GetObject(hbmp, sizeof(bm), &bm);
1507 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1508 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1509 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1510 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1511 ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1512 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1513 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1514 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1516 bytes = GetBitmapBits(hbmp, 0, NULL);
1517 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1518 bm.bmWidthBytes * bm.bmHeight, bytes);
1519 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1520 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1521 bm.bmWidthBytes * bm.bmHeight, bytes);
1523 /* retrieve 1-bit DIB data */
1524 memset(bi, 0, sizeof(*bi));
1525 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1526 bi->bmiHeader.biWidth = bm.bmWidth;
1527 bi->bmiHeader.biHeight = bm.bmHeight;
1528 bi->bmiHeader.biPlanes = 1;
1529 bi->bmiHeader.biBitCount = 1;
1530 bi->bmiHeader.biCompression = BI_RGB;
1531 bi->bmiHeader.biSizeImage = 0;
1532 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1533 memset(buf, 0xAA, sizeof(buf));
1534 SetLastError(0xdeadbeef);
1535 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1536 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1537 lines, bm.bmHeight, GetLastError());
1538 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1540 /* the color table consists of black and white */
1541 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1542 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1543 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1544 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1545 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1546 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1547 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1548 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1549 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1550 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1551 for (i = 2; i < 256; i++)
1553 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1554 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1555 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1556 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1557 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1560 /* returned bits are DWORD aligned and upside down */
1561 todo_wine
1562 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1564 /* retrieve 24-bit DIB data */
1565 memset(bi, 0, sizeof(*bi));
1566 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1567 bi->bmiHeader.biWidth = bm.bmWidth;
1568 bi->bmiHeader.biHeight = bm.bmHeight;
1569 bi->bmiHeader.biPlanes = 1;
1570 bi->bmiHeader.biBitCount = 24;
1571 bi->bmiHeader.biCompression = BI_RGB;
1572 bi->bmiHeader.biSizeImage = 0;
1573 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1574 memset(buf, 0xAA, sizeof(buf));
1575 SetLastError(0xdeadbeef);
1576 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1577 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1578 lines, bm.bmHeight, GetLastError());
1579 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1581 /* the color table doesn't exist for 24-bit images */
1582 for (i = 0; i < 256; i++)
1584 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1585 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1586 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1587 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1588 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1591 /* returned bits are DWORD aligned and upside down */
1592 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1593 DeleteObject(hbmp);
1595 ReleaseDC(0, hdc);
1598 static void test_select_object(void)
1600 HDC hdc;
1601 HBITMAP hbm, hbm_old;
1602 INT planes, bpp, i;
1603 DWORD depths[] = {8, 15, 16, 24, 32};
1604 BITMAP bm;
1605 DWORD bytes;
1607 hdc = GetDC(0);
1608 ok(hdc != 0, "GetDC(0) failed\n");
1609 hbm = CreateCompatibleBitmap(hdc, 10, 10);
1610 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
1612 hbm_old = SelectObject(hdc, hbm);
1613 ok(hbm_old == 0, "SelectObject should fail\n");
1615 DeleteObject(hbm);
1616 ReleaseDC(0, hdc);
1618 hdc = CreateCompatibleDC(0);
1619 ok(hdc != 0, "GetDC(0) failed\n");
1620 hbm = CreateCompatibleBitmap(hdc, 10, 10);
1621 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
1623 hbm_old = SelectObject(hdc, hbm);
1624 ok(hbm_old != 0, "SelectObject failed\n");
1625 hbm_old = SelectObject(hdc, hbm_old);
1626 ok(hbm_old == hbm, "SelectObject failed\n");
1628 DeleteObject(hbm);
1630 /* test an 1-bpp bitmap */
1631 planes = GetDeviceCaps(hdc, PLANES);
1632 bpp = 1;
1634 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
1635 ok(hbm != 0, "CreateBitmap failed\n");
1637 hbm_old = SelectObject(hdc, hbm);
1638 ok(hbm_old != 0, "SelectObject failed\n");
1639 hbm_old = SelectObject(hdc, hbm_old);
1640 ok(hbm_old == hbm, "SelectObject failed\n");
1642 DeleteObject(hbm);
1644 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
1645 /* test a color bitmap to dc bpp matching */
1646 planes = GetDeviceCaps(hdc, PLANES);
1647 bpp = GetDeviceCaps(hdc, BITSPIXEL);
1649 hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
1650 ok(hbm != 0, "CreateBitmap failed\n");
1652 hbm_old = SelectObject(hdc, hbm);
1653 if(depths[i] == bpp ||
1654 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
1656 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
1657 SelectObject(hdc, hbm_old);
1658 } else {
1659 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
1662 memset(&bm, 0xAA, sizeof(bm));
1663 bytes = GetObject(hbm, sizeof(bm), &bm);
1664 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1665 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1666 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
1667 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
1668 ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1669 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
1670 if(depths[i] == 15) {
1671 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
1672 } else {
1673 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1675 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1677 DeleteObject(hbm);
1680 DeleteDC(hdc);
1683 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
1685 INT ret;
1686 BITMAP bm;
1688 ret = GetObjectType(hbmp);
1689 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
1691 ret = GetObject(hbmp, 0, 0);
1692 ok_(__FILE__, line)(ret == sizeof(BITMAP) /* XP */ ||
1693 ret == sizeof(DIBSECTION) /* Win9x */, "object size %d\n", ret);
1695 memset(&bm, 0xDA, sizeof(bm));
1696 SetLastError(0xdeadbeef);
1697 ret = GetObject(hbmp, sizeof(bm), &bm);
1698 if (!ret) /* XP, only for curObj2 */ return;
1699 ok_(__FILE__, line)(ret == sizeof(BITMAP) ||
1700 ret == sizeof(DIBSECTION) /* Win9x, only for curObj2 */,
1701 "GetObject returned %d, error %u\n", ret, GetLastError());
1702 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
1703 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
1704 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
1705 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
1706 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
1707 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
1708 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1711 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
1713 static void test_CreateBitmap(void)
1715 BITMAP bmp;
1716 HDC screenDC = GetDC(0);
1717 HDC hdc = CreateCompatibleDC(screenDC);
1718 UINT i, expect = 0;
1720 /* all of these are the stock monochrome bitmap */
1721 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
1722 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
1723 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
1724 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
1725 HBITMAP curObj1 = (HBITMAP)GetCurrentObject(hdc, OBJ_BITMAP);
1726 HBITMAP curObj2 = (HBITMAP)GetCurrentObject(screenDC, OBJ_BITMAP);
1728 /* these 2 are not the stock monochrome bitmap */
1729 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
1730 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
1732 HBITMAP old1 = (HBITMAP)SelectObject(hdc, bm2);
1733 HBITMAP old2 = (HBITMAP)SelectObject(screenDC, bm3);
1734 SelectObject(hdc, old1);
1735 SelectObject(screenDC, old2);
1737 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
1738 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
1739 bm, bm1, bm4, bm5, curObj1, old1);
1740 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
1741 ok(bm != curObj2 /* XP */ || bm == curObj2 /* Win9x */,
1742 "0: %p, curObj2 %p\n", bm, curObj2);
1743 ok(old2 == 0, "old2 %p\n", old2);
1745 test_mono_1x1_bmp(bm);
1746 test_mono_1x1_bmp(bm1);
1747 test_mono_1x1_bmp(bm2);
1748 test_mono_1x1_bmp(bm3);
1749 test_mono_1x1_bmp(bm4);
1750 test_mono_1x1_bmp(bm5);
1751 test_mono_1x1_bmp(old1);
1752 test_mono_1x1_bmp(curObj1);
1753 test_mono_1x1_bmp(curObj2);
1755 DeleteObject(bm);
1756 DeleteObject(bm1);
1757 DeleteObject(bm2);
1758 DeleteObject(bm3);
1759 DeleteObject(bm4);
1760 DeleteObject(bm5);
1762 DeleteDC(hdc);
1763 ReleaseDC(0, screenDC);
1765 /* show that Windows ignores the provided bm.bmWidthBytes */
1766 bmp.bmType = 0;
1767 bmp.bmWidth = 1;
1768 bmp.bmHeight = 1;
1769 bmp.bmWidthBytes = 28;
1770 bmp.bmPlanes = 1;
1771 bmp.bmBitsPixel = 1;
1772 bmp.bmBits = NULL;
1773 bm = CreateBitmapIndirect(&bmp);
1774 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
1775 test_mono_1x1_bmp(bm);
1776 DeleteObject(bm);
1778 /* Test how the bmBitsPixel field is treated */
1779 for(i = 1; i <= 33; i++) {
1780 bmp.bmType = 0;
1781 bmp.bmWidth = 1;
1782 bmp.bmHeight = 1;
1783 bmp.bmWidthBytes = 28;
1784 bmp.bmPlanes = 1;
1785 bmp.bmBitsPixel = i;
1786 bmp.bmBits = NULL;
1787 bm = CreateBitmapIndirect(&bmp);
1788 if(i > 32) {
1789 DWORD error = GetLastError();
1790 ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
1791 ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
1792 continue;
1794 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
1795 GetObject(bm, sizeof(bmp), &bmp);
1796 if(i == 1) {
1797 expect = 1;
1798 } else if(i <= 4) {
1799 expect = 4;
1800 } else if(i <= 8) {
1801 expect = 8;
1802 } else if(i <= 16) {
1803 expect = 16;
1804 } else if(i <= 24) {
1805 expect = 24;
1806 } else if(i <= 32) {
1807 expect = 32;
1809 ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
1810 i, bmp.bmBitsPixel, expect);
1811 DeleteObject(bm);
1815 static void test_bitmapinfoheadersize(void)
1817 HBITMAP hdib;
1818 BITMAPINFO bmi;
1819 BITMAPCOREINFO bci;
1820 HDC hdc = GetDC(0);
1822 memset(&bmi, 0, sizeof(BITMAPINFO));
1823 bmi.bmiHeader.biHeight = 100;
1824 bmi.bmiHeader.biWidth = 512;
1825 bmi.bmiHeader.biBitCount = 24;
1826 bmi.bmiHeader.biPlanes = 1;
1828 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
1830 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1831 ok(hdib == NULL, "CreateDIBSection succeeded\n");
1833 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1835 SetLastError(0xdeadbeef);
1836 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1837 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1838 DeleteObject(hdib);
1840 bmi.bmiHeader.biSize++;
1842 SetLastError(0xdeadbeef);
1843 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1844 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1845 DeleteObject(hdib);
1847 bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
1849 SetLastError(0xdeadbeef);
1850 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1851 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1852 DeleteObject(hdib);
1854 bmi.bmiHeader.biSize++;
1856 SetLastError(0xdeadbeef);
1857 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1858 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1859 DeleteObject(hdib);
1861 bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
1863 SetLastError(0xdeadbeef);
1864 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1865 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1866 DeleteObject(hdib);
1868 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
1870 SetLastError(0xdeadbeef);
1871 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1872 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1873 DeleteObject(hdib);
1875 memset(&bci, 0, sizeof(BITMAPCOREINFO));
1876 bci.bmciHeader.bcHeight = 100;
1877 bci.bmciHeader.bcWidth = 512;
1878 bci.bmciHeader.bcBitCount = 24;
1879 bci.bmciHeader.bcPlanes = 1;
1881 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
1883 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
1884 ok(hdib == NULL, "CreateDIBSection succeeded\n");
1886 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
1888 SetLastError(0xdeadbeef);
1889 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
1890 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1891 DeleteObject(hdib);
1893 bci.bmciHeader.bcSize++;
1895 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
1896 ok(hdib == NULL, "CreateDIBSection succeeded\n");
1898 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
1900 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
1901 ok(hdib == NULL, "CreateDIBSection succeeded\n");
1903 ReleaseDC(0, hdc);
1906 static void test_get16dibits(void)
1908 BYTE bits[4 * (16 / sizeof(BYTE))];
1909 HBITMAP hbmp;
1910 HDC screen_dc = GetDC(NULL);
1911 int ret;
1912 BITMAPINFO * info;
1913 int info_len = sizeof(BITMAPINFOHEADER) + 1024;
1914 BYTE *p;
1915 int overwritten_bytes = 0;
1917 memset(bits, 0, sizeof(bits));
1918 hbmp = CreateBitmap(2, 2, 1, 16, bits);
1919 ok(hbmp != NULL, "CreateBitmap failed\n");
1921 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
1922 assert(info);
1924 memset(info, '!', info_len);
1925 memset(info, 0, sizeof(info->bmiHeader));
1927 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1928 info->bmiHeader.biWidth = 2;
1929 info->bmiHeader.biHeight = 2;
1930 info->bmiHeader.biPlanes = 1;
1931 info->bmiHeader.biCompression = BI_RGB;
1933 ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
1934 ok(ret != 0, "GetDIBits failed\n");
1936 for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
1937 if (*p != '!')
1938 overwritten_bytes++;
1939 ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
1941 HeapFree(GetProcessHeap(), 0, info);
1942 DeleteObject(hbmp);
1943 ReleaseDC(NULL, screen_dc);
1946 void test_GdiAlphaBlend()
1948 /* test out-of-bound parameters for GdiAlphaBlend */
1949 HDC hdcNull;
1951 HDC hdcDst;
1952 HBITMAP bmpDst;
1953 HBITMAP oldDst;
1955 BITMAPINFO bmi;
1956 HDC hdcSrc;
1957 HBITMAP bmpSrc;
1958 HBITMAP oldSrc;
1959 LPVOID bits;
1961 BLENDFUNCTION blend;
1963 if (!pGdiAlphaBlend)
1965 skip("GdiAlphaBlend() is not implemented\n");
1966 return;
1969 hdcNull = GetDC(NULL);
1970 hdcDst = CreateCompatibleDC(hdcNull);
1971 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
1972 hdcSrc = CreateCompatibleDC(hdcNull);
1974 memset(&bmi, 0, sizeof(bmi)); /* as of Wine 0.9.44 we require the src to be a DIB section */
1975 bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
1976 bmi.bmiHeader.biHeight = 20;
1977 bmi.bmiHeader.biWidth = 20;
1978 bmi.bmiHeader.biBitCount = 32;
1979 bmi.bmiHeader.biPlanes = 1;
1980 bmi.bmiHeader.biCompression = BI_RGB;
1981 bmpSrc = CreateDIBSection(hdcDst, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
1982 ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
1984 oldDst = (HBITMAP)SelectObject(hdcDst, bmpDst);
1985 oldSrc = (HBITMAP)SelectObject(hdcSrc, bmpSrc);
1987 blend.BlendOp = AC_SRC_OVER;
1988 blend.BlendFlags = 0;
1989 blend.SourceConstantAlpha = 128;
1990 blend.AlphaFormat = 0;
1992 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend), TRUE, BOOL, "%d");
1993 SetLastError(0xdeadbeef);
1994 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), FALSE, BOOL, "%d");
1995 expect_eq(GetLastError(), ERROR_INVALID_PARAMETER, int, "%d");
1996 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), FALSE, BOOL, "%d");
1997 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend), FALSE, BOOL, "%d");
1998 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
1999 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
2001 SetWindowOrgEx(hdcSrc, -10, -10, NULL);
2002 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), TRUE, BOOL, "%d");
2003 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), TRUE, BOOL, "%d");
2004 SetMapMode(hdcSrc, MM_ANISOTROPIC);
2005 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
2006 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend), TRUE, BOOL, "%d");
2007 expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend), TRUE, BOOL, "%d");
2009 SelectObject(hdcDst, oldDst);
2010 SelectObject(hdcSrc, oldSrc);
2011 DeleteObject(bmpSrc);
2012 DeleteObject(bmpDst);
2013 DeleteDC(hdcDst);
2014 DeleteDC(hdcSrc);
2016 ReleaseDC(NULL, hdcNull);
2020 START_TEST(bitmap)
2022 HMODULE hdll;
2023 is_win9x = GetWindowLongPtrW(GetDesktopWindow(), GWLP_WNDPROC) == 0;
2025 hdll = GetModuleHandle("gdi32.dll");
2026 pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
2028 test_createdibitmap();
2029 test_dibsections();
2030 test_mono_dibsection();
2031 test_bitmap();
2032 test_bmBits();
2033 test_GetDIBits_selected_DIB(1);
2034 test_GetDIBits_selected_DIB(4);
2035 test_GetDIBits_selected_DIB(8);
2036 test_GetDIBits_selected_DDB(TRUE);
2037 test_GetDIBits_selected_DDB(FALSE);
2038 test_GetDIBits();
2039 test_select_object();
2040 test_CreateBitmap();
2041 test_GdiAlphaBlend();
2042 test_bitmapinfoheadersize();
2043 test_get16dibits();