wintrust: Add a helper function to initialize chain creation parameters.
[wine] / dlls / gdi32 / tests / bitmap.c
1 /*
2  * Unit test suite for bitmaps
3  *
4  * Copyright 2004 Huw Davies
5  * Copyright 2006 Dmitry Timoshkov
6  *
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.
11  *
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.
16  *
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
20  */
21
22 #include <stdarg.h>
23 #include <assert.h>
24 #include <string.h>
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wingdi.h"
29 #include "winuser.h"
30 #include "mmsystem.h"
31
32 #include "wine/test.h"
33
34 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
35
36 static BOOL is_win9x;
37
38 static INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp )
39 {
40     switch(bpp)
41     {
42     case 1:
43         return 2 * ((bmWidth+15) >> 4);
44
45     case 24:
46         bmWidth *= 3; /* fall through */
47     case 8:
48         return bmWidth + (bmWidth & 1);
49
50     case 32:
51         return bmWidth * 4;
52
53     case 16:
54     case 15:
55         return bmWidth * 2;
56
57     case 4:
58         return 2 * ((bmWidth+3) >> 2);
59
60     default:
61         trace("Unknown depth %d, please report.\n", bpp );
62         assert(0);
63     }
64     return -1;
65 }
66
67 static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHEADER *bmih)
68 {
69     BITMAP bm;
70     INT ret, width_bytes;
71     char buf[512], buf_cmp[512];
72
73     ret = GetObject(hbm, sizeof(bm), &bm);
74     ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
75
76     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
77     ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
78     ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
79     width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
80     ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
81     ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
82     ok(bm.bmBitsPixel == expected_depth, "wrong bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, expected_depth);
83     ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
84
85     assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
86     assert(sizeof(buf) == sizeof(buf_cmp));
87
88     ret = GetBitmapBits(hbm, 0, NULL);
89     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
90
91     memset(buf_cmp, 0xAA, sizeof(buf_cmp));
92     memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
93
94     memset(buf, 0xAA, sizeof(buf));
95     ret = GetBitmapBits(hbm, sizeof(buf), buf);
96     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
97     ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
98
99     /* test various buffer sizes for GetObject */
100     ret = GetObject(hbm, 0, NULL);
101     ok(ret == sizeof(bm), "wrong size %d\n", ret);
102
103     ret = GetObject(hbm, sizeof(bm) * 2, &bm);
104     ok(ret == sizeof(bm), "wrong size %d\n", ret);
105
106     ret = GetObject(hbm, sizeof(bm) / 2, &bm);
107     ok(ret == 0, "%d != 0\n", ret);
108
109     ret = GetObject(hbm, 0, &bm);
110     ok(ret == 0, "%d != 0\n", ret);
111
112     ret = GetObject(hbm, 1, &bm);
113     ok(ret == 0, "%d != 0\n", ret);
114 }
115
116 static void test_createdibitmap(void)
117 {
118     HDC hdc, hdcmem;
119     BITMAPINFOHEADER bmih;
120     HBITMAP hbm, hbm_colour, hbm_old;
121     INT screen_depth;
122
123     hdc = GetDC(0);
124     screen_depth = GetDeviceCaps(hdc, BITSPIXEL);
125     memset(&bmih, 0, sizeof(bmih));
126     bmih.biSize = sizeof(bmih);
127     bmih.biWidth = 10;
128     bmih.biHeight = 10;
129     bmih.biPlanes = 1;
130     bmih.biBitCount = 32;
131     bmih.biCompression = BI_RGB;
132  
133     /* First create an un-initialised bitmap.  The depth of the bitmap
134        should match that of the hdc and not that supplied in bmih.
135     */
136
137     /* First try 32 bits */
138     hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
139     ok(hbm != NULL, "CreateDIBitmap failed\n");
140     test_bitmap_info(hbm, screen_depth, &bmih);
141     DeleteObject(hbm);
142     
143     /* Then 16 */
144     bmih.biBitCount = 16;
145     hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
146     ok(hbm != NULL, "CreateDIBitmap failed\n");
147     test_bitmap_info(hbm, screen_depth, &bmih);
148     DeleteObject(hbm);
149
150     /* Then 1 */
151     bmih.biBitCount = 1;
152     hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
153     ok(hbm != NULL, "CreateDIBitmap failed\n");
154     test_bitmap_info(hbm, screen_depth, &bmih);
155     DeleteObject(hbm);
156
157     /* Now with a monochrome dc we expect a monochrome bitmap */
158     hdcmem = CreateCompatibleDC(hdc);
159
160     /* First try 32 bits */
161     bmih.biBitCount = 32;
162     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
163     ok(hbm != NULL, "CreateDIBitmap failed\n");
164     test_bitmap_info(hbm, 1, &bmih);
165     DeleteObject(hbm);
166     
167     /* Then 16 */
168     bmih.biBitCount = 16;
169     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
170     ok(hbm != NULL, "CreateDIBitmap failed\n");
171     test_bitmap_info(hbm, 1, &bmih);
172     DeleteObject(hbm);
173     
174     /* Then 1 */
175     bmih.biBitCount = 1;
176     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
177     ok(hbm != NULL, "CreateDIBitmap failed\n");
178     test_bitmap_info(hbm, 1, &bmih);
179     DeleteObject(hbm);
180
181     /* Now select a polychrome bitmap into the dc and we expect
182        screen_depth bitmaps again */
183     hbm_colour = CreateCompatibleBitmap(hdc, 1, 1);
184     hbm_old = SelectObject(hdcmem, hbm_colour);
185
186     /* First try 32 bits */
187     bmih.biBitCount = 32;
188     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
189     ok(hbm != NULL, "CreateDIBitmap failed\n");
190     test_bitmap_info(hbm, screen_depth, &bmih);
191     DeleteObject(hbm);
192     
193     /* Then 16 */
194     bmih.biBitCount = 16;
195     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
196     ok(hbm != NULL, "CreateDIBitmap failed\n");
197     test_bitmap_info(hbm, screen_depth, &bmih);
198     DeleteObject(hbm);
199     
200     /* Then 1 */
201     bmih.biBitCount = 1;
202     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
203     ok(hbm != NULL, "CreateDIBitmap failed\n");
204     test_bitmap_info(hbm, screen_depth, &bmih);
205     DeleteObject(hbm);
206
207     SelectObject(hdcmem, hbm_old);
208     DeleteObject(hbm_colour);
209     DeleteDC(hdcmem);
210
211     /* If hdc == 0 then we get a 1 bpp bitmap */
212     if (!is_win9x) {
213         bmih.biBitCount = 32;
214         hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0);
215         ok(hbm != NULL, "CreateDIBitmap failed\n");
216         test_bitmap_info(hbm, 1, &bmih);
217         DeleteObject(hbm);
218     }
219     
220     ReleaseDC(0, hdc);
221 }
222
223 static INT DIB_GetWidthBytes( int width, int bpp )
224 {
225     int words;
226
227     switch (bpp)
228     {
229         case 1:  words = (width + 31) / 32; break;
230         case 4:  words = (width + 7) / 8; break;
231         case 8:  words = (width + 3) / 4; break;
232         case 15:
233         case 16: words = (width + 1) / 2; break;
234         case 24: words = (width * 3 + 3)/4; break;
235         case 32: words = width; break;
236
237         default:
238             words=0;
239             trace("Unknown depth %d, please report.\n", bpp );
240             assert(0);
241             break;
242     }
243     return 4 * words;
244 }
245
246 static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
247 {
248     BITMAP bm;
249     DIBSECTION ds;
250     INT ret, width_bytes;
251     BYTE *buf;
252
253     ret = GetObject(hbm, sizeof(bm), &bm);
254     ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
255
256     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
257     ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
258     ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
259     width_bytes = DIB_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
260     ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
261     ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
262     ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount);
263     ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
264
265     buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);
266
267     width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
268
269     /* GetBitmapBits returns not 32-bit aligned data */
270     ret = GetBitmapBits(hbm, 0, NULL);
271     ok(ret == width_bytes * bm.bmHeight, "%d != %d\n", ret, width_bytes * bm.bmHeight);
272
273     memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
274     ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
275     ok(ret == width_bytes * bm.bmHeight, "%d != %d\n", ret, width_bytes * bm.bmHeight);
276
277     HeapFree(GetProcessHeap(), 0, buf);
278
279     /* test various buffer sizes for GetObject */
280     memset(&ds, 0xAA, sizeof(ds));
281     ret = GetObject(hbm, sizeof(bm) * 2, &bm);
282     ok(ret == sizeof(bm), "wrong size %d\n", ret);
283     ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
284     ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
285     ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
286
287     ret = GetObject(hbm, sizeof(bm) / 2, &bm);
288     ok(ret == 0, "%d != 0\n", ret);
289
290     ret = GetObject(hbm, 0, &bm);
291     ok(ret == 0, "%d != 0\n", ret);
292
293     ret = GetObject(hbm, 1, &bm);
294     ok(ret == 0, "%d != 0\n", ret);
295
296     /* test various buffer sizes for GetObject */
297     ret = GetObject(hbm, 0, NULL);
298     ok(ret == sizeof(bm), "wrong size %d\n", ret);
299
300     memset(&ds, 0xAA, sizeof(ds));
301     ret = GetObject(hbm, sizeof(ds) * 2, &ds);
302     ok(ret == sizeof(ds), "wrong size %d\n", ret);
303
304     ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
305     ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%u != %u\n",
306        ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
307     ok(bmih->biSizeImage == 0, "%u != 0\n", bmih->biSizeImage);
308     ds.dsBmih.biSizeImage = 0;
309
310     ok(ds.dsBmih.biSize == bmih->biSize, "%u != %u\n", ds.dsBmih.biSize, bmih->biSize);
311     ok(ds.dsBmih.biWidth == bmih->biWidth, "%u != %u\n", ds.dsBmih.biWidth, bmih->biWidth);
312     ok(ds.dsBmih.biHeight == bmih->biHeight, "%u != %u\n", ds.dsBmih.biHeight, bmih->biHeight);
313     ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes);
314     ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount);
315     ok(ds.dsBmih.biCompression == bmih->biCompression, "%u != %u\n", ds.dsBmih.biCompression, bmih->biCompression);
316     ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%u != %u\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
317     ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%u != %u\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
318     ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%u != %u\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);
319
320     memset(&ds, 0xAA, sizeof(ds));
321     ret = GetObject(hbm, sizeof(ds) - 4, &ds);
322     ok(ret == sizeof(ds.dsBm), "wrong size %d\n", ret);
323     ok(ds.dsBm.bmWidth == bmih->biWidth, "%u != %u\n", ds.dsBmih.biWidth, bmih->biWidth);
324     ok(ds.dsBm.bmHeight == bmih->biHeight, "%u != %u\n", ds.dsBmih.biHeight, bmih->biHeight);
325     ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);
326
327     ret = GetObject(hbm, 0, &ds);
328     ok(ret == 0, "%d != 0\n", ret);
329
330     ret = GetObject(hbm, 1, &ds);
331     ok(ret == 0, "%d != 0\n", ret);
332 }
333
334 #define test_color_todo(got, exp, txt, todo) \
335     if (!todo && got != exp && screen_depth < 24) { \
336       todo_wine ok(0, #txt " failed at %d-bit screen depth: got 0x%06x expected 0x%06x - skipping DIB tests\n", \
337                    screen_depth, (UINT)got, (UINT)exp); \
338       return; \
339     } else if (todo) todo_wine { ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp); } \
340     else ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp) \
341
342 #define test_color(hdc, color, exp, todo_setp, todo_getp) \
343 { \
344     COLORREF c; \
345     c = SetPixel(hdc, 0, 0, color); \
346     if (!is_win9x) { test_color_todo(c, exp, SetPixel, todo_setp); } \
347     c = GetPixel(hdc, 0, 0); \
348     test_color_todo(c, exp, GetPixel, todo_getp); \
349 }
350
351 static void test_dibsections(void)
352 {
353     HDC hdc, hdcmem, hdcmem2;
354     HBITMAP hdib, oldbm, hdib2, oldbm2;
355     char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
356     char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
357     BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
358     BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
359     HBITMAP hcoredib;
360     char coreBits[256];
361     BYTE *bits;
362     RGBQUAD rgb[256];
363     int ret;
364     char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
365     LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
366     WORD *index;
367     DWORD *bits32;
368     HPALETTE hpal, oldpal;
369     DIBSECTION dibsec;
370     COLORREF c0, c1;
371     int i;
372     int screen_depth;
373     MEMORY_BASIC_INFORMATION info;
374
375     hdc = GetDC(0);
376     screen_depth = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
377
378     memset(pbmi, 0, sizeof(bmibuf));
379     pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
380     pbmi->bmiHeader.biHeight = 100;
381     pbmi->bmiHeader.biWidth = 512;
382     pbmi->bmiHeader.biBitCount = 24;
383     pbmi->bmiHeader.biPlanes = 1;
384     pbmi->bmiHeader.biCompression = BI_RGB;
385
386     SetLastError(0xdeadbeef);
387     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
388     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
389     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
390     ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
391
392     /* test the DIB memory */
393     ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
394         "VirtualQuery failed\n");
395     ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
396     ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
397     ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
398     ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
399     ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
400     ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
401     ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
402
403     test_dib_info(hdib, bits, &pbmi->bmiHeader);
404     DeleteObject(hdib);
405
406     pbmi->bmiHeader.biBitCount = 8;
407     pbmi->bmiHeader.biCompression = BI_RLE8;
408     SetLastError(0xdeadbeef);
409     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
410     ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
411     ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
412
413     pbmi->bmiHeader.biBitCount = 16;
414     pbmi->bmiHeader.biCompression = BI_BITFIELDS;
415     ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
416     ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
417     ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
418     SetLastError(0xdeadbeef);
419     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
420     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
421
422     /* test the DIB memory */
423     ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
424         "VirtualQuery failed\n");
425     ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
426     ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
427     ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
428     ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
429     ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
430     ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
431     ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
432
433     test_dib_info(hdib, bits, &pbmi->bmiHeader);
434     DeleteObject(hdib);
435
436     memset(pbmi, 0, sizeof(bmibuf));
437     pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
438     pbmi->bmiHeader.biHeight = 16;
439     pbmi->bmiHeader.biWidth = 16;
440     pbmi->bmiHeader.biBitCount = 1;
441     pbmi->bmiHeader.biPlanes = 1;
442     pbmi->bmiHeader.biCompression = BI_RGB;
443     pbmi->bmiColors[0].rgbRed = 0xff;
444     pbmi->bmiColors[0].rgbGreen = 0;
445     pbmi->bmiColors[0].rgbBlue = 0;
446     pbmi->bmiColors[1].rgbRed = 0;
447     pbmi->bmiColors[1].rgbGreen = 0;
448     pbmi->bmiColors[1].rgbBlue = 0xff;
449
450     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
451     ok(hdib != NULL, "CreateDIBSection failed\n");
452     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
453     ok(dibsec.dsBmih.biClrUsed == 2,
454         "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
455
456     /* Test if the old BITMAPCOREINFO structure is supported */    
457         
458     pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
459     pbci->bmciHeader.bcBitCount = 0;
460
461     if (!is_win9x) {
462         ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
463         ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
464         ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
465             && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
466         "GetDIBits did't fill in the BITMAPCOREHEADER structure properly\n");
467
468         ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
469         ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
470         ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
471             (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
472             (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
473             "The color table has not been translated to the old BITMAPCOREINFO format\n");
474
475         hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
476         ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
477
478         ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
479         ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
480         ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
481         ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
482             (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
483             (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
484             "The color table has not been translated to the old BITMAPCOREINFO format\n");
485
486         DeleteObject(hcoredib);
487     }
488
489     hdcmem = CreateCompatibleDC(hdc);
490     oldbm = SelectObject(hdcmem, hdib);
491
492     ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
493     ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
494     ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
495        "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
496        rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
497        rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
498
499     c0 = RGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen, pbmi->bmiColors[0].rgbBlue);
500     c1 = RGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen, pbmi->bmiColors[1].rgbBlue);
501
502     test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
503     test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
504     test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
505     test_color(hdcmem, PALETTEINDEX(0), c0, 1, 1);
506     test_color(hdcmem, PALETTEINDEX(1), c0, 1, 1);
507     test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
508     test_color(hdcmem, PALETTERGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen,
509         pbmi->bmiColors[0].rgbBlue), c0, 1, 1);
510     test_color(hdcmem, PALETTERGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen,
511         pbmi->bmiColors[1].rgbBlue), c1, 1, 1);
512     test_color(hdcmem, PALETTERGB(0, 0, 0), c0, 1, 1);
513     test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
514     test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1, 1, 1);
515
516     SelectObject(hdcmem, oldbm);
517     DeleteObject(hdib);
518
519     pbmi->bmiColors[0].rgbRed = 0xff;
520     pbmi->bmiColors[0].rgbGreen = 0xff;
521     pbmi->bmiColors[0].rgbBlue = 0xff;
522     pbmi->bmiColors[1].rgbRed = 0;
523     pbmi->bmiColors[1].rgbGreen = 0;
524     pbmi->bmiColors[1].rgbBlue = 0;
525
526     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
527     ok(hdib != NULL, "CreateDIBSection failed\n");
528
529     test_dib_info(hdib, bits, &pbmi->bmiHeader);
530
531     oldbm = SelectObject(hdcmem, hdib);
532
533     ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
534     ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
535     ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
536        "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
537        rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
538        rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
539
540     SelectObject(hdcmem, oldbm);
541     test_dib_info(hdib, bits, &pbmi->bmiHeader);
542     DeleteObject(hdib);
543
544     pbmi->bmiHeader.biBitCount = 4;
545     for (i = 0; i < 16; i++) {
546         pbmi->bmiColors[i].rgbRed = i;
547         pbmi->bmiColors[i].rgbGreen = 16-i;
548         pbmi->bmiColors[i].rgbBlue = 0;
549     }
550     hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
551     ok(hdib != NULL, "CreateDIBSection failed\n");
552     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
553     ok(dibsec.dsBmih.biClrUsed == 16,
554        "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
555     test_dib_info(hdib, bits, &pbmi->bmiHeader);
556     DeleteObject(hdib);
557
558     pbmi->bmiHeader.biBitCount = 8;
559
560     for (i = 0; i < 128; i++) {
561         pbmi->bmiColors[i].rgbRed = 255 - i * 2;
562         pbmi->bmiColors[i].rgbGreen = i * 2;
563         pbmi->bmiColors[i].rgbBlue = 0;
564         pbmi->bmiColors[255 - i].rgbRed = 0;
565         pbmi->bmiColors[255 - i].rgbGreen = i * 2;
566         pbmi->bmiColors[255 - i].rgbBlue = 255 - i * 2;
567     }
568     hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
569     ok(hdib != NULL, "CreateDIBSection failed\n");
570     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
571     ok(dibsec.dsBmih.biClrUsed == 256,
572         "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
573
574     oldbm = SelectObject(hdcmem, hdib);
575
576     for (i = 0; i < 256; i++) {
577         test_color(hdcmem, DIBINDEX(i), 
578             RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
579         test_color(hdcmem, PALETTERGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 
580             RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
581     }
582
583     SelectObject(hdcmem, oldbm);
584     test_dib_info(hdib, bits, &pbmi->bmiHeader);
585     DeleteObject(hdib);
586
587     pbmi->bmiHeader.biBitCount = 1;
588
589     /* Now create a palette and a palette indexed dib section */
590     memset(plogpal, 0, sizeof(logpalbuf));
591     plogpal->palVersion = 0x300;
592     plogpal->palNumEntries = 2;
593     plogpal->palPalEntry[0].peRed = 0xff;
594     plogpal->palPalEntry[0].peBlue = 0xff;
595     plogpal->palPalEntry[1].peGreen = 0xff;
596
597     index = (WORD*)pbmi->bmiColors;
598     *index++ = 0;
599     *index = 1;
600     hpal = CreatePalette(plogpal);
601     ok(hpal != NULL, "CreatePalette failed\n");
602     oldpal = SelectPalette(hdc, hpal, TRUE);
603     hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
604     ok(hdib != NULL, "CreateDIBSection failed\n");
605     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
606     ok(dibsec.dsBmih.biClrUsed == 2,
607         "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
608
609     /* The colour table has already been grabbed from the dc, so we select back the
610        old palette */
611
612     SelectPalette(hdc, oldpal, TRUE);
613     oldbm = SelectObject(hdcmem, hdib);
614     oldpal = SelectPalette(hdcmem, hpal, TRUE);
615
616     ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
617     ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
618     ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
619        rgb[1].rgbRed == 0    && rgb[1].rgbBlue == 0    && rgb[1].rgbGreen == 0xff,
620        "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
621        rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
622        rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
623
624     c0 = RGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen, plogpal->palPalEntry[0].peBlue);
625     c1 = RGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen, plogpal->palPalEntry[1].peBlue);
626
627     test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
628     test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
629     test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
630     test_color(hdcmem, PALETTEINDEX(0), c0, 0, 1);
631     test_color(hdcmem, PALETTEINDEX(1), c1, 0, 1);
632     test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
633     test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen,
634         plogpal->palPalEntry[0].peBlue), c0, 1, 1);
635     test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen,
636         plogpal->palPalEntry[1].peBlue), c1, 1, 1);
637     test_color(hdcmem, PALETTERGB(0, 0, 0), c1, 1, 1);
638     test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
639     test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0, 1, 1);
640     test_color(hdcmem, PALETTERGB(0, 1, 0), c1, 1, 1);
641     test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1, 1, 1);
642     test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0, 1, 1);
643
644     /* Bottom and 2nd row from top green, everything else magenta */
645     bits[0] = bits[1] = 0xff;
646     bits[13 * 4] = bits[13*4 + 1] = 0xff;
647
648     test_dib_info(hdib, bits, &pbmi->bmiHeader);
649
650     pbmi->bmiHeader.biBitCount = 32;
651
652     hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
653     ok(hdib2 != NULL, "CreateDIBSection failed\n");
654     hdcmem2 = CreateCompatibleDC(hdc);
655     oldbm2 = SelectObject(hdcmem2, hdib2);
656
657     BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
658
659     ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
660     ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
661
662     SelectObject(hdcmem2, oldbm2);
663     test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
664     DeleteObject(hdib2);
665
666     SelectObject(hdcmem, oldbm);
667     SelectObject(hdcmem, oldpal);
668     DeleteObject(hdib);
669     DeleteObject(hpal);
670
671
672     pbmi->bmiHeader.biBitCount = 8;
673
674     memset(plogpal, 0, sizeof(logpalbuf));
675     plogpal->palVersion = 0x300;
676     plogpal->palNumEntries = 256;
677
678     for (i = 0; i < 128; i++) {
679         plogpal->palPalEntry[i].peRed = 255 - i * 2;
680         plogpal->palPalEntry[i].peBlue = i * 2;
681         plogpal->palPalEntry[i].peGreen = 0;
682         plogpal->palPalEntry[255 - i].peRed = 0;
683         plogpal->palPalEntry[255 - i].peGreen = i * 2;
684         plogpal->palPalEntry[255 - i].peBlue = 255 - i * 2;
685     }
686
687     index = (WORD*)pbmi->bmiColors;
688     for (i = 0; i < 256; i++) {
689         *index++ = i;
690     }
691
692     hpal = CreatePalette(plogpal);
693     ok(hpal != NULL, "CreatePalette failed\n");
694     oldpal = SelectPalette(hdc, hpal, TRUE);
695     hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
696     ok(hdib != NULL, "CreateDIBSection failed\n");
697     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
698     ok(dibsec.dsBmih.biClrUsed == 256,
699         "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
700
701     test_dib_info(hdib, bits, &pbmi->bmiHeader);
702
703     SelectPalette(hdc, oldpal, TRUE);
704     oldbm = SelectObject(hdcmem, hdib);
705     oldpal = SelectPalette(hdcmem, hpal, TRUE);
706
707     ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
708     ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
709     for (i = 0; i < 256; i++) {
710         ok(rgb[i].rgbRed == plogpal->palPalEntry[i].peRed && 
711             rgb[i].rgbBlue == plogpal->palPalEntry[i].peBlue && 
712             rgb[i].rgbGreen == plogpal->palPalEntry[i].peGreen, 
713             "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
714             i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
715     }
716
717     for (i = 0; i < 256; i++) {
718         test_color(hdcmem, DIBINDEX(i), 
719             RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
720         test_color(hdcmem, PALETTEINDEX(i), 
721             RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
722         test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 
723             RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
724     }
725
726     SelectPalette(hdcmem, oldpal, TRUE);
727     SelectObject(hdcmem, oldbm);
728     DeleteObject(hdib);
729     DeleteObject(hpal);
730
731
732     DeleteDC(hdcmem);
733     ReleaseDC(0, hdc);
734 }
735
736 static void test_mono_dibsection(void)
737 {
738     HDC hdc, memdc;
739     HBITMAP old_bm, mono_ds;
740     char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
741     BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
742     BYTE bits[10 * 4];
743     BYTE *ds_bits;
744     int num;
745
746     hdc = GetDC(0);
747
748     memdc = CreateCompatibleDC(hdc);
749
750     memset(pbmi, 0, sizeof(bmibuf));
751     pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
752     pbmi->bmiHeader.biHeight = 10;
753     pbmi->bmiHeader.biWidth = 10;
754     pbmi->bmiHeader.biBitCount = 1;
755     pbmi->bmiHeader.biPlanes = 1;
756     pbmi->bmiHeader.biCompression = BI_RGB;
757     pbmi->bmiColors[0].rgbRed = 0xff;
758     pbmi->bmiColors[0].rgbGreen = 0xff;
759     pbmi->bmiColors[0].rgbBlue = 0xff;
760     pbmi->bmiColors[1].rgbRed = 0x0;
761     pbmi->bmiColors[1].rgbGreen = 0x0;
762     pbmi->bmiColors[1].rgbBlue = 0x0;
763
764     /*
765      * First dib section is 'inverted' ie color[0] is white, color[1] is black
766      */
767
768     mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
769     ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
770     old_bm = SelectObject(memdc, mono_ds);
771
772     /* black border, white interior */
773     Rectangle(memdc, 0, 0, 10, 10);
774     ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
775     ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
776
777     /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
778
779     memset(bits, 0, sizeof(bits));
780     bits[0] = 0xaa;
781
782     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
783     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
784
785     /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
786
787     pbmi->bmiColors[0].rgbRed = 0x0;
788     pbmi->bmiColors[0].rgbGreen = 0x0;
789     pbmi->bmiColors[0].rgbBlue = 0x0;
790     pbmi->bmiColors[1].rgbRed = 0xff;
791     pbmi->bmiColors[1].rgbGreen = 0xff;
792     pbmi->bmiColors[1].rgbBlue = 0xff;
793
794     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
795     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
796
797     SelectObject(memdc, old_bm);
798     DeleteObject(mono_ds);
799
800     /*
801      * Next dib section is 'normal' ie color[0] is black, color[1] is white
802      */
803
804     pbmi->bmiColors[0].rgbRed = 0x0;
805     pbmi->bmiColors[0].rgbGreen = 0x0;
806     pbmi->bmiColors[0].rgbBlue = 0x0;
807     pbmi->bmiColors[1].rgbRed = 0xff;
808     pbmi->bmiColors[1].rgbGreen = 0xff;
809     pbmi->bmiColors[1].rgbBlue = 0xff;
810
811     mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
812     ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
813     old_bm = SelectObject(memdc, mono_ds);
814
815     /* black border, white interior */
816     Rectangle(memdc, 0, 0, 10, 10);
817     ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
818     ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
819
820     /* SetDIBitsToDevice with a normal bmi -> normal dib section */
821
822     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
823     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
824
825     /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
826
827     pbmi->bmiColors[0].rgbRed = 0xff;
828     pbmi->bmiColors[0].rgbGreen = 0xff;
829     pbmi->bmiColors[0].rgbBlue = 0xff;
830     pbmi->bmiColors[1].rgbRed = 0x0;
831     pbmi->bmiColors[1].rgbGreen = 0x0;
832     pbmi->bmiColors[1].rgbBlue = 0x0;
833
834     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
835     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
836
837     /*
838      * Take that 'normal' dibsection and change its colour table to an 'inverted' one
839      */
840
841     pbmi->bmiColors[0].rgbRed = 0xff;
842     pbmi->bmiColors[0].rgbGreen = 0xff;
843     pbmi->bmiColors[0].rgbBlue = 0xff;
844     pbmi->bmiColors[1].rgbRed = 0x0;
845     pbmi->bmiColors[1].rgbGreen = 0x0;
846     pbmi->bmiColors[1].rgbBlue = 0x0;
847     num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors);
848     ok(num == 2, "num = %d\n", num);
849
850     /* black border, white interior */
851     Rectangle(memdc, 0, 0, 10, 10);
852 todo_wine {
853     ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
854     ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
855  }
856     /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
857
858     memset(bits, 0, sizeof(bits));
859     bits[0] = 0xaa;
860
861     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
862     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
863
864     /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
865
866     pbmi->bmiColors[0].rgbRed = 0x0;
867     pbmi->bmiColors[0].rgbGreen = 0x0;
868     pbmi->bmiColors[0].rgbBlue = 0x0;
869     pbmi->bmiColors[1].rgbRed = 0xff;
870     pbmi->bmiColors[1].rgbGreen = 0xff;
871     pbmi->bmiColors[1].rgbBlue = 0xff;
872
873     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
874     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
875
876     SelectObject(memdc, old_bm);
877     DeleteObject(mono_ds);
878
879     /*
880      * Now a dib section with a strange colour map just for fun.  This behaves just like an inverted one.
881      */
882  
883     pbmi->bmiColors[0].rgbRed = 0xff;
884     pbmi->bmiColors[0].rgbGreen = 0x0;
885     pbmi->bmiColors[0].rgbBlue = 0x0;
886     pbmi->bmiColors[1].rgbRed = 0xfe;
887     pbmi->bmiColors[1].rgbGreen = 0x0;
888     pbmi->bmiColors[1].rgbBlue = 0x0;
889
890     mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
891     ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
892     old_bm = SelectObject(memdc, mono_ds);
893
894     /* black border, white interior */
895     Rectangle(memdc, 0, 0, 10, 10);
896     ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
897     ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
898
899     /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
900
901     pbmi->bmiColors[0].rgbRed = 0x0;
902     pbmi->bmiColors[0].rgbGreen = 0x0;
903     pbmi->bmiColors[0].rgbBlue = 0x0;
904     pbmi->bmiColors[1].rgbRed = 0xff;
905     pbmi->bmiColors[1].rgbGreen = 0xff;
906     pbmi->bmiColors[1].rgbBlue = 0xff;
907
908     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
909     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
910
911     /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
912
913     pbmi->bmiColors[0].rgbRed = 0xff;
914     pbmi->bmiColors[0].rgbGreen = 0xff;
915     pbmi->bmiColors[0].rgbBlue = 0xff;
916     pbmi->bmiColors[1].rgbRed = 0x0;
917     pbmi->bmiColors[1].rgbGreen = 0x0;
918     pbmi->bmiColors[1].rgbBlue = 0x0;
919
920     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
921     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
922
923     SelectObject(memdc, old_bm);
924     DeleteObject(mono_ds);
925
926     DeleteDC(memdc);
927     ReleaseDC(0, hdc);
928 }
929
930 static void test_bitmap(void)
931 {
932     char buf[256], buf_cmp[256];
933     HBITMAP hbmp, hbmp_old;
934     HDC hdc;
935     BITMAP bm;
936     INT ret;
937
938     hdc = CreateCompatibleDC(0);
939     assert(hdc != 0);
940
941     hbmp = CreateBitmap(15, 15, 1, 1, NULL);
942     assert(hbmp != NULL);
943
944     ret = GetObject(hbmp, sizeof(bm), &bm);
945     ok(ret == sizeof(bm), "wrong size %d\n", ret);
946
947     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
948     ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
949     ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
950     ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
951     ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
952     ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
953     ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
954
955     assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
956     assert(sizeof(buf) == sizeof(buf_cmp));
957
958     ret = GetBitmapBits(hbmp, 0, NULL);
959     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
960
961     memset(buf_cmp, 0xAA, sizeof(buf_cmp));
962     memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
963
964     memset(buf, 0xAA, sizeof(buf));
965     ret = GetBitmapBits(hbmp, sizeof(buf), buf);
966     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
967     ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
968
969     hbmp_old = SelectObject(hdc, hbmp);
970
971     ret = GetObject(hbmp, sizeof(bm), &bm);
972     ok(ret == sizeof(bm), "wrong size %d\n", ret);
973
974     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
975     ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
976     ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
977     ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
978     ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
979     ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
980     ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
981
982     memset(buf, 0xAA, sizeof(buf));
983     ret = GetBitmapBits(hbmp, sizeof(buf), buf);
984     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
985     ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
986
987     hbmp_old = SelectObject(hdc, hbmp_old);
988     ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
989
990     /* test various buffer sizes for GetObject */
991     ret = GetObject(hbmp, sizeof(bm) * 2, &bm);
992     ok(ret == sizeof(bm), "wrong size %d\n", ret);
993
994     ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
995     ok(ret == 0, "%d != 0\n", ret);
996
997     ret = GetObject(hbmp, 0, &bm);
998     ok(ret == 0, "%d != 0\n", ret);
999
1000     ret = GetObject(hbmp, 1, &bm);
1001     ok(ret == 0, "%d != 0\n", ret);
1002
1003     DeleteObject(hbmp);
1004     DeleteDC(hdc);
1005 }
1006
1007 static void test_bmBits(void)
1008 {
1009     BYTE bits[4];
1010     HBITMAP hbmp;
1011     BITMAP bmp;
1012
1013     memset(bits, 0, sizeof(bits));
1014     hbmp = CreateBitmap(2, 2, 1, 4, bits);
1015     ok(hbmp != NULL, "CreateBitmap failed\n");
1016
1017     memset(&bmp, 0xFF, sizeof(bmp));
1018     ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1019        "GetObject failed or returned a wrong structure size\n");
1020     ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1021
1022     DeleteObject(hbmp);
1023 }
1024
1025 static void test_GetDIBits_selected_DIB(UINT bpp)
1026 {
1027     HBITMAP dib;
1028     BITMAPINFO * info;
1029     BITMAPINFO * info2;
1030     void * bits;
1031     void * bits2;
1032     UINT dib_size;
1033     HDC dib_dc, dc;
1034     HBITMAP old_bmp;
1035     BOOL equalContents;
1036     UINT i;
1037     int res;
1038
1039     /* Create a DIB section with a color table */
1040
1041     info  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD));
1042     info2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD));
1043     assert(info);
1044     assert(info2);
1045
1046     info->bmiHeader.biSize = sizeof(info->bmiHeader);
1047
1048     /* Choose width and height such that the row length (in bytes)
1049        is a multiple of 4 (makes things easier) */
1050     info->bmiHeader.biWidth = 32;
1051     info->bmiHeader.biHeight = 32;
1052     info->bmiHeader.biPlanes = 1;
1053     info->bmiHeader.biBitCount = bpp;
1054     info->bmiHeader.biCompression = BI_RGB;
1055
1056     for (i=0; i < (1u << bpp); i++)
1057     {
1058         BYTE c = i * (1 << (8 - bpp));
1059         info->bmiColors[i].rgbRed = c;
1060         info->bmiColors[i].rgbGreen = c;
1061         info->bmiColors[i].rgbBlue = c;
1062         info->bmiColors[i].rgbReserved = 0;
1063     }
1064
1065     dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1066     assert(dib);
1067     dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1068
1069     /* Set the bits of the DIB section */
1070     for (i=0; i < dib_size; i++)
1071     {
1072         ((BYTE *)bits)[i] = i % 256;
1073     }
1074
1075     /* Select the DIB into a DC */
1076     dib_dc = CreateCompatibleDC(NULL);
1077     old_bmp = (HBITMAP) SelectObject(dib_dc, dib);
1078     dc = CreateCompatibleDC(NULL);
1079     bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib_size);
1080     assert(bits2);
1081
1082     /* Copy the DIB attributes but not the color table */
1083     memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1084
1085     res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1086     ok(res, "GetDIBits failed\n");
1087
1088     /* Compare the color table and the bits */
1089     equalContents = TRUE;
1090     for (i=0; i < (1u << bpp); i++)
1091     {
1092         if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed)
1093             || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen)
1094             || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue)
1095             || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved))
1096         {
1097             equalContents = FALSE;
1098             break;
1099         }
1100     }
1101     ok(equalContents, "GetDIBits with DIB selected in DC: Invalid DIB color table\n");
1102
1103     equalContents = TRUE;
1104     for (i=0; i < dib_size / sizeof(DWORD); i++)
1105     {
1106         if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i])
1107         {
1108             equalContents = FALSE;
1109             break;
1110         }
1111     }
1112     if (bpp != 1)
1113         ok(equalContents, "GetDIBits with %d bpp DIB selected in DC: Invalid DIB bits\n",bpp);
1114     else
1115         todo_wine ok(equalContents, "GetDIBits with %d bpp DIB selected in DC: Invalid DIB bits\n",bpp);
1116
1117     HeapFree(GetProcessHeap(), 0, bits2);
1118     DeleteDC(dc);
1119
1120     SelectObject(dib_dc, old_bmp);
1121     DeleteDC(dib_dc);
1122     DeleteObject(dib);
1123
1124     HeapFree(GetProcessHeap(), 0, info2);
1125     HeapFree(GetProcessHeap(), 0, info);
1126 }
1127
1128 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1129 {
1130     HBITMAP ddb;
1131     BITMAPINFO * info;
1132     BITMAPINFO * info2;
1133     void * bits;
1134     void * bits2;
1135     HDC ddb_dc, dc;
1136     HBITMAP old_bmp;
1137     BOOL equalContents;
1138     UINT width, height;
1139     UINT bpp;
1140     UINT i, j;
1141     int res;
1142
1143     width = height = 16;
1144
1145     /* Create a DDB (device-dependent bitmap) */
1146     if (monochrome)
1147     {
1148         bpp = 1;
1149         ddb = CreateBitmap(width, height, 1, 1, NULL);
1150     }
1151     else
1152     {
1153         HDC screen_dc = GetDC(NULL);
1154         bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1155         ddb = CreateCompatibleBitmap(screen_dc, width, height);
1156         ReleaseDC(NULL, screen_dc);
1157     }
1158
1159     /* Set the pixels */
1160     ddb_dc = CreateCompatibleDC(NULL);
1161     old_bmp = (HBITMAP) SelectObject(ddb_dc, ddb);
1162     for (i = 0; i < width; i++)
1163     {
1164         for (j=0; j < height; j++)
1165         {
1166             BYTE c = (i * width + j) % 256;
1167             SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1168         }
1169     }
1170     SelectObject(ddb_dc, old_bmp);
1171
1172     info  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1173     info2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1174     assert(info);
1175     assert(info2);
1176
1177     info->bmiHeader.biSize = sizeof(info->bmiHeader);
1178     info->bmiHeader.biWidth = width;
1179     info->bmiHeader.biHeight = height;
1180     info->bmiHeader.biPlanes = 1;
1181     info->bmiHeader.biBitCount = bpp;
1182     info->bmiHeader.biCompression = BI_RGB;
1183
1184     dc = CreateCompatibleDC(NULL);
1185
1186     /* Fill in biSizeImage */
1187     GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1188     ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1189
1190     bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1191     bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1192     assert(bits);
1193     assert(bits2);
1194
1195     /* Get the bits */
1196     res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1197     ok(res, "GetDIBits failed\n");
1198
1199     /* Copy the DIB attributes but not the color table */
1200     memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1201
1202     /* Select the DDB into another DC */
1203     old_bmp = (HBITMAP) SelectObject(ddb_dc, ddb);
1204
1205     /* Get the bits */
1206     res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1207     ok(res, "GetDIBits failed\n");
1208
1209     /* Compare the color table and the bits */
1210     if (bpp <= 8)
1211     {
1212         equalContents = TRUE;
1213         for (i=0; i < (1u << bpp); i++)
1214         {
1215             if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed)
1216                 || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen)
1217                 || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue)
1218                 || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved))
1219             {
1220                 equalContents = FALSE;
1221                 break;
1222             }
1223         }
1224         ok(equalContents, "GetDIBits with DDB selected in DC: Got a different color table\n");
1225     }
1226
1227     equalContents = TRUE;
1228     for (i=0; i < info->bmiHeader.biSizeImage / sizeof(DWORD); i++)
1229     {
1230         if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i])
1231         {
1232             equalContents = FALSE;
1233         }
1234     }
1235     ok(equalContents, "GetDIBits with DDB selected in DC: Got different DIB bits\n");
1236
1237     HeapFree(GetProcessHeap(), 0, bits2);
1238     HeapFree(GetProcessHeap(), 0, bits);
1239     DeleteDC(dc);
1240
1241     SelectObject(ddb_dc, old_bmp);
1242     DeleteDC(ddb_dc);
1243     DeleteObject(ddb);
1244
1245     HeapFree(GetProcessHeap(), 0, info2);
1246     HeapFree(GetProcessHeap(), 0, info);
1247 }
1248
1249 static void test_GetDIBits(void)
1250 {
1251     /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1252     static const BYTE bmp_bits_1[16 * 2] =
1253     {
1254         0xff,0xff, 0,0, 0xff,0xff, 0,0,
1255         0xff,0xff, 0,0, 0xff,0xff, 0,0,
1256         0xff,0xff, 0,0, 0xff,0xff, 0,0,
1257         0xff,0xff, 0,0, 0xff,0xff, 0,0
1258     };
1259     /* 4-bytes aligned 1-bit DIB data: 16x16 */
1260     static const BYTE dib_bits_1[16 * 4] =
1261     {
1262         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1263         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1264         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1265         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1266     };
1267     /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1268     static const BYTE bmp_bits_24[16 * 16*3] =
1269     {
1270         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1271         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1272         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1273         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1274         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1275         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1276         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1277         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1278         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1279         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1280         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1281         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1282         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1283         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1284         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1285         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1286         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1287         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1288         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1289         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1290         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1291         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1292         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1293         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1294         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1295         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1296         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1297         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1298         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1299         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1300         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1301         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1302     };
1303     /* 4-bytes aligned 24-bit DIB data: 16x16 */
1304     static const BYTE dib_bits_24[16 * 16*3] =
1305     {
1306         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1307         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1308         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1309         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1310         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1311         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1312         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1313         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1314         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1315         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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     };
1339     HBITMAP hbmp;
1340     BITMAP bm;
1341     HDC hdc;
1342     int i, bytes, lines;
1343     BYTE buf[1024];
1344     char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1345     BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1346
1347     hdc = GetDC(0);
1348
1349     /* 1-bit source bitmap data */
1350     hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1351     ok(hbmp != 0, "CreateBitmap failed\n");
1352
1353     memset(&bm, 0xAA, sizeof(bm));
1354     bytes = GetObject(hbmp, sizeof(bm), &bm);
1355     ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1356     ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1357     ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1358     ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1359     ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1360     ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1361     ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1362     ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1363
1364     bytes = GetBitmapBits(hbmp, 0, NULL);
1365     ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1366     bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1367     ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1368     ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1369
1370     /* retrieve 1-bit DIB data */
1371     memset(bi, 0, sizeof(*bi));
1372     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1373     bi->bmiHeader.biWidth = bm.bmWidth;
1374     bi->bmiHeader.biHeight = bm.bmHeight;
1375     bi->bmiHeader.biPlanes = 1;
1376     bi->bmiHeader.biBitCount = 1;
1377     bi->bmiHeader.biCompression = BI_RGB;
1378     bi->bmiHeader.biSizeImage = 0;
1379     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1380     SetLastError(0xdeadbeef);
1381     lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1382     ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1383     ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
1384     ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1385
1386     memset(buf, 0xAA, sizeof(buf));
1387     SetLastError(0xdeadbeef);
1388     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1389     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1390        lines, bm.bmHeight, GetLastError());
1391     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1392
1393     /* the color table consists of black and white */
1394     ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1395        bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1396        "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1397        bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1398        bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1399 todo_wine
1400     ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1401        bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1402        "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1403        bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1404        bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1405     for (i = 2; i < 256; i++)
1406     {
1407         ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1408            bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1409            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1410            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1411            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1412     }
1413
1414     /* returned bits are DWORD aligned and upside down */
1415 todo_wine
1416     ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1417
1418     /* retrieve 24-bit DIB data */
1419     memset(bi, 0, sizeof(*bi));
1420     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1421     bi->bmiHeader.biWidth = bm.bmWidth;
1422     bi->bmiHeader.biHeight = bm.bmHeight;
1423     bi->bmiHeader.biPlanes = 1;
1424     bi->bmiHeader.biBitCount = 24;
1425     bi->bmiHeader.biCompression = BI_RGB;
1426     bi->bmiHeader.biSizeImage = 0;
1427     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1428     memset(buf, 0xAA, sizeof(buf));
1429     SetLastError(0xdeadbeef);
1430     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1431     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1432        lines, bm.bmHeight, GetLastError());
1433     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1434
1435     /* the color table doesn't exist for 24-bit images */
1436     for (i = 0; i < 256; i++)
1437     {
1438         ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1439            bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1440            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1441            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1442            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1443     }
1444
1445     /* returned bits are DWORD aligned and upside down */
1446 todo_wine
1447     ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1448     DeleteObject(hbmp);
1449
1450     /* 24-bit source bitmap data */
1451     hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1452     ok(hbmp != 0, "CreateBitmap failed\n");
1453     SetLastError(0xdeadbeef);
1454     bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1455     lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1456     ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1457        lines, bm.bmHeight, GetLastError());
1458
1459     memset(&bm, 0xAA, sizeof(bm));
1460     bytes = GetObject(hbmp, sizeof(bm), &bm);
1461     ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1462     ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1463     ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1464     ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1465     ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1466     ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1467     ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1468     ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1469
1470     bytes = GetBitmapBits(hbmp, 0, NULL);
1471     ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1472        bm.bmWidthBytes * bm.bmHeight, bytes);
1473     bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1474     ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1475        bm.bmWidthBytes * bm.bmHeight, bytes);
1476
1477     /* retrieve 1-bit DIB data */
1478     memset(bi, 0, sizeof(*bi));
1479     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1480     bi->bmiHeader.biWidth = bm.bmWidth;
1481     bi->bmiHeader.biHeight = bm.bmHeight;
1482     bi->bmiHeader.biPlanes = 1;
1483     bi->bmiHeader.biBitCount = 1;
1484     bi->bmiHeader.biCompression = BI_RGB;
1485     bi->bmiHeader.biSizeImage = 0;
1486     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1487     memset(buf, 0xAA, sizeof(buf));
1488     SetLastError(0xdeadbeef);
1489     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1490     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1491        lines, bm.bmHeight, GetLastError());
1492     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1493
1494     /* the color table consists of black and white */
1495     ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1496        bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1497        "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1498        bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1499        bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1500     ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1501        bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1502        "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1503        bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1504        bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1505     for (i = 2; i < 256; i++)
1506     {
1507         ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1508            bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1509            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1510            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1511            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1512     }
1513
1514     /* returned bits are DWORD aligned and upside down */
1515 todo_wine
1516     ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1517
1518     /* retrieve 24-bit DIB data */
1519     memset(bi, 0, sizeof(*bi));
1520     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1521     bi->bmiHeader.biWidth = bm.bmWidth;
1522     bi->bmiHeader.biHeight = bm.bmHeight;
1523     bi->bmiHeader.biPlanes = 1;
1524     bi->bmiHeader.biBitCount = 24;
1525     bi->bmiHeader.biCompression = BI_RGB;
1526     bi->bmiHeader.biSizeImage = 0;
1527     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1528     memset(buf, 0xAA, sizeof(buf));
1529     SetLastError(0xdeadbeef);
1530     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1531     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1532        lines, bm.bmHeight, GetLastError());
1533     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1534
1535     /* the color table doesn't exist for 24-bit images */
1536     for (i = 0; i < 256; i++)
1537     {
1538         ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1539            bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1540            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1541            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1542            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1543     }
1544
1545     /* returned bits are DWORD aligned and upside down */
1546     ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1547     DeleteObject(hbmp);
1548
1549     ReleaseDC(0, hdc);
1550 }
1551
1552 static void test_select_object(void)
1553 {
1554     HDC hdc;
1555     HBITMAP hbm, hbm_old;
1556     INT planes, bpp;
1557
1558     hdc = GetDC(0);
1559     ok(hdc != 0, "GetDC(0) failed\n");
1560     hbm = CreateCompatibleBitmap(hdc, 10, 10);
1561     ok(hbm != 0, "CreateCompatibleBitmap failed\n");
1562
1563     hbm_old = SelectObject(hdc, hbm);
1564     ok(hbm_old == 0, "SelectObject should fail\n");
1565
1566     DeleteObject(hbm);
1567     ReleaseDC(0, hdc);
1568
1569     hdc = CreateCompatibleDC(0);
1570     ok(hdc != 0, "GetDC(0) failed\n");
1571     hbm = CreateCompatibleBitmap(hdc, 10, 10);
1572     ok(hbm != 0, "CreateCompatibleBitmap failed\n");
1573
1574     hbm_old = SelectObject(hdc, hbm);
1575     ok(hbm_old != 0, "SelectObject failed\n");
1576     hbm_old = SelectObject(hdc, hbm_old);
1577     ok(hbm_old == hbm, "SelectObject failed\n");
1578
1579     DeleteObject(hbm);
1580
1581     /* test an 1-bpp bitmap */
1582     planes = GetDeviceCaps(hdc, PLANES);
1583     bpp = 1;
1584
1585     hbm = CreateBitmap(10, 10, planes, bpp, NULL);
1586     ok(hbm != 0, "CreateBitmap failed\n");
1587
1588     hbm_old = SelectObject(hdc, hbm);
1589     ok(hbm_old != 0, "SelectObject failed\n");
1590     hbm_old = SelectObject(hdc, hbm_old);
1591     ok(hbm_old == hbm, "SelectObject failed\n");
1592
1593     DeleteObject(hbm);
1594
1595     /* test a color bitmap that doesn't match the dc's bpp */
1596     planes = GetDeviceCaps(hdc, PLANES);
1597     bpp = GetDeviceCaps(hdc, BITSPIXEL) == 24 ? 8 : 24;
1598
1599     hbm = CreateBitmap(10, 10, planes, bpp, NULL);
1600     ok(hbm != 0, "CreateBitmap failed\n");
1601
1602     hbm_old = SelectObject(hdc, hbm);
1603     ok(hbm_old == 0, "SelectObject should fail\n");
1604
1605     DeleteObject(hbm);
1606
1607     DeleteDC(hdc);
1608 }
1609
1610 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
1611 {
1612     INT ret;
1613     BITMAP bm;
1614
1615     ret = GetObjectType(hbmp);
1616     ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
1617
1618     ret = GetObject(hbmp, 0, 0);
1619     ok_(__FILE__, line)(ret == sizeof(BITMAP) /* XP */ ||
1620                         ret == sizeof(DIBSECTION) /* Win9x */, "object size %d\n", ret);
1621
1622     memset(&bm, 0xDA, sizeof(bm));
1623     SetLastError(0xdeadbeef);
1624     ret = GetObject(hbmp, sizeof(bm), &bm);
1625     if (!ret) /* XP, only for curObj2 */ return;
1626     ok_(__FILE__, line)(ret == sizeof(BITMAP) ||
1627                         ret == sizeof(DIBSECTION) /* Win9x, only for curObj2 */,
1628                         "GetObject returned %d, error %u\n", ret, GetLastError());
1629     ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1630     ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth %d\n", bm.bmWidth);
1631     ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight %d\n", bm.bmHeight);
1632     ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1633     ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1634     ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1635     ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1636 }
1637
1638 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
1639
1640 static void test_CreateBitmap(void)
1641 {
1642     BITMAP bmp;
1643     HDC screenDC = GetDC(0);
1644     HDC hdc = CreateCompatibleDC(screenDC);
1645
1646     /* all of these are the stock monochrome bitmap */
1647     HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
1648     HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
1649     HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
1650     HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
1651     HBITMAP curObj1 = (HBITMAP)GetCurrentObject(hdc, OBJ_BITMAP);
1652     HBITMAP curObj2 = (HBITMAP)GetCurrentObject(screenDC, OBJ_BITMAP);
1653
1654     /* these 2 are not the stock monochrome bitmap */
1655     HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
1656     HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
1657
1658     HBITMAP old1 = (HBITMAP)SelectObject(hdc, bm2);
1659     HBITMAP old2 = (HBITMAP)SelectObject(screenDC, bm3);
1660     SelectObject(hdc, old1);
1661     SelectObject(screenDC, old2);
1662
1663     ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
1664        "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
1665        bm, bm1, bm4, bm5, curObj1, old1);
1666     ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
1667     ok(bm != curObj2 /* XP */ || bm == curObj2 /* Win9x */,
1668        "0: %p, curObj2 %p\n", bm, curObj2);
1669     ok(old2 == 0, "old2 %p\n", old2);
1670
1671     test_mono_1x1_bmp(bm);
1672     test_mono_1x1_bmp(bm1);
1673     test_mono_1x1_bmp(bm2);
1674     test_mono_1x1_bmp(bm3);
1675     test_mono_1x1_bmp(bm4);
1676     test_mono_1x1_bmp(bm5);
1677     test_mono_1x1_bmp(old1);
1678     test_mono_1x1_bmp(curObj1);
1679     test_mono_1x1_bmp(curObj2);
1680
1681     DeleteObject(bm);
1682     DeleteObject(bm1);
1683     DeleteObject(bm2);
1684     DeleteObject(bm3);
1685     DeleteObject(bm4);
1686     DeleteObject(bm5);
1687
1688     DeleteDC(hdc);
1689     ReleaseDC(0, screenDC);
1690
1691     /* show that Windows ignores the provided bm.bmWidthBytes */
1692     bmp.bmType = 0;
1693     bmp.bmWidth = 1;
1694     bmp.bmHeight = 1;
1695     bmp.bmWidthBytes = 28;
1696     bmp.bmPlanes = 1;
1697     bmp.bmBitsPixel = 1;
1698     bmp.bmBits = NULL;
1699     bm = CreateBitmapIndirect(&bmp);
1700     ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
1701     test_mono_1x1_bmp(bm);
1702     DeleteObject(bm);
1703 }
1704
1705 static void test_bitmapinfoheadersize(void)
1706 {
1707     HBITMAP hdib;
1708     BITMAPINFO bmi;
1709     BITMAPCOREINFO bci;
1710     HDC hdc = GetDC(0);
1711
1712     memset(&bmi, 0, sizeof(BITMAPINFO));
1713     bmi.bmiHeader.biHeight = 100;
1714     bmi.bmiHeader.biWidth = 512;
1715     bmi.bmiHeader.biBitCount = 24;
1716     bmi.bmiHeader.biPlanes = 1;
1717
1718     bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
1719
1720     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1721     ok(hdib == NULL, "CreateDIBSection succeeded\n");
1722
1723     bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1724
1725     SetLastError(0xdeadbeef);
1726     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1727     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1728     DeleteObject(hdib);
1729
1730     bmi.bmiHeader.biSize++;
1731
1732     SetLastError(0xdeadbeef);
1733     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1734     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1735     DeleteObject(hdib);
1736
1737     bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
1738
1739     SetLastError(0xdeadbeef);
1740     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1741     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1742     DeleteObject(hdib);
1743
1744     bmi.bmiHeader.biSize++;
1745
1746     SetLastError(0xdeadbeef);
1747     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1748     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1749     DeleteObject(hdib);
1750
1751     bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
1752
1753     SetLastError(0xdeadbeef);
1754     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1755     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1756     DeleteObject(hdib);
1757
1758     bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
1759
1760     SetLastError(0xdeadbeef);
1761     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
1762     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1763     DeleteObject(hdib);
1764
1765     memset(&bci, 0, sizeof(BITMAPCOREINFO));
1766     bci.bmciHeader.bcHeight = 100;
1767     bci.bmciHeader.bcWidth = 512;
1768     bci.bmciHeader.bcBitCount = 24;
1769     bci.bmciHeader.bcPlanes = 1;
1770
1771     bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
1772
1773     hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
1774     ok(hdib == NULL, "CreateDIBSection succeeded\n");
1775
1776     bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
1777
1778     SetLastError(0xdeadbeef);
1779     hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
1780     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
1781     DeleteObject(hdib);
1782
1783     bci.bmciHeader.bcSize++;
1784
1785     hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
1786     ok(hdib == NULL, "CreateDIBSection succeeded\n");
1787
1788     bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
1789
1790     hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
1791     ok(hdib == NULL, "CreateDIBSection succeeded\n");
1792
1793     ReleaseDC(0, hdc);
1794 }
1795
1796 static void test_get16dibits(void)
1797 {
1798     BYTE bits[4 * (16 / sizeof(BYTE))];
1799     HBITMAP hbmp;
1800     HDC screen_dc = GetDC(NULL);
1801     int ret;
1802     BITMAPINFO * info;
1803     int info_len = sizeof(BITMAPINFOHEADER) + 1024;
1804     BYTE *p;
1805     int overwritten_bytes = 0;
1806
1807     memset(bits, 0, sizeof(bits));
1808     hbmp = CreateBitmap(2, 2, 1, 16, bits);
1809     ok(hbmp != NULL, "CreateBitmap failed\n");
1810
1811     info  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
1812     assert(info);
1813
1814     memset(info, '!', info_len);
1815     memset(info, 0, sizeof(info->bmiHeader));
1816
1817     info->bmiHeader.biSize = sizeof(info->bmiHeader);
1818     info->bmiHeader.biWidth = 2;
1819     info->bmiHeader.biHeight = 2;
1820     info->bmiHeader.biPlanes = 1;
1821     info->bmiHeader.biCompression = BI_RGB;
1822
1823     ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
1824     ok(ret != 0, "GetDIBits failed\n");
1825
1826     for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
1827         if (*p != '!')
1828             overwritten_bytes++;
1829     ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
1830
1831     DeleteObject(hbmp);
1832     ReleaseDC(NULL, screen_dc);
1833 }
1834
1835 void test_GdiAlphaBlend()
1836 {
1837     /* test out-of-bound parameters for GdiAlphaBlend */
1838     HDC hdcNull = GetDC(NULL);
1839
1840     HDC hdcDst = CreateCompatibleDC(hdcNull);
1841     HBITMAP bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
1842     HBITMAP oldDst;
1843
1844     BITMAPINFO bmi;
1845     HDC hdcSrc = CreateCompatibleDC(hdcNull);
1846     HBITMAP bmpSrc;
1847     HBITMAP oldSrc;
1848     LPVOID bits;
1849
1850     BLENDFUNCTION blend;
1851
1852     memset(&bmi, 0, sizeof(bmi));  /* as of Wine 0.9.44 we require the src to be a DIB section */
1853     bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
1854     bmi.bmiHeader.biHeight = 20;
1855     bmi.bmiHeader.biWidth = 20;
1856     bmi.bmiHeader.biBitCount = 32;
1857     bmi.bmiHeader.biPlanes = 1;
1858     bmi.bmiHeader.biCompression = BI_RGB;
1859     bmpSrc = CreateDIBSection(hdcDst, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
1860     ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
1861
1862     oldDst = (HBITMAP)SelectObject(hdcDst, bmpDst);
1863     oldSrc = (HBITMAP)SelectObject(hdcSrc, bmpSrc);
1864
1865     blend.BlendOp = AC_SRC_OVER;
1866     blend.BlendFlags = 0;
1867     blend.SourceConstantAlpha = 128;
1868     blend.AlphaFormat = 0;
1869
1870     expect_eq(GdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend), TRUE, BOOL, "%d");
1871     SetLastError(0xdeadbeef);
1872     expect_eq(GdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), FALSE, BOOL, "%d");
1873     expect_eq(GetLastError(), ERROR_INVALID_PARAMETER, int, "%d");
1874     expect_eq(GdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), FALSE, BOOL, "%d");
1875     expect_eq(GdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend), FALSE, BOOL, "%d");
1876     expect_eq(GdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
1877     expect_eq(GdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
1878
1879     SetWindowOrgEx(hdcSrc, -10, -10, NULL);
1880     expect_eq(GdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), TRUE, BOOL, "%d");
1881     expect_eq(GdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), TRUE, BOOL, "%d");
1882     SetMapMode(hdcSrc, MM_ANISOTROPIC);
1883     ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
1884     expect_eq(GdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend), TRUE, BOOL, "%d");
1885     expect_eq(GdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend), TRUE, BOOL, "%d");
1886
1887     SelectObject(hdcDst, oldDst);
1888     SelectObject(hdcSrc, oldSrc);
1889     DeleteObject(bmpSrc);
1890     DeleteObject(bmpDst);
1891     DeleteDC(hdcDst);
1892     DeleteDC(hdcSrc);
1893
1894     ReleaseDC(NULL, hdcNull);
1895
1896 }
1897
1898 START_TEST(bitmap)
1899 {
1900     is_win9x = GetWindowLongPtrW(GetDesktopWindow(), GWLP_WNDPROC) == 0;
1901
1902     test_createdibitmap();
1903     test_dibsections();
1904     test_mono_dibsection();
1905     test_bitmap();
1906     test_bmBits();
1907     test_GetDIBits_selected_DIB(1);
1908     test_GetDIBits_selected_DIB(4);
1909     test_GetDIBits_selected_DIB(8);
1910     test_GetDIBits_selected_DDB(TRUE);
1911     test_GetDIBits_selected_DDB(FALSE);
1912     test_GetDIBits();
1913     test_select_object();
1914     test_CreateBitmap();
1915     test_GdiAlphaBlend();
1916     test_bitmapinfoheadersize();
1917     test_get16dibits();
1918 }