mshtml: Added beginning OnDataAvailable implementation.
[wine] / dlls / gdi / 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
25 #include "windef.h"
26 #include "winbase.h"
27 #include "wingdi.h"
28 #include "winuser.h"
29 #include "mmsystem.h"
30
31 #include "wine/test.h"
32
33 static BOOL is_win9x;
34
35 static INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp )
36 {
37     switch(bpp)
38     {
39     case 1:
40         return 2 * ((bmWidth+15) >> 4);
41
42     case 24:
43         bmWidth *= 3; /* fall through */
44     case 8:
45         return bmWidth + (bmWidth & 1);
46
47     case 32:
48         return bmWidth * 4;
49
50     case 16:
51     case 15:
52         return bmWidth * 2;
53
54     case 4:
55         return 2 * ((bmWidth+3) >> 2);
56
57     default:
58         trace("Unknown depth %d, please report.\n", bpp );
59         assert(0);
60     }
61     return -1;
62 }
63
64 static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHEADER *bmih)
65 {
66     BITMAP bm;
67     INT ret, width_bytes;
68     char buf[512], buf_cmp[512];
69
70     ret = GetObject(hbm, sizeof(bm), &bm);
71     ok(ret == sizeof(bm), "GetObject returned %d instead of %d\n", ret, sizeof(bm));
72
73     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
74     ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
75     ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
76     width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
77     ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
78     ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
79     ok(bm.bmBitsPixel == expected_depth, "wrong bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, expected_depth);
80     ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
81
82     assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
83     assert(sizeof(buf) == sizeof(buf_cmp));
84
85     ret = GetBitmapBits(hbm, 0, NULL);
86     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
87
88     memset(buf_cmp, 0xAA, sizeof(buf_cmp));
89     memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
90
91     memset(buf, 0xAA, sizeof(buf));
92     ret = GetBitmapBits(hbm, sizeof(buf), buf);
93     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
94     ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
95
96     /* test various buffer sizes for GetObject */
97     ret = GetObject(hbm, 0, NULL);
98     ok(ret == sizeof(bm), "%d != %d\n", ret, sizeof(bm));
99
100     ret = GetObject(hbm, sizeof(bm) * 2, &bm);
101     ok(ret == sizeof(bm), "%d != %d\n", ret, sizeof(bm));
102
103     ret = GetObject(hbm, sizeof(bm) / 2, &bm);
104     ok(ret == 0, "%d != 0\n", ret);
105
106     ret = GetObject(hbm, 0, &bm);
107     ok(ret == 0, "%d != 0\n", ret);
108
109     ret = GetObject(hbm, 1, &bm);
110     ok(ret == 0, "%d != 0\n", ret);
111 }
112
113 static void test_createdibitmap(void)
114 {
115     HDC hdc, hdcmem;
116     BITMAPINFOHEADER bmih;
117     HBITMAP hbm, hbm_colour, hbm_old;
118     INT screen_depth;
119
120     hdc = GetDC(0);
121     screen_depth = GetDeviceCaps(hdc, BITSPIXEL);
122     memset(&bmih, 0, sizeof(bmih));
123     bmih.biSize = sizeof(bmih);
124     bmih.biWidth = 10;
125     bmih.biHeight = 10;
126     bmih.biPlanes = 1;
127     bmih.biBitCount = 32;
128     bmih.biCompression = BI_RGB;
129  
130     /* First create an un-initialised bitmap.  The depth of the bitmap
131        should match that of the hdc and not that supplied in bmih.
132     */
133
134     /* First try 32 bits */
135     hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
136     ok(hbm != NULL, "CreateDIBitmap failed\n");
137     test_bitmap_info(hbm, screen_depth, &bmih);
138     DeleteObject(hbm);
139     
140     /* Then 16 */
141     bmih.biBitCount = 16;
142     hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
143     ok(hbm != NULL, "CreateDIBitmap failed\n");
144     test_bitmap_info(hbm, screen_depth, &bmih);
145     DeleteObject(hbm);
146
147     /* Then 1 */
148     bmih.biBitCount = 1;
149     hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
150     ok(hbm != NULL, "CreateDIBitmap failed\n");
151     test_bitmap_info(hbm, screen_depth, &bmih);
152     DeleteObject(hbm);
153
154     /* Now with a monochrome dc we expect a monochrome bitmap */
155     hdcmem = CreateCompatibleDC(hdc);
156
157     /* First try 32 bits */
158     bmih.biBitCount = 32;
159     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
160     ok(hbm != NULL, "CreateDIBitmap failed\n");
161     test_bitmap_info(hbm, 1, &bmih);
162     DeleteObject(hbm);
163     
164     /* Then 16 */
165     bmih.biBitCount = 16;
166     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
167     ok(hbm != NULL, "CreateDIBitmap failed\n");
168     test_bitmap_info(hbm, 1, &bmih);
169     DeleteObject(hbm);
170     
171     /* Then 1 */
172     bmih.biBitCount = 1;
173     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
174     ok(hbm != NULL, "CreateDIBitmap failed\n");
175     test_bitmap_info(hbm, 1, &bmih);
176     DeleteObject(hbm);
177
178     /* Now select a polychrome bitmap into the dc and we expect
179        screen_depth bitmaps again */
180     hbm_colour = CreateCompatibleBitmap(hdc, 1, 1);
181     hbm_old = SelectObject(hdcmem, hbm_colour);
182
183     /* First try 32 bits */
184     bmih.biBitCount = 32;
185     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
186     ok(hbm != NULL, "CreateDIBitmap failed\n");
187     test_bitmap_info(hbm, screen_depth, &bmih);
188     DeleteObject(hbm);
189     
190     /* Then 16 */
191     bmih.biBitCount = 16;
192     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
193     ok(hbm != NULL, "CreateDIBitmap failed\n");
194     test_bitmap_info(hbm, screen_depth, &bmih);
195     DeleteObject(hbm);
196     
197     /* Then 1 */
198     bmih.biBitCount = 1;
199     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
200     ok(hbm != NULL, "CreateDIBitmap failed\n");
201     test_bitmap_info(hbm, screen_depth, &bmih);
202     DeleteObject(hbm);
203
204     SelectObject(hdcmem, hbm_old);
205     DeleteObject(hbm_colour);
206     DeleteDC(hdcmem);
207
208     /* If hdc == 0 then we get a 1 bpp bitmap */
209     if (!is_win9x) {
210         bmih.biBitCount = 32;
211         hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0);
212         ok(hbm != NULL, "CreateDIBitmap failed\n");
213         test_bitmap_info(hbm, 1, &bmih);
214         DeleteObject(hbm);
215     }
216     
217     ReleaseDC(0, hdc);
218 }
219
220 static INT DIB_GetWidthBytes( int width, int bpp )
221 {
222     int words;
223
224     switch (bpp)
225     {
226         case 1:  words = (width + 31) / 32; break;
227         case 4:  words = (width + 7) / 8; break;
228         case 8:  words = (width + 3) / 4; break;
229         case 15:
230         case 16: words = (width + 1) / 2; break;
231         case 24: words = (width * 3 + 3)/4; break;
232         case 32: words = width; break;
233
234         default:
235             words=0;
236             trace("Unknown depth %d, please report.\n", bpp );
237             assert(0);
238             break;
239     }
240     return 4 * words;
241 }
242
243 static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
244 {
245     BITMAP bm;
246     DIBSECTION ds;
247     INT ret, width_bytes;
248     BYTE *buf;
249
250     ret = GetObject(hbm, sizeof(bm), &bm);
251     ok(ret == sizeof(bm), "GetObject returned %d instead of %d\n", ret, sizeof(bm));
252
253     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
254     ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
255     ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
256     width_bytes = DIB_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
257     ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
258     ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
259     ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount);
260     ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
261
262     buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);
263
264     width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
265
266     /* GetBitmapBits returns not 32-bit aligned data */
267     ret = GetBitmapBits(hbm, 0, NULL);
268     ok(ret == width_bytes * bm.bmHeight, "%d != %d\n", ret, width_bytes * bm.bmHeight);
269
270     memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
271     ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
272     ok(ret == width_bytes * bm.bmHeight, "%d != %d\n", ret, width_bytes * bm.bmHeight);
273
274     HeapFree(GetProcessHeap(), 0, buf);
275
276     /* test various buffer sizes for GetObject */
277     memset(&ds, 0xAA, sizeof(ds));
278     ret = GetObject(hbm, sizeof(bm) * 2, &bm);
279     ok(ret == sizeof(bm), "%d != %d\n", ret, sizeof(bm));
280     ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
281     ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
282     ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
283
284     ret = GetObject(hbm, sizeof(bm) / 2, &bm);
285     ok(ret == 0, "%d != 0\n", ret);
286
287     ret = GetObject(hbm, 0, &bm);
288     ok(ret == 0, "%d != 0\n", ret);
289
290     ret = GetObject(hbm, 1, &bm);
291     ok(ret == 0, "%d != 0\n", ret);
292
293     /* test various buffer sizes for GetObject */
294     ret = GetObject(hbm, 0, NULL);
295     ok(ret == sizeof(bm), "%d != %d\n", ret, sizeof(bm));
296
297     memset(&ds, 0xAA, sizeof(ds));
298     ret = GetObject(hbm, sizeof(ds) * 2, &ds);
299     ok(ret == sizeof(ds), "%d != %d\n", ret, sizeof(ds));
300
301     ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
302     ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%lu != %u\n",
303        ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
304     ok(bmih->biSizeImage == 0, "%lu != 0\n", bmih->biSizeImage);
305     ds.dsBmih.biSizeImage = 0;
306
307     ok(ds.dsBmih.biSize == bmih->biSize, "%lu != %lu\n", ds.dsBmih.biSize, bmih->biSize);
308     ok(ds.dsBmih.biWidth == bmih->biWidth, "%lu != %lu\n", ds.dsBmih.biWidth, bmih->biWidth);
309     ok(ds.dsBmih.biHeight == bmih->biHeight, "%lu != %lu\n", ds.dsBmih.biHeight, bmih->biHeight);
310     ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes);
311     ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount);
312     ok(ds.dsBmih.biCompression == bmih->biCompression, "%lu != %lu\n", ds.dsBmih.biCompression, bmih->biCompression);
313     ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%lu != %lu\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
314     ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%lu != %lu\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
315     ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%lu != %lu\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);
316
317     memset(&ds, 0xAA, sizeof(ds));
318     ret = GetObject(hbm, sizeof(ds) - 4, &ds);
319     ok(ret == sizeof(ds.dsBm), "%d != %d\n", ret, sizeof(ds.dsBm));
320     ok(ds.dsBm.bmWidth == bmih->biWidth, "%lu != %lu\n", ds.dsBmih.biWidth, bmih->biWidth);
321     ok(ds.dsBm.bmHeight == bmih->biHeight, "%lu != %lu\n", ds.dsBmih.biHeight, bmih->biHeight);
322     ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);
323
324     ret = GetObject(hbm, 0, &ds);
325     ok(ret == 0, "%d != 0\n", ret);
326
327     ret = GetObject(hbm, 1, &ds);
328     ok(ret == 0, "%d != 0\n", ret);
329 }
330
331 #define test_color_todo(got, exp, txt, todo) \
332     if (!todo && got != exp && screen_depth < 24) { \
333       todo_wine ok(0, #txt " failed at %d-bit screen depth: got 0x%06x expected 0x%06x - skipping DIB tests\n", \
334                    screen_depth, (UINT)got, (UINT)exp); \
335       return; \
336     } else if (todo) todo_wine { ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp); } \
337     else ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp) \
338
339 #define test_color(hdc, color, exp, todo_setp, todo_getp) \
340 { \
341     COLORREF c; \
342     c = SetPixel(hdc, 0, 0, color); \
343     if (!is_win9x) { test_color_todo(c, exp, SetPixel, todo_setp); } \
344     c = GetPixel(hdc, 0, 0); \
345     test_color_todo(c, exp, GetPixel, todo_getp); \
346 }
347
348 static void test_dibsections(void)
349 {
350     HDC hdc, hdcmem, hdcmem2;
351     HBITMAP hdib, oldbm, hdib2, oldbm2;
352     char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
353     char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
354     BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
355     BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
356     HBITMAP hcoredib;
357     char coreBits[256];
358     BYTE *bits;
359     RGBQUAD rgb[256];
360     int ret;
361     char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
362     LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
363     WORD *index;
364     DWORD *bits32;
365     HPALETTE hpal, oldpal;
366     DIBSECTION dibsec;
367     COLORREF c0, c1;
368     int i;
369     int screen_depth;
370     MEMORY_BASIC_INFORMATION info;
371
372     hdc = GetDC(0);
373     screen_depth = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
374
375     memset(pbmi, 0, sizeof(bmibuf));
376     pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
377     pbmi->bmiHeader.biHeight = 100;
378     pbmi->bmiHeader.biWidth = 512;
379     pbmi->bmiHeader.biBitCount = 24;
380     pbmi->bmiHeader.biPlanes = 1;
381     pbmi->bmiHeader.biCompression = BI_RGB;
382
383     SetLastError(0xdeadbeef);
384     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
385     ok(hdib != NULL, "CreateDIBSection error %ld\n", GetLastError());
386     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
387     ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
388
389     /* test the DIB memory */
390     ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
391         "VirtualQuery failed\n");
392     ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
393     ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
394     ok(info.AllocationProtect == PAGE_READWRITE, "%lx != PAGE_READWRITE\n", info.AllocationProtect);
395     ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
396     ok(info.State == MEM_COMMIT, "%lx != MEM_COMMIT\n", info.State);
397     ok(info.Protect == PAGE_READWRITE, "%lx != PAGE_READWRITE\n", info.Protect);
398     ok(info.Type == MEM_PRIVATE, "%lx != MEM_PRIVATE\n", info.Type);
399
400     test_dib_info(hdib, bits, &pbmi->bmiHeader);
401     DeleteObject(hdib);
402
403     pbmi->bmiHeader.biBitCount = 8;
404     pbmi->bmiHeader.biCompression = BI_RLE8;
405     SetLastError(0xdeadbeef);
406     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
407     ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
408     ok(GetLastError() == 0xdeadbeef, "wrong error %ld\n", GetLastError());
409
410     pbmi->bmiHeader.biBitCount = 16;
411     pbmi->bmiHeader.biCompression = BI_BITFIELDS;
412     ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
413     ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
414     ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
415     SetLastError(0xdeadbeef);
416     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
417     ok(hdib != NULL, "CreateDIBSection error %ld\n", GetLastError());
418
419     /* test the DIB memory */
420     ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
421         "VirtualQuery failed\n");
422     ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
423     ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
424     ok(info.AllocationProtect == PAGE_READWRITE, "%lx != PAGE_READWRITE\n", info.AllocationProtect);
425     ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
426     ok(info.State == MEM_COMMIT, "%lx != MEM_COMMIT\n", info.State);
427     ok(info.Protect == PAGE_READWRITE, "%lx != PAGE_READWRITE\n", info.Protect);
428     ok(info.Type == MEM_PRIVATE, "%lx != MEM_PRIVATE\n", info.Type);
429
430     test_dib_info(hdib, bits, &pbmi->bmiHeader);
431     DeleteObject(hdib);
432
433     memset(pbmi, 0, sizeof(bmibuf));
434     pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
435     pbmi->bmiHeader.biHeight = 16;
436     pbmi->bmiHeader.biWidth = 16;
437     pbmi->bmiHeader.biBitCount = 1;
438     pbmi->bmiHeader.biPlanes = 1;
439     pbmi->bmiHeader.biCompression = BI_RGB;
440     pbmi->bmiColors[0].rgbRed = 0xff;
441     pbmi->bmiColors[0].rgbGreen = 0;
442     pbmi->bmiColors[0].rgbBlue = 0;
443     pbmi->bmiColors[1].rgbRed = 0;
444     pbmi->bmiColors[1].rgbGreen = 0;
445     pbmi->bmiColors[1].rgbBlue = 0xff;
446
447     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
448     ok(hdib != NULL, "CreateDIBSection failed\n");
449     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
450     ok(dibsec.dsBmih.biClrUsed == 2,
451         "created DIBSection: wrong biClrUsed field: %lu, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
452
453     /* Test if the old BITMAPCOREINFO structure is supported */    
454         
455     pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
456     pbci->bmciHeader.bcBitCount = 0;
457
458     if (!is_win9x) {
459         ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
460         ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
461         ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
462             && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
463         "GetDIBits did't fill in the BITMAPCOREHEADER structure properly\n");
464
465         ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
466         ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
467         ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
468             (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
469             (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
470             "The color table has not been translated to the old BITMAPCOREINFO format\n");
471
472         hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
473         ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
474
475         ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
476         ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
477         ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
478         ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
479             (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
480             (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
481             "The color table has not been translated to the old BITMAPCOREINFO format\n");
482
483         DeleteObject(hcoredib);
484     }
485
486     hdcmem = CreateCompatibleDC(hdc);
487     oldbm = SelectObject(hdcmem, hdib);
488
489     ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
490     ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
491     ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
492        "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
493        rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
494        rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
495
496     c0 = RGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen, pbmi->bmiColors[0].rgbBlue);
497     c1 = RGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen, pbmi->bmiColors[1].rgbBlue);
498
499     test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
500     test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
501     test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
502     test_color(hdcmem, PALETTEINDEX(0), c0, 1, 1);
503     test_color(hdcmem, PALETTEINDEX(1), c0, 1, 1);
504     test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
505     test_color(hdcmem, PALETTERGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen,
506         pbmi->bmiColors[0].rgbBlue), c0, 1, 1);
507     test_color(hdcmem, PALETTERGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen,
508         pbmi->bmiColors[1].rgbBlue), c1, 1, 1);
509     test_color(hdcmem, PALETTERGB(0, 0, 0), c0, 1, 1);
510     test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
511     test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1, 1, 1);
512
513     SelectObject(hdcmem, oldbm);
514     DeleteObject(hdib);
515
516     pbmi->bmiColors[0].rgbRed = 0xff;
517     pbmi->bmiColors[0].rgbGreen = 0xff;
518     pbmi->bmiColors[0].rgbBlue = 0xff;
519     pbmi->bmiColors[1].rgbRed = 0;
520     pbmi->bmiColors[1].rgbGreen = 0;
521     pbmi->bmiColors[1].rgbBlue = 0;
522
523     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
524     ok(hdib != NULL, "CreateDIBSection failed\n");
525
526     test_dib_info(hdib, bits, &pbmi->bmiHeader);
527
528     oldbm = SelectObject(hdcmem, hdib);
529
530     ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
531     ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
532     ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
533        "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
534        rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
535        rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
536
537     SelectObject(hdcmem, oldbm);
538     test_dib_info(hdib, bits, &pbmi->bmiHeader);
539     DeleteObject(hdib);
540
541     pbmi->bmiHeader.biBitCount = 4;
542     for (i = 0; i < 16; i++) {
543         pbmi->bmiColors[i].rgbRed = i;
544         pbmi->bmiColors[i].rgbGreen = 16-i;
545         pbmi->bmiColors[i].rgbBlue = 0;
546     }
547     hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
548     ok(hdib != NULL, "CreateDIBSection failed\n");
549     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
550     ok(dibsec.dsBmih.biClrUsed == 16,
551        "created DIBSection: wrong biClrUsed field: %lu, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
552     test_dib_info(hdib, bits, &pbmi->bmiHeader);
553     DeleteObject(hdib);
554
555     pbmi->bmiHeader.biBitCount = 8;
556
557     for (i = 0; i < 128; i++) {
558         pbmi->bmiColors[i].rgbRed = 255 - i * 2;
559         pbmi->bmiColors[i].rgbGreen = i * 2;
560         pbmi->bmiColors[i].rgbBlue = 0;
561         pbmi->bmiColors[255 - i].rgbRed = 0;
562         pbmi->bmiColors[255 - i].rgbGreen = i * 2;
563         pbmi->bmiColors[255 - i].rgbBlue = 255 - i * 2;
564     }
565     hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
566     ok(hdib != NULL, "CreateDIBSection failed\n");
567     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
568     ok(dibsec.dsBmih.biClrUsed == 256,
569         "created DIBSection: wrong biClrUsed field: %lu, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
570
571     oldbm = SelectObject(hdcmem, hdib);
572
573     for (i = 0; i < 256; i++) {
574         test_color(hdcmem, DIBINDEX(i), 
575             RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
576         test_color(hdcmem, PALETTERGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 
577             RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
578     }
579
580     SelectObject(hdcmem, oldbm);
581     test_dib_info(hdib, bits, &pbmi->bmiHeader);
582     DeleteObject(hdib);
583
584     pbmi->bmiHeader.biBitCount = 1;
585
586     /* Now create a palette and a palette indexed dib section */
587     memset(plogpal, 0, sizeof(logpalbuf));
588     plogpal->palVersion = 0x300;
589     plogpal->palNumEntries = 2;
590     plogpal->palPalEntry[0].peRed = 0xff;
591     plogpal->palPalEntry[0].peBlue = 0xff;
592     plogpal->palPalEntry[1].peGreen = 0xff;
593
594     index = (WORD*)pbmi->bmiColors;
595     *index++ = 0;
596     *index = 1;
597     hpal = CreatePalette(plogpal);
598     ok(hpal != NULL, "CreatePalette failed\n");
599     oldpal = SelectPalette(hdc, hpal, TRUE);
600     hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
601     ok(hdib != NULL, "CreateDIBSection failed\n");
602     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
603     ok(dibsec.dsBmih.biClrUsed == 2,
604         "created DIBSection: wrong biClrUsed field: %lu, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
605
606     /* The colour table has already been grabbed from the dc, so we select back the
607        old palette */
608
609     SelectPalette(hdc, oldpal, TRUE);
610     oldbm = SelectObject(hdcmem, hdib);
611     oldpal = SelectPalette(hdcmem, hpal, TRUE);
612
613     ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
614     ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
615     ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
616        rgb[1].rgbRed == 0    && rgb[1].rgbBlue == 0    && rgb[1].rgbGreen == 0xff,
617        "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
618        rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
619        rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
620
621     c0 = RGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen, plogpal->palPalEntry[0].peBlue);
622     c1 = RGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen, plogpal->palPalEntry[1].peBlue);
623
624     test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
625     test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
626     test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
627     test_color(hdcmem, PALETTEINDEX(0), c0, 0, 1);
628     test_color(hdcmem, PALETTEINDEX(1), c1, 0, 1);
629     test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
630     test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen,
631         plogpal->palPalEntry[0].peBlue), c0, 1, 1);
632     test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen,
633         plogpal->palPalEntry[1].peBlue), c1, 1, 1);
634     test_color(hdcmem, PALETTERGB(0, 0, 0), c1, 1, 1);
635     test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
636     test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0, 1, 1);
637     test_color(hdcmem, PALETTERGB(0, 1, 0), c1, 1, 1);
638     test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1, 1, 1);
639     test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0, 1, 1);
640
641     /* Bottom and 2nd row from top green, everything else magenta */
642     bits[0] = bits[1] = 0xff;
643     bits[13 * 4] = bits[13*4 + 1] = 0xff;
644
645     test_dib_info(hdib, bits, &pbmi->bmiHeader);
646
647     pbmi->bmiHeader.biBitCount = 32;
648
649     hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
650     ok(hdib2 != NULL, "CreateDIBSection failed\n");
651     hdcmem2 = CreateCompatibleDC(hdc);
652     oldbm2 = SelectObject(hdcmem2, hdib2);
653
654     BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
655
656     ok(bits32[0] == 0xff00, "lower left pixel is %08lx\n", bits32[0]);
657     ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08lx\n", bits32[17]);
658
659     SelectObject(hdcmem2, oldbm2);
660     test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
661     DeleteObject(hdib2);
662
663     SelectObject(hdcmem, oldbm);
664     SelectObject(hdcmem, oldpal);
665     DeleteObject(hdib);
666     DeleteObject(hpal);
667
668
669     pbmi->bmiHeader.biBitCount = 8;
670
671     memset(plogpal, 0, sizeof(logpalbuf));
672     plogpal->palVersion = 0x300;
673     plogpal->palNumEntries = 256;
674
675     for (i = 0; i < 128; i++) {
676         plogpal->palPalEntry[i].peRed = 255 - i * 2;
677         plogpal->palPalEntry[i].peBlue = i * 2;
678         plogpal->palPalEntry[i].peGreen = 0;
679         plogpal->palPalEntry[255 - i].peRed = 0;
680         plogpal->palPalEntry[255 - i].peGreen = i * 2;
681         plogpal->palPalEntry[255 - i].peBlue = 255 - i * 2;
682     }
683
684     index = (WORD*)pbmi->bmiColors;
685     for (i = 0; i < 256; i++) {
686         *index++ = i;
687     }
688
689     hpal = CreatePalette(plogpal);
690     ok(hpal != NULL, "CreatePalette failed\n");
691     oldpal = SelectPalette(hdc, hpal, TRUE);
692     hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
693     ok(hdib != NULL, "CreateDIBSection failed\n");
694     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
695     ok(dibsec.dsBmih.biClrUsed == 256,
696         "created DIBSection: wrong biClrUsed field: %lu, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
697
698     test_dib_info(hdib, bits, &pbmi->bmiHeader);
699
700     SelectPalette(hdc, oldpal, TRUE);
701     oldbm = SelectObject(hdcmem, hdib);
702     oldpal = SelectPalette(hdcmem, hpal, TRUE);
703
704     ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
705     ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
706     for (i = 0; i < 256; i++) {
707         ok(rgb[i].rgbRed == plogpal->palPalEntry[i].peRed && 
708             rgb[i].rgbBlue == plogpal->palPalEntry[i].peBlue && 
709             rgb[i].rgbGreen == plogpal->palPalEntry[i].peGreen, 
710             "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
711             i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
712     }
713
714     for (i = 0; i < 256; i++) {
715         test_color(hdcmem, DIBINDEX(i), 
716             RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
717         test_color(hdcmem, PALETTEINDEX(i), 
718             RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
719         test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 
720             RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
721     }
722
723     SelectPalette(hdcmem, oldpal, TRUE);
724     SelectObject(hdcmem, oldbm);
725     DeleteObject(hdib);
726     DeleteObject(hpal);
727
728
729     DeleteDC(hdcmem);
730     ReleaseDC(0, hdc);
731 }    
732
733 void test_mono_dibsection(void)
734 {
735     HDC hdc, memdc;
736     HBITMAP old_bm, mono_ds;
737     char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
738     BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
739     BYTE bits[10 * 4];
740     BYTE *ds_bits;
741     int num;
742
743     hdc = GetDC(0);
744
745     memdc = CreateCompatibleDC(hdc);
746
747     memset(pbmi, 0, sizeof(bmibuf));
748     pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
749     pbmi->bmiHeader.biHeight = 10;
750     pbmi->bmiHeader.biWidth = 10;
751     pbmi->bmiHeader.biBitCount = 1;
752     pbmi->bmiHeader.biPlanes = 1;
753     pbmi->bmiHeader.biCompression = BI_RGB;
754     pbmi->bmiColors[0].rgbRed = 0xff;
755     pbmi->bmiColors[0].rgbGreen = 0xff;
756     pbmi->bmiColors[0].rgbBlue = 0xff;
757     pbmi->bmiColors[1].rgbRed = 0x0;
758     pbmi->bmiColors[1].rgbGreen = 0x0;
759     pbmi->bmiColors[1].rgbBlue = 0x0;
760
761     /*
762      * First dib section is 'inverted' ie color[0] is white, color[1] is black
763      */
764
765     mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
766     ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
767     old_bm = SelectObject(memdc, mono_ds);
768
769     /* black border, white interior */
770     Rectangle(memdc, 0, 0, 10, 10);
771     ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
772     ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
773
774     /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
775
776     memset(bits, 0, sizeof(bits));
777     bits[0] = 0xaa;
778
779     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
780     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
781
782     /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
783
784     pbmi->bmiColors[0].rgbRed = 0x0;
785     pbmi->bmiColors[0].rgbGreen = 0x0;
786     pbmi->bmiColors[0].rgbBlue = 0x0;
787     pbmi->bmiColors[1].rgbRed = 0xff;
788     pbmi->bmiColors[1].rgbGreen = 0xff;
789     pbmi->bmiColors[1].rgbBlue = 0xff;
790
791     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
792     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
793
794     SelectObject(memdc, old_bm);
795     DeleteObject(mono_ds);
796
797     /*
798      * Next dib section is 'normal' ie color[0] is black, color[1] is white
799      */
800
801     pbmi->bmiColors[0].rgbRed = 0x0;
802     pbmi->bmiColors[0].rgbGreen = 0x0;
803     pbmi->bmiColors[0].rgbBlue = 0x0;
804     pbmi->bmiColors[1].rgbRed = 0xff;
805     pbmi->bmiColors[1].rgbGreen = 0xff;
806     pbmi->bmiColors[1].rgbBlue = 0xff;
807
808     mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
809     ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
810     old_bm = SelectObject(memdc, mono_ds);
811
812     /* black border, white interior */
813     Rectangle(memdc, 0, 0, 10, 10);
814     ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
815     ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
816
817     /* SetDIBitsToDevice with a normal bmi -> normal dib section */
818
819     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
820     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
821
822     /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
823
824     pbmi->bmiColors[0].rgbRed = 0xff;
825     pbmi->bmiColors[0].rgbGreen = 0xff;
826     pbmi->bmiColors[0].rgbBlue = 0xff;
827     pbmi->bmiColors[1].rgbRed = 0x0;
828     pbmi->bmiColors[1].rgbGreen = 0x0;
829     pbmi->bmiColors[1].rgbBlue = 0x0;
830
831     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
832     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
833
834     /*
835      * Take that 'normal' dibsection and change its colour table to an 'inverted' one
836      */
837
838     pbmi->bmiColors[0].rgbRed = 0xff;
839     pbmi->bmiColors[0].rgbGreen = 0xff;
840     pbmi->bmiColors[0].rgbBlue = 0xff;
841     pbmi->bmiColors[1].rgbRed = 0x0;
842     pbmi->bmiColors[1].rgbGreen = 0x0;
843     pbmi->bmiColors[1].rgbBlue = 0x0;
844     num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors);
845     ok(num == 2, "num = %d\n", num);
846
847     /* black border, white interior */
848     Rectangle(memdc, 0, 0, 10, 10);
849 todo_wine {
850     ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
851     ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
852  }
853     /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
854
855     memset(bits, 0, sizeof(bits));
856     bits[0] = 0xaa;
857
858     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
859     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
860
861     /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
862
863     pbmi->bmiColors[0].rgbRed = 0x0;
864     pbmi->bmiColors[0].rgbGreen = 0x0;
865     pbmi->bmiColors[0].rgbBlue = 0x0;
866     pbmi->bmiColors[1].rgbRed = 0xff;
867     pbmi->bmiColors[1].rgbGreen = 0xff;
868     pbmi->bmiColors[1].rgbBlue = 0xff;
869
870     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
871     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
872
873     SelectObject(memdc, old_bm);
874     DeleteObject(mono_ds);
875
876     /*
877      * Now a dib section with a strange colour map just for fun.  This behaves just like an inverted one.
878      */
879  
880     pbmi->bmiColors[0].rgbRed = 0xff;
881     pbmi->bmiColors[0].rgbGreen = 0x0;
882     pbmi->bmiColors[0].rgbBlue = 0x0;
883     pbmi->bmiColors[1].rgbRed = 0xfe;
884     pbmi->bmiColors[1].rgbGreen = 0x0;
885     pbmi->bmiColors[1].rgbBlue = 0x0;
886
887     mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
888     ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
889     old_bm = SelectObject(memdc, mono_ds);
890
891     /* black border, white interior */
892     Rectangle(memdc, 0, 0, 10, 10);
893     ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
894     ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
895
896     /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
897
898     pbmi->bmiColors[0].rgbRed = 0x0;
899     pbmi->bmiColors[0].rgbGreen = 0x0;
900     pbmi->bmiColors[0].rgbBlue = 0x0;
901     pbmi->bmiColors[1].rgbRed = 0xff;
902     pbmi->bmiColors[1].rgbGreen = 0xff;
903     pbmi->bmiColors[1].rgbBlue = 0xff;
904
905     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
906     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
907
908     /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
909
910     pbmi->bmiColors[0].rgbRed = 0xff;
911     pbmi->bmiColors[0].rgbGreen = 0xff;
912     pbmi->bmiColors[0].rgbBlue = 0xff;
913     pbmi->bmiColors[1].rgbRed = 0x0;
914     pbmi->bmiColors[1].rgbGreen = 0x0;
915     pbmi->bmiColors[1].rgbBlue = 0x0;
916
917     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
918     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
919
920     SelectObject(memdc, old_bm);
921     DeleteObject(mono_ds);
922
923     DeleteDC(memdc);
924     ReleaseDC(0, hdc);
925 }
926
927 static void test_bitmap(void)
928 {
929     char buf[256], buf_cmp[256];
930     HBITMAP hbmp, hbmp_old;
931     HDC hdc;
932     BITMAP bm;
933     INT ret;
934
935     hdc = CreateCompatibleDC(0);
936     assert(hdc != 0);
937
938     hbmp = CreateBitmap(15, 15, 1, 1, NULL);
939     assert(hbmp != NULL);
940
941     ret = GetObject(hbmp, sizeof(bm), &bm);
942     ok(ret == sizeof(bm), "%d != %d\n", ret, sizeof(bm));
943
944     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
945     ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
946     ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
947     ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
948     ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
949     ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
950     ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
951
952     assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
953     assert(sizeof(buf) == sizeof(buf_cmp));
954
955     ret = GetBitmapBits(hbmp, 0, NULL);
956     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
957
958     memset(buf_cmp, 0xAA, sizeof(buf_cmp));
959     memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
960
961     memset(buf, 0xAA, sizeof(buf));
962     ret = GetBitmapBits(hbmp, sizeof(buf), buf);
963     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
964     ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
965
966     hbmp_old = SelectObject(hdc, hbmp);
967
968     ret = GetObject(hbmp, sizeof(bm), &bm);
969     ok(ret == sizeof(bm), "%d != %d\n", ret, sizeof(bm));
970
971     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
972     ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
973     ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
974     ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
975     ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
976     ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
977     ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
978
979     memset(buf, 0xAA, sizeof(buf));
980     ret = GetBitmapBits(hbmp, sizeof(buf), buf);
981     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
982     ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
983
984     hbmp_old = SelectObject(hdc, hbmp_old);
985     ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
986
987     /* test various buffer sizes for GetObject */
988     ret = GetObject(hbmp, sizeof(bm) * 2, &bm);
989     ok(ret == sizeof(bm), "%d != %d\n", ret, sizeof(bm));
990
991     ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
992     ok(ret == 0, "%d != 0\n", ret);
993
994     ret = GetObject(hbmp, 0, &bm);
995     ok(ret == 0, "%d != 0\n", ret);
996
997     ret = GetObject(hbmp, 1, &bm);
998     ok(ret == 0, "%d != 0\n", ret);
999
1000     DeleteObject(hbmp);
1001     DeleteDC(hdc);
1002 }
1003
1004 static void test_bmBits(void)
1005 {
1006     BYTE bits[4];
1007     HBITMAP hbmp;
1008     BITMAP bmp;
1009
1010     memset(bits, 0, sizeof(bits));
1011     hbmp = CreateBitmap(2, 2, 1, 4, bits);
1012     ok(hbmp != NULL, "CreateBitmap failed\n");
1013
1014     memset(&bmp, 0xFF, sizeof(bmp));
1015     ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1016        "GetObject failed or returned a wrong structure size\n");
1017     ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1018
1019     DeleteObject(hbmp);
1020 }
1021
1022
1023 START_TEST(bitmap)
1024 {
1025     is_win9x = GetWindowLongPtrW(GetDesktopWindow(), GWLP_WNDPROC) == 0;
1026
1027     test_createdibitmap();
1028     test_dibsections();
1029     test_mono_dibsection();
1030     test_bitmap();
1031     test_bmBits();
1032 }