gdi32/tests: Fix a test failure on Win9x/WinME.
[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 "winerror.h"
29 #include "wingdi.h"
30 #include "winuser.h"
31 #include "mmsystem.h"
32
33 #include "wine/test.h"
34
35 static BOOL (WINAPI *pGdiAlphaBlend)(HDC,int,int,int,int,HDC,int,int,int,int,BLENDFUNCTION);
36
37 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
38
39 static BOOL is_win9x;
40
41 static INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp )
42 {
43     switch(bpp)
44     {
45     case 1:
46         return 2 * ((bmWidth+15) >> 4);
47
48     case 24:
49         bmWidth *= 3; /* fall through */
50     case 8:
51         return bmWidth + (bmWidth & 1);
52
53     case 32:
54         return bmWidth * 4;
55
56     case 16:
57     case 15:
58         return bmWidth * 2;
59
60     case 4:
61         return 2 * ((bmWidth+3) >> 2);
62
63     default:
64         trace("Unknown depth %d, please report.\n", bpp );
65         assert(0);
66     }
67     return -1;
68 }
69
70 static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHEADER *bmih)
71 {
72     BITMAP bm;
73     BITMAP bma[2];
74     INT ret, width_bytes;
75     BYTE buf[512], buf_cmp[512];
76     DWORD gle;
77
78     ret = GetObject(hbm, sizeof(bm), &bm);
79     ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
80
81     ok(bm.bmType == 0 || broken(bm.bmType == 21072 /* Win9x */), "wrong bm.bmType %d\n", bm.bmType);
82     ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
83     ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
84     width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
85     ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
86     ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
87     ok(bm.bmBitsPixel == expected_depth, "wrong bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, expected_depth);
88     ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
89
90     assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
91     assert(sizeof(buf) == sizeof(buf_cmp));
92
93     SetLastError(0xdeadbeef);
94     ret = GetBitmapBits(hbm, 0, NULL);
95     gle=GetLastError();
96     ok(ret == bm.bmWidthBytes * bm.bmHeight || (ret == 0 && gle == ERROR_INVALID_PARAMETER /* Win9x */), "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
97
98     memset(buf_cmp, 0xAA, sizeof(buf_cmp));
99     memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
100
101     memset(buf, 0xAA, sizeof(buf));
102     ret = GetBitmapBits(hbm, sizeof(buf), buf);
103     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
104     ok(!memcmp(buf, buf_cmp, sizeof(buf)) ||
105        broken(memcmp(buf, buf_cmp, sizeof(buf))), /* win9x doesn't init the bitmap bits */
106         "buffers do not match, depth %d\n", bmih->biBitCount);
107
108     /* test various buffer sizes for GetObject */
109     ret = GetObject(hbm, sizeof(*bma) * 2, bma);
110     ok(ret == sizeof(*bma) || broken(ret == sizeof(*bma) * 2 /* Win9x */), "wrong size %d\n", ret);
111
112     ret = GetObject(hbm, sizeof(bm) / 2, &bm);
113     ok(ret == 0 || broken(ret == sizeof(bm) / 2 /* Win9x */), "%d != 0\n", ret);
114
115     ret = GetObject(hbm, 0, &bm);
116     ok(ret == 0, "%d != 0\n", ret);
117
118     ret = GetObject(hbm, 1, &bm);
119     ok(ret == 0 || broken(ret == 1 /* Win9x */), "%d != 0\n", ret);
120
121     /* Don't trust Win9x not to try to write to NULL */
122     if (ret == 0)
123     {
124         ret = GetObject(hbm, 0, NULL);
125         ok(ret == sizeof(bm), "wrong size %d\n", ret);
126     }
127 }
128
129 static void test_createdibitmap(void)
130 {
131     HDC hdc, hdcmem;
132     BITMAPINFOHEADER bmih;
133     BITMAPINFO bm;
134     HBITMAP hbm, hbm_colour, hbm_old;
135     INT screen_depth;
136     DWORD pixel;
137
138     hdc = GetDC(0);
139     screen_depth = GetDeviceCaps(hdc, BITSPIXEL);
140     memset(&bmih, 0, sizeof(bmih));
141     bmih.biSize = sizeof(bmih);
142     bmih.biWidth = 10;
143     bmih.biHeight = 10;
144     bmih.biPlanes = 1;
145     bmih.biBitCount = 32;
146     bmih.biCompression = BI_RGB;
147
148     hbm = CreateDIBitmap(hdc, NULL, CBM_INIT, NULL, NULL, 0);
149     ok(hbm == NULL, "CreateDIBitmap should fail\n");
150     hbm = CreateDIBitmap(hdc, NULL, 0, NULL, NULL, 0);
151     ok(hbm == NULL, "CreateDIBitmap should fail\n");
152
153     /* First create an un-initialised bitmap.  The depth of the bitmap
154        should match that of the hdc and not that supplied in bmih.
155     */
156
157     /* First try 32 bits */
158     hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
159     ok(hbm != NULL, "CreateDIBitmap failed\n");
160     test_bitmap_info(hbm, screen_depth, &bmih);
161     DeleteObject(hbm);
162     
163     /* Then 16 */
164     bmih.biBitCount = 16;
165     hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
166     ok(hbm != NULL, "CreateDIBitmap failed\n");
167     test_bitmap_info(hbm, screen_depth, &bmih);
168     DeleteObject(hbm);
169
170     /* Then 1 */
171     bmih.biBitCount = 1;
172     hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
173     ok(hbm != NULL, "CreateDIBitmap failed\n");
174     test_bitmap_info(hbm, screen_depth, &bmih);
175     DeleteObject(hbm);
176
177     /* Now with a monochrome dc we expect a monochrome bitmap */
178     hdcmem = CreateCompatibleDC(hdc);
179
180     /* First try 32 bits */
181     bmih.biBitCount = 32;
182     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
183     ok(hbm != NULL, "CreateDIBitmap failed\n");
184     test_bitmap_info(hbm, 1, &bmih);
185     DeleteObject(hbm);
186     
187     /* Then 16 */
188     bmih.biBitCount = 16;
189     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
190     ok(hbm != NULL, "CreateDIBitmap failed\n");
191     test_bitmap_info(hbm, 1, &bmih);
192     DeleteObject(hbm);
193     
194     /* Then 1 */
195     bmih.biBitCount = 1;
196     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
197     ok(hbm != NULL, "CreateDIBitmap failed\n");
198     test_bitmap_info(hbm, 1, &bmih);
199     DeleteObject(hbm);
200
201     /* Now select a polychrome bitmap into the dc and we expect
202        screen_depth bitmaps again */
203     hbm_colour = CreateCompatibleBitmap(hdc, bmih.biWidth, bmih.biHeight);
204     test_bitmap_info(hbm_colour, screen_depth, &bmih);
205     hbm_old = SelectObject(hdcmem, hbm_colour);
206
207     /* First try 32 bits */
208     bmih.biBitCount = 32;
209     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
210     ok(hbm != NULL, "CreateDIBitmap failed\n");
211     test_bitmap_info(hbm, screen_depth, &bmih);
212     DeleteObject(hbm);
213     
214     /* Then 16 */
215     bmih.biBitCount = 16;
216     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
217     ok(hbm != NULL, "CreateDIBitmap failed\n");
218     test_bitmap_info(hbm, screen_depth, &bmih);
219     DeleteObject(hbm);
220     
221     /* Then 1 */
222     bmih.biBitCount = 1;
223     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
224     ok(hbm != NULL, "CreateDIBitmap failed\n");
225     test_bitmap_info(hbm, screen_depth, &bmih);
226     DeleteObject(hbm);
227
228     SelectObject(hdcmem, hbm_old);
229     DeleteObject(hbm_colour);
230     DeleteDC(hdcmem);
231
232     /* If hdc == 0 then we get a 1 bpp bitmap */
233     if (!is_win9x) {
234         bmih.biBitCount = 32;
235         hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0);
236         ok(hbm != NULL, "CreateDIBitmap failed\n");
237         test_bitmap_info(hbm, 1, &bmih);
238         DeleteObject(hbm);
239     }
240
241     /* Test how formats are converted */
242     pixel = 0xffffffff;
243     bmih.biBitCount = 1;
244     bmih.biWidth = 1;
245     bmih.biHeight = 1;
246
247     memset(&bm, 0, sizeof(bm));
248     bm.bmiHeader.biSize = sizeof(bm.bmiHeader);
249     bm.bmiHeader.biWidth = 1;
250     bm.bmiHeader.biHeight = 1;
251     bm.bmiHeader.biPlanes = 1;
252     bm.bmiHeader.biBitCount= 24;
253     bm.bmiHeader.biCompression= BI_RGB;
254     bm.bmiHeader.biSizeImage = 0;
255     hbm = CreateDIBitmap(hdc, &bmih, CBM_INIT, &pixel, &bm, DIB_RGB_COLORS);
256     ok(hbm != NULL, "CreateDIBitmap failed\n");
257
258     pixel = 0xdeadbeef;
259     bm.bmiHeader.biBitCount= 32;
260     GetDIBits(hdc, hbm, 0, 1, &pixel, &bm, DIB_RGB_COLORS);
261     ok(pixel == 0x00ffffff, "Reading a 32 bit pixel from a DDB returned %08x\n", pixel);
262     DeleteObject(hbm);
263
264     ReleaseDC(0, hdc);
265 }
266
267 static INT DIB_GetWidthBytes( int width, int bpp )
268 {
269     int words;
270
271     switch (bpp)
272     {
273         case 1:  words = (width + 31) / 32; break;
274         case 4:  words = (width + 7) / 8; break;
275         case 8:  words = (width + 3) / 4; break;
276         case 15:
277         case 16: words = (width + 1) / 2; break;
278         case 24: words = (width * 3 + 3)/4; break;
279         case 32: words = width; break;
280
281         default:
282             words=0;
283             trace("Unknown depth %d, please report.\n", bpp );
284             assert(0);
285             break;
286     }
287     return 4 * words;
288 }
289
290 static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
291 {
292     BITMAP bm;
293     BITMAP bma[2];
294     DIBSECTION ds;
295     DIBSECTION dsa[2];
296     INT ret, bm_width_bytes, dib_width_bytes;
297     BYTE *buf;
298
299     ret = GetObject(hbm, sizeof(bm), &bm);
300     ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
301
302     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
303     ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
304     ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
305     dib_width_bytes = DIB_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
306     bm_width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
307     if (bm.bmWidthBytes != dib_width_bytes) /* Win2k bug */
308         ok(bm.bmWidthBytes == bm_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, bm_width_bytes);
309     else
310         ok(bm.bmWidthBytes == dib_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, dib_width_bytes);
311     ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
312     ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount);
313     ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
314
315     buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);
316
317     /* GetBitmapBits returns not 32-bit aligned data */
318     SetLastError(0xdeadbeef);
319     ret = GetBitmapBits(hbm, 0, NULL);
320     ok(ret == bm_width_bytes * bm.bmHeight ||
321         broken(ret == 0 && GetLastError() == ERROR_INVALID_PARAMETER), /* Win9x */
322         "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
323
324     memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
325     ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
326     ok(ret == bm_width_bytes * bm.bmHeight, "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
327
328     HeapFree(GetProcessHeap(), 0, buf);
329
330     /* test various buffer sizes for GetObject */
331     memset(&ds, 0xAA, sizeof(ds));
332     ret = GetObject(hbm, sizeof(*bma) * 2, bma);
333     ok(ret == sizeof(*bma) || broken(ret == sizeof(*bma) * 2 /* Win9x */), "wrong size %d\n", ret);
334     ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
335     ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
336     ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
337
338     ret = GetObject(hbm, sizeof(bm) / 2, &bm);
339     ok(ret == 0 || broken(ret == sizeof(bm) / 2 /* Win9x */), "%d != 0\n", ret);
340
341     ret = GetObject(hbm, 0, &bm);
342     ok(ret == 0, "%d != 0\n", ret);
343
344     ret = GetObject(hbm, 1, &bm);
345     ok(ret == 0 || broken(ret ==  1 /* Win9x */), "%d != 0\n", ret);
346
347     /* test various buffer sizes for GetObject */
348     ret = GetObject(hbm, 0, NULL);
349     ok(ret == sizeof(bm) || broken(ret == sizeof(DIBSECTION) /* Win9x */), "wrong size %d\n", ret);
350
351     ret = GetObject(hbm, sizeof(*dsa) * 2, dsa);
352     ok(ret == sizeof(*dsa) || broken(ret == sizeof(*dsa) * 2 /* Win9x */), "wrong size %d\n", ret);
353
354     memset(&ds, 0xAA, sizeof(ds));
355     ret = GetObject(hbm, sizeof(ds), &ds);
356     ok(ret == sizeof(ds), "wrong size %d\n", ret);
357
358     ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
359     if (ds.dsBm.bmWidthBytes != bm_width_bytes) /* Win2k bug */
360         ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%u != %u\n",
361            ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
362     ok(bmih->biSizeImage == 0, "%u != 0\n", bmih->biSizeImage);
363     ds.dsBmih.biSizeImage = 0;
364
365     ok(ds.dsBmih.biSize == bmih->biSize, "%u != %u\n", ds.dsBmih.biSize, bmih->biSize);
366     ok(ds.dsBmih.biWidth == bmih->biWidth, "%u != %u\n", ds.dsBmih.biWidth, bmih->biWidth);
367     ok(ds.dsBmih.biHeight == bmih->biHeight, "%u != %u\n", ds.dsBmih.biHeight, bmih->biHeight);
368     ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes);
369     ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount);
370     ok(ds.dsBmih.biCompression == bmih->biCompression, "%u != %u\n", ds.dsBmih.biCompression, bmih->biCompression);
371     ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%u != %u\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
372     ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%u != %u\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
373     ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%u != %u\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);
374
375     memset(&ds, 0xAA, sizeof(ds));
376     ret = GetObject(hbm, sizeof(ds) - 4, &ds);
377     ok(ret == sizeof(ds.dsBm) || broken(ret == (sizeof(ds) - 4) /* Win9x */), "wrong size %d\n", ret);
378     ok(ds.dsBm.bmWidth == bmih->biWidth, "%u != %u\n", ds.dsBmih.biWidth, bmih->biWidth);
379     ok(ds.dsBm.bmHeight == bmih->biHeight, "%u != %u\n", ds.dsBmih.biHeight, bmih->biHeight);
380     ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);
381
382     ret = GetObject(hbm, 0, &ds);
383     ok(ret == 0, "%d != 0\n", ret);
384
385     ret = GetObject(hbm, 1, &ds);
386     ok(ret == 0 || broken(ret == 1 /* Win9x */), "%d != 0\n", ret);
387 }
388
389 #define test_color_todo(got, exp, txt, todo) \
390     if (!todo && got != exp && screen_depth < 24) { \
391       todo_wine ok(0, #txt " failed at %d-bit screen depth: got 0x%06x expected 0x%06x - skipping DIB tests\n", \
392                    screen_depth, (UINT)got, (UINT)exp); \
393       return; \
394     } else if (todo) todo_wine { ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp); } \
395     else ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp) \
396
397 #define test_color(hdc, color, exp, todo_setp, todo_getp) \
398 { \
399     COLORREF c; \
400     c = SetPixel(hdc, 0, 0, color); \
401     if (!is_win9x) { test_color_todo(c, exp, SetPixel, todo_setp); } \
402     c = GetPixel(hdc, 0, 0); \
403     test_color_todo(c, exp, GetPixel, todo_getp); \
404 }
405
406 static void test_dib_bits_access( HBITMAP hdib, void *bits )
407 {
408     MEMORY_BASIC_INFORMATION info;
409     char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
410     DWORD data[256];
411     BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
412     HDC hdc = GetDC(0);
413     char filename[MAX_PATH];
414     HANDLE file;
415     DWORD written;
416     INT ret;
417
418     ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
419         "VirtualQuery failed\n");
420     ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
421     ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
422     ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
423     ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
424     ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
425     ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
426
427     memset( pbmi, 0, sizeof(bmibuf) );
428     memset( data, 0xcc, sizeof(data) );
429     pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
430     pbmi->bmiHeader.biHeight = 16;
431     pbmi->bmiHeader.biWidth = 16;
432     pbmi->bmiHeader.biBitCount = 32;
433     pbmi->bmiHeader.biPlanes = 1;
434     pbmi->bmiHeader.biCompression = BI_RGB;
435
436     ret = SetDIBits( hdc, hdib, 0, 16, data, pbmi, DIB_RGB_COLORS );
437     ok(ret == 16 ||
438        broken(ret == 0), /* win9x */
439        "SetDIBits failed: expected 16 got %d\n", ret);
440
441     ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
442         "VirtualQuery failed\n");
443     ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
444     ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
445     ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
446     ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
447     ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
448     /* it has been protected now */
449     todo_wine ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
450
451     /* try writing protected bits to a file */
452
453     GetTempFileNameA( ".", "dib", 0, filename );
454     file = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
455                         CREATE_ALWAYS, 0, 0 );
456     ok( file != INVALID_HANDLE_VALUE, "failed to open %s error %u\n", filename, GetLastError() );
457     ret = WriteFile( file, bits, 8192, &written, NULL );
458     ok( ret, "WriteFile failed error %u\n", GetLastError() );
459     if (ret) ok( written == 8192, "only wrote %u bytes\n", written );
460     CloseHandle( file );
461     DeleteFileA( filename );
462 }
463
464 static void test_dibsections(void)
465 {
466     HDC hdc, hdcmem, hdcmem2;
467     HBITMAP hdib, oldbm, hdib2, oldbm2;
468     char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
469     char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
470     BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
471     BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
472     HBITMAP hcoredib;
473     char coreBits[256];
474     BYTE *bits;
475     RGBQUAD rgb[256];
476     int ret;
477     char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
478     LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
479     WORD *index;
480     DWORD *bits32;
481     HPALETTE hpal, oldpal;
482     DIBSECTION dibsec;
483     COLORREF c0, c1;
484     int i;
485     int screen_depth;
486     MEMORY_BASIC_INFORMATION info;
487
488     hdc = GetDC(0);
489     screen_depth = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
490
491     memset(pbmi, 0, sizeof(bmibuf));
492     pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
493     pbmi->bmiHeader.biHeight = 100;
494     pbmi->bmiHeader.biWidth = 512;
495     pbmi->bmiHeader.biBitCount = 24;
496     pbmi->bmiHeader.biPlanes = 1;
497     pbmi->bmiHeader.biCompression = BI_RGB;
498
499     SetLastError(0xdeadbeef);
500
501     /* invalid pointer for BITMAPINFO
502        (*bits should be NULL on error) */
503     bits = (BYTE*)0xdeadbeef;
504     hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
505     ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n");
506
507     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
508     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
509     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
510     ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
511
512     /* test the DIB memory */
513     ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
514         "VirtualQuery failed\n");
515     ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
516     ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
517     ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
518     ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
519     ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
520     ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
521     ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
522
523     test_dib_bits_access( hdib, bits );
524
525     test_dib_info(hdib, bits, &pbmi->bmiHeader);
526     DeleteObject(hdib);
527
528     pbmi->bmiHeader.biBitCount = 8;
529     pbmi->bmiHeader.biCompression = BI_RLE8;
530     SetLastError(0xdeadbeef);
531     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
532     ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
533     ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
534
535     pbmi->bmiHeader.biBitCount = 16;
536     pbmi->bmiHeader.biCompression = BI_BITFIELDS;
537     ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
538     ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
539     ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
540     SetLastError(0xdeadbeef);
541     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
542     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
543
544     /* test the DIB memory */
545     ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
546         "VirtualQuery failed\n");
547     ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
548     ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
549     ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
550     ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
551     ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
552     ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
553     ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
554
555     test_dib_info(hdib, bits, &pbmi->bmiHeader);
556     DeleteObject(hdib);
557
558     memset(pbmi, 0, sizeof(bmibuf));
559     pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
560     pbmi->bmiHeader.biHeight = 16;
561     pbmi->bmiHeader.biWidth = 16;
562     pbmi->bmiHeader.biBitCount = 1;
563     pbmi->bmiHeader.biPlanes = 1;
564     pbmi->bmiHeader.biCompression = BI_RGB;
565     pbmi->bmiColors[0].rgbRed = 0xff;
566     pbmi->bmiColors[0].rgbGreen = 0;
567     pbmi->bmiColors[0].rgbBlue = 0;
568     pbmi->bmiColors[1].rgbRed = 0;
569     pbmi->bmiColors[1].rgbGreen = 0;
570     pbmi->bmiColors[1].rgbBlue = 0xff;
571
572     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
573     ok(hdib != NULL, "CreateDIBSection failed\n");
574     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
575     ok(dibsec.dsBmih.biClrUsed == 2,
576         "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
577
578     /* Test if the old BITMAPCOREINFO structure is supported */    
579         
580     pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
581     pbci->bmciHeader.bcBitCount = 0;
582
583     if (!is_win9x) {
584         ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
585         ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
586         ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
587             && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
588         "GetDIBits did't fill in the BITMAPCOREHEADER structure properly\n");
589
590         ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
591         ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
592         ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
593             (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
594             (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
595             "The color table has not been translated to the old BITMAPCOREINFO format\n");
596
597         hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
598         ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
599
600         ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
601         ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
602         ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
603         ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
604             (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
605             (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
606             "The color table has not been translated to the old BITMAPCOREINFO format\n");
607
608         DeleteObject(hcoredib);
609     }
610
611     hdcmem = CreateCompatibleDC(hdc);
612     oldbm = SelectObject(hdcmem, hdib);
613
614     ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
615     ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
616     ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
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(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen, pbmi->bmiColors[0].rgbBlue);
622     c1 = RGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen, pbmi->bmiColors[1].rgbBlue);
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, 1, 1);
628     test_color(hdcmem, PALETTEINDEX(1), c0, 1, 1);
629     test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
630     test_color(hdcmem, PALETTERGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen,
631         pbmi->bmiColors[0].rgbBlue), c0, 1, 1);
632     test_color(hdcmem, PALETTERGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen,
633         pbmi->bmiColors[1].rgbBlue), c1, 1, 1);
634     test_color(hdcmem, PALETTERGB(0, 0, 0), c0, 1, 1);
635     test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
636     test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1, 1, 1);
637
638     SelectObject(hdcmem, oldbm);
639     DeleteObject(hdib);
640
641     pbmi->bmiColors[0].rgbRed = 0xff;
642     pbmi->bmiColors[0].rgbGreen = 0xff;
643     pbmi->bmiColors[0].rgbBlue = 0xff;
644     pbmi->bmiColors[1].rgbRed = 0;
645     pbmi->bmiColors[1].rgbGreen = 0;
646     pbmi->bmiColors[1].rgbBlue = 0;
647
648     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
649     ok(hdib != NULL, "CreateDIBSection failed\n");
650
651     test_dib_info(hdib, bits, &pbmi->bmiHeader);
652
653     oldbm = SelectObject(hdcmem, hdib);
654
655     ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
656     ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
657     ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
658        "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
659        rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
660        rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
661
662     SelectObject(hdcmem, oldbm);
663     test_dib_info(hdib, bits, &pbmi->bmiHeader);
664     DeleteObject(hdib);
665
666     pbmi->bmiHeader.biBitCount = 4;
667     for (i = 0; i < 16; i++) {
668         pbmi->bmiColors[i].rgbRed = i;
669         pbmi->bmiColors[i].rgbGreen = 16-i;
670         pbmi->bmiColors[i].rgbBlue = 0;
671     }
672     hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
673     ok(hdib != NULL, "CreateDIBSection failed\n");
674     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
675     ok(dibsec.dsBmih.biClrUsed == 16,
676        "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
677     test_dib_info(hdib, bits, &pbmi->bmiHeader);
678     DeleteObject(hdib);
679
680     pbmi->bmiHeader.biBitCount = 8;
681
682     for (i = 0; i < 128; i++) {
683         pbmi->bmiColors[i].rgbRed = 255 - i * 2;
684         pbmi->bmiColors[i].rgbGreen = i * 2;
685         pbmi->bmiColors[i].rgbBlue = 0;
686         pbmi->bmiColors[255 - i].rgbRed = 0;
687         pbmi->bmiColors[255 - i].rgbGreen = i * 2;
688         pbmi->bmiColors[255 - i].rgbBlue = 255 - i * 2;
689     }
690     hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
691     ok(hdib != NULL, "CreateDIBSection failed\n");
692     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
693     ok(dibsec.dsBmih.biClrUsed == 256,
694         "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
695
696     oldbm = SelectObject(hdcmem, hdib);
697
698     for (i = 0; i < 256; i++) {
699         test_color(hdcmem, DIBINDEX(i), 
700             RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
701         test_color(hdcmem, PALETTERGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 
702             RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
703     }
704
705     SelectObject(hdcmem, oldbm);
706     test_dib_info(hdib, bits, &pbmi->bmiHeader);
707     DeleteObject(hdib);
708
709     pbmi->bmiHeader.biBitCount = 1;
710
711     /* Now create a palette and a palette indexed dib section */
712     memset(plogpal, 0, sizeof(logpalbuf));
713     plogpal->palVersion = 0x300;
714     plogpal->palNumEntries = 2;
715     plogpal->palPalEntry[0].peRed = 0xff;
716     plogpal->palPalEntry[0].peBlue = 0xff;
717     plogpal->palPalEntry[1].peGreen = 0xff;
718
719     index = (WORD*)pbmi->bmiColors;
720     *index++ = 0;
721     *index = 1;
722     hpal = CreatePalette(plogpal);
723     ok(hpal != NULL, "CreatePalette failed\n");
724     oldpal = SelectPalette(hdc, hpal, TRUE);
725     hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
726     ok(hdib != NULL, "CreateDIBSection failed\n");
727     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
728     ok(dibsec.dsBmih.biClrUsed == 2 ||
729        broken(dibsec.dsBmih.biClrUsed == 0), /* win9x */
730         "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
731
732     /* The colour table has already been grabbed from the dc, so we select back the
733        old palette */
734
735     SelectPalette(hdc, oldpal, TRUE);
736     oldbm = SelectObject(hdcmem, hdib);
737     oldpal = SelectPalette(hdcmem, hpal, TRUE);
738
739     ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
740     ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
741     ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
742        rgb[1].rgbRed == 0    && rgb[1].rgbBlue == 0    && rgb[1].rgbGreen == 0xff,
743        "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
744        rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
745        rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
746
747     c0 = RGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen, plogpal->palPalEntry[0].peBlue);
748     c1 = RGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen, plogpal->palPalEntry[1].peBlue);
749
750     test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
751     test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
752     test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
753     test_color(hdcmem, PALETTEINDEX(0), c0, 0, 1);
754     test_color(hdcmem, PALETTEINDEX(1), c1, 0, 1);
755     test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
756     test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen,
757         plogpal->palPalEntry[0].peBlue), c0, 1, 1);
758     test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen,
759         plogpal->palPalEntry[1].peBlue), c1, 1, 1);
760     test_color(hdcmem, PALETTERGB(0, 0, 0), c1, 1, 1);
761     test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
762     test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0, 1, 1);
763     test_color(hdcmem, PALETTERGB(0, 1, 0), c1, 1, 1);
764     test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1, 1, 1);
765     test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0, 1, 1);
766
767     /* Bottom and 2nd row from top green, everything else magenta */
768     bits[0] = bits[1] = 0xff;
769     bits[13 * 4] = bits[13*4 + 1] = 0xff;
770
771     test_dib_info(hdib, bits, &pbmi->bmiHeader);
772
773     pbmi->bmiHeader.biBitCount = 32;
774
775     hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
776     ok(hdib2 != NULL, "CreateDIBSection failed\n");
777     hdcmem2 = CreateCompatibleDC(hdc);
778     oldbm2 = SelectObject(hdcmem2, hdib2);
779
780     BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
781
782     ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
783     ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
784
785     SelectObject(hdcmem2, oldbm2);
786     test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
787     DeleteObject(hdib2);
788
789     SelectObject(hdcmem, oldbm);
790     SelectObject(hdcmem, oldpal);
791     DeleteObject(hdib);
792     DeleteObject(hpal);
793
794
795     pbmi->bmiHeader.biBitCount = 8;
796
797     memset(plogpal, 0, sizeof(logpalbuf));
798     plogpal->palVersion = 0x300;
799     plogpal->palNumEntries = 256;
800
801     for (i = 0; i < 128; i++) {
802         plogpal->palPalEntry[i].peRed = 255 - i * 2;
803         plogpal->palPalEntry[i].peBlue = i * 2;
804         plogpal->palPalEntry[i].peGreen = 0;
805         plogpal->palPalEntry[255 - i].peRed = 0;
806         plogpal->palPalEntry[255 - i].peGreen = i * 2;
807         plogpal->palPalEntry[255 - i].peBlue = 255 - i * 2;
808     }
809
810     index = (WORD*)pbmi->bmiColors;
811     for (i = 0; i < 256; i++) {
812         *index++ = i;
813     }
814
815     hpal = CreatePalette(plogpal);
816     ok(hpal != NULL, "CreatePalette failed\n");
817     oldpal = SelectPalette(hdc, hpal, TRUE);
818     hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
819     ok(hdib != NULL, "CreateDIBSection failed\n");
820     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
821     ok(dibsec.dsBmih.biClrUsed == 256 ||
822        broken(dibsec.dsBmih.biClrUsed == 0), /* win9x */
823         "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
824
825     test_dib_info(hdib, bits, &pbmi->bmiHeader);
826
827     SelectPalette(hdc, oldpal, TRUE);
828     oldbm = SelectObject(hdcmem, hdib);
829     oldpal = SelectPalette(hdcmem, hpal, TRUE);
830
831     ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
832     ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
833     for (i = 0; i < 256; i++) {
834         ok(rgb[i].rgbRed == plogpal->palPalEntry[i].peRed && 
835             rgb[i].rgbBlue == plogpal->palPalEntry[i].peBlue && 
836             rgb[i].rgbGreen == plogpal->palPalEntry[i].peGreen, 
837             "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
838             i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
839     }
840
841     for (i = 0; i < 256; i++) {
842         test_color(hdcmem, DIBINDEX(i), 
843             RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
844         test_color(hdcmem, PALETTEINDEX(i), 
845             RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
846         test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 
847             RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
848     }
849
850     SelectPalette(hdcmem, oldpal, TRUE);
851     SelectObject(hdcmem, oldbm);
852     DeleteObject(hdib);
853     DeleteObject(hpal);
854
855
856     DeleteDC(hdcmem);
857     ReleaseDC(0, hdc);
858 }
859
860 static void test_mono_dibsection(void)
861 {
862     HDC hdc, memdc;
863     HBITMAP old_bm, mono_ds;
864     char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
865     BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
866     BYTE bits[10 * 4];
867     BYTE *ds_bits;
868     int num;
869
870     hdc = GetDC(0);
871
872     memdc = CreateCompatibleDC(hdc);
873
874     memset(pbmi, 0, sizeof(bmibuf));
875     pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
876     pbmi->bmiHeader.biHeight = 10;
877     pbmi->bmiHeader.biWidth = 10;
878     pbmi->bmiHeader.biBitCount = 1;
879     pbmi->bmiHeader.biPlanes = 1;
880     pbmi->bmiHeader.biCompression = BI_RGB;
881     pbmi->bmiColors[0].rgbRed = 0xff;
882     pbmi->bmiColors[0].rgbGreen = 0xff;
883     pbmi->bmiColors[0].rgbBlue = 0xff;
884     pbmi->bmiColors[1].rgbRed = 0x0;
885     pbmi->bmiColors[1].rgbGreen = 0x0;
886     pbmi->bmiColors[1].rgbBlue = 0x0;
887
888     /*
889      * First dib section is 'inverted' ie color[0] is white, color[1] is black
890      */
891
892     mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
893     ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
894     old_bm = SelectObject(memdc, mono_ds);
895
896     /* black border, white interior */
897     Rectangle(memdc, 0, 0, 10, 10);
898     ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
899     ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
900
901     /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
902
903     memset(bits, 0, sizeof(bits));
904     bits[0] = 0xaa;
905
906     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
907     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
908
909     /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
910
911     pbmi->bmiColors[0].rgbRed = 0x0;
912     pbmi->bmiColors[0].rgbGreen = 0x0;
913     pbmi->bmiColors[0].rgbBlue = 0x0;
914     pbmi->bmiColors[1].rgbRed = 0xff;
915     pbmi->bmiColors[1].rgbGreen = 0xff;
916     pbmi->bmiColors[1].rgbBlue = 0xff;
917
918     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
919     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
920
921     SelectObject(memdc, old_bm);
922     DeleteObject(mono_ds);
923
924     /*
925      * Next dib section is 'normal' ie color[0] is black, color[1] is white
926      */
927
928     pbmi->bmiColors[0].rgbRed = 0x0;
929     pbmi->bmiColors[0].rgbGreen = 0x0;
930     pbmi->bmiColors[0].rgbBlue = 0x0;
931     pbmi->bmiColors[1].rgbRed = 0xff;
932     pbmi->bmiColors[1].rgbGreen = 0xff;
933     pbmi->bmiColors[1].rgbBlue = 0xff;
934
935     mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
936     ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
937     old_bm = SelectObject(memdc, mono_ds);
938
939     /* black border, white interior */
940     Rectangle(memdc, 0, 0, 10, 10);
941     ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
942     ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
943
944     /* SetDIBitsToDevice with a normal bmi -> normal dib section */
945
946     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
947     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
948
949     /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
950
951     pbmi->bmiColors[0].rgbRed = 0xff;
952     pbmi->bmiColors[0].rgbGreen = 0xff;
953     pbmi->bmiColors[0].rgbBlue = 0xff;
954     pbmi->bmiColors[1].rgbRed = 0x0;
955     pbmi->bmiColors[1].rgbGreen = 0x0;
956     pbmi->bmiColors[1].rgbBlue = 0x0;
957
958     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
959     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
960
961     /*
962      * Take that 'normal' dibsection and change its colour table to an 'inverted' one
963      */
964
965     pbmi->bmiColors[0].rgbRed = 0xff;
966     pbmi->bmiColors[0].rgbGreen = 0xff;
967     pbmi->bmiColors[0].rgbBlue = 0xff;
968     pbmi->bmiColors[1].rgbRed = 0x0;
969     pbmi->bmiColors[1].rgbGreen = 0x0;
970     pbmi->bmiColors[1].rgbBlue = 0x0;
971     num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors);
972     ok(num == 2, "num = %d\n", num);
973
974     /* black border, white interior */
975     Rectangle(memdc, 0, 0, 10, 10);
976 todo_wine {
977     ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
978     ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
979  }
980     /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
981
982     memset(bits, 0, sizeof(bits));
983     bits[0] = 0xaa;
984
985     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
986     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
987
988     /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
989
990     pbmi->bmiColors[0].rgbRed = 0x0;
991     pbmi->bmiColors[0].rgbGreen = 0x0;
992     pbmi->bmiColors[0].rgbBlue = 0x0;
993     pbmi->bmiColors[1].rgbRed = 0xff;
994     pbmi->bmiColors[1].rgbGreen = 0xff;
995     pbmi->bmiColors[1].rgbBlue = 0xff;
996
997     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
998     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
999
1000     SelectObject(memdc, old_bm);
1001     DeleteObject(mono_ds);
1002
1003     /*
1004      * Now a dib section with a strange colour map just for fun.  This behaves just like an inverted one.
1005      */
1006  
1007     pbmi->bmiColors[0].rgbRed = 0xff;
1008     pbmi->bmiColors[0].rgbGreen = 0x0;
1009     pbmi->bmiColors[0].rgbBlue = 0x0;
1010     pbmi->bmiColors[1].rgbRed = 0xfe;
1011     pbmi->bmiColors[1].rgbGreen = 0x0;
1012     pbmi->bmiColors[1].rgbBlue = 0x0;
1013
1014     mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1015     ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1016     old_bm = SelectObject(memdc, mono_ds);
1017
1018     /* black border, white interior */
1019     Rectangle(memdc, 0, 0, 10, 10);
1020     ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1021     ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1022
1023     /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1024
1025     pbmi->bmiColors[0].rgbRed = 0x0;
1026     pbmi->bmiColors[0].rgbGreen = 0x0;
1027     pbmi->bmiColors[0].rgbBlue = 0x0;
1028     pbmi->bmiColors[1].rgbRed = 0xff;
1029     pbmi->bmiColors[1].rgbGreen = 0xff;
1030     pbmi->bmiColors[1].rgbBlue = 0xff;
1031
1032     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1033     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1034
1035     /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
1036
1037     pbmi->bmiColors[0].rgbRed = 0xff;
1038     pbmi->bmiColors[0].rgbGreen = 0xff;
1039     pbmi->bmiColors[0].rgbBlue = 0xff;
1040     pbmi->bmiColors[1].rgbRed = 0x0;
1041     pbmi->bmiColors[1].rgbGreen = 0x0;
1042     pbmi->bmiColors[1].rgbBlue = 0x0;
1043
1044     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1045     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1046
1047     SelectObject(memdc, old_bm);
1048     DeleteObject(mono_ds);
1049
1050     DeleteDC(memdc);
1051     ReleaseDC(0, hdc);
1052 }
1053
1054 static void test_bitmap(void)
1055 {
1056     char buf[256], buf_cmp[256];
1057     HBITMAP hbmp, hbmp_old;
1058     HDC hdc;
1059     BITMAP bm;
1060     BITMAP bma[2];
1061     INT ret;
1062
1063     hdc = CreateCompatibleDC(0);
1064     assert(hdc != 0);
1065
1066     SetLastError(0xdeadbeef);
1067     hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1068     if (!hbmp)
1069     {
1070         ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1071            GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1072            "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1073     }
1074     else
1075         DeleteObject(hbmp);
1076
1077     SetLastError(0xdeadbeef);
1078     hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1079     if (!hbmp)
1080     {
1081         ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1082            GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1083            "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1084     }
1085     else
1086         DeleteObject(hbmp);
1087
1088     SetLastError(0xdeadbeef);
1089     hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1090     ok(!hbmp || broken(hbmp != NULL /* Win9x */), "CreateBitmap should fail\n");
1091     if (!hbmp)
1092         ok(GetLastError() == ERROR_INVALID_PARAMETER,
1093            "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1094     else
1095         DeleteObject(hbmp);
1096
1097     hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1098     assert(hbmp != NULL);
1099
1100     ret = GetObject(hbmp, sizeof(bm), &bm);
1101     ok(ret == sizeof(bm), "wrong size %d\n", ret);
1102
1103     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1104     ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1105     ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1106     ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1107     ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1108     ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1109     ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1110
1111     assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1112     assert(sizeof(buf) == sizeof(buf_cmp));
1113
1114     ret = GetBitmapBits(hbmp, 0, NULL);
1115     ok(ret == bm.bmWidthBytes * bm.bmHeight || broken(ret == 0 /* Win9x */),
1116         "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1117
1118     memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1119     memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1120
1121     memset(buf, 0xAA, sizeof(buf));
1122     ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1123     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1124     ok(!memcmp(buf, buf_cmp, sizeof(buf)) ||
1125        broken(memcmp(buf, buf_cmp, sizeof(buf))), /* win9x doesn't init the bitmap bits */
1126        "buffers do not match\n");
1127
1128     hbmp_old = SelectObject(hdc, hbmp);
1129
1130     ret = GetObject(hbmp, sizeof(bm), &bm);
1131     ok(ret == sizeof(bm), "wrong size %d\n", ret);
1132
1133     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1134     ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1135     ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1136     ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1137     ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1138     ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1139     ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1140
1141     memset(buf, 0xAA, sizeof(buf));
1142     ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1143     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1144     ok(!memcmp(buf, buf_cmp, sizeof(buf)) ||
1145        broken(memcmp(buf, buf_cmp, sizeof(buf))), /* win9x doesn't init the bitmap bits */
1146        "buffers do not match\n");
1147
1148     hbmp_old = SelectObject(hdc, hbmp_old);
1149     ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1150
1151     /* test various buffer sizes for GetObject */
1152     ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
1153     ok(ret == sizeof(*bma) || broken(ret == sizeof(*bma) * 2 /* Win9x */), "wrong size %d\n", ret);
1154
1155     ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1156     ok(ret == 0 || broken(ret == sizeof(bm) / 2 /* Win9x */), "%d != 0\n", ret);
1157
1158     ret = GetObject(hbmp, 0, &bm);
1159     ok(ret == 0, "%d != 0\n", ret);
1160
1161     ret = GetObject(hbmp, 1, &bm);
1162     ok(ret == 0 || broken(ret == 1 /* Win9x */), "%d != 0\n", ret);
1163
1164     DeleteObject(hbmp);
1165     DeleteDC(hdc);
1166 }
1167
1168 static void test_bmBits(void)
1169 {
1170     BYTE bits[4];
1171     HBITMAP hbmp;
1172     BITMAP bmp;
1173
1174     memset(bits, 0, sizeof(bits));
1175     hbmp = CreateBitmap(2, 2, 1, 4, bits);
1176     ok(hbmp != NULL, "CreateBitmap failed\n");
1177
1178     memset(&bmp, 0xFF, sizeof(bmp));
1179     ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1180        "GetObject failed or returned a wrong structure size\n");
1181     ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1182
1183     DeleteObject(hbmp);
1184 }
1185
1186 static void test_GetDIBits_selected_DIB(UINT bpp)
1187 {
1188     HBITMAP dib;
1189     BITMAPINFO * info;
1190     BITMAPINFO * info2;
1191     void * bits;
1192     void * bits2;
1193     UINT dib_size;
1194     HDC dib_dc, dc;
1195     HBITMAP old_bmp;
1196     BOOL equalContents;
1197     UINT i;
1198     int res;
1199
1200     /* Create a DIB section with a color table */
1201
1202     info  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD));
1203     info2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD));
1204     assert(info);
1205     assert(info2);
1206
1207     info->bmiHeader.biSize = sizeof(info->bmiHeader);
1208
1209     /* Choose width and height such that the row length (in bytes)
1210        is a multiple of 4 (makes things easier) */
1211     info->bmiHeader.biWidth = 32;
1212     info->bmiHeader.biHeight = 32;
1213     info->bmiHeader.biPlanes = 1;
1214     info->bmiHeader.biBitCount = bpp;
1215     info->bmiHeader.biCompression = BI_RGB;
1216
1217     for (i=0; i < (1u << bpp); i++)
1218     {
1219         BYTE c = i * (1 << (8 - bpp));
1220         info->bmiColors[i].rgbRed = c;
1221         info->bmiColors[i].rgbGreen = c;
1222         info->bmiColors[i].rgbBlue = c;
1223         info->bmiColors[i].rgbReserved = 0;
1224     }
1225
1226     dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1227     assert(dib);
1228     dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1229
1230     /* Set the bits of the DIB section */
1231     for (i=0; i < dib_size; i++)
1232     {
1233         ((BYTE *)bits)[i] = i % 256;
1234     }
1235
1236     /* Select the DIB into a DC */
1237     dib_dc = CreateCompatibleDC(NULL);
1238     old_bmp = SelectObject(dib_dc, dib);
1239     dc = CreateCompatibleDC(NULL);
1240     bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib_size);
1241     assert(bits2);
1242
1243     /* Copy the DIB attributes but not the color table */
1244     memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1245
1246     res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1247     ok(res, "GetDIBits failed\n");
1248
1249     /* Compare the color table and the bits */
1250     equalContents = TRUE;
1251     for (i=0; i < (1u << bpp); i++)
1252     {
1253         if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed)
1254             || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen)
1255             || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue)
1256             || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved))
1257         {
1258             equalContents = FALSE;
1259             break;
1260         }
1261     }
1262     ok(equalContents, "GetDIBits with DIB selected in DC: Invalid DIB color table\n");
1263
1264     equalContents = TRUE;
1265     for (i=0; i < dib_size / sizeof(DWORD); i++)
1266     {
1267         if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i])
1268         {
1269             equalContents = FALSE;
1270             break;
1271         }
1272     }
1273     ok(equalContents, "GetDIBits with %d bpp DIB selected in DC: Invalid DIB bits\n",bpp);
1274
1275     HeapFree(GetProcessHeap(), 0, bits2);
1276     DeleteDC(dc);
1277
1278     SelectObject(dib_dc, old_bmp);
1279     DeleteDC(dib_dc);
1280     DeleteObject(dib);
1281
1282     HeapFree(GetProcessHeap(), 0, info2);
1283     HeapFree(GetProcessHeap(), 0, info);
1284 }
1285
1286 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1287 {
1288     HBITMAP ddb;
1289     BITMAPINFO * info;
1290     BITMAPINFO * info2;
1291     void * bits;
1292     void * bits2;
1293     HDC ddb_dc, dc;
1294     HBITMAP old_bmp;
1295     BOOL equalContents;
1296     UINT width, height;
1297     UINT bpp;
1298     UINT i, j;
1299     int res;
1300
1301     width = height = 16;
1302
1303     /* Create a DDB (device-dependent bitmap) */
1304     if (monochrome)
1305     {
1306         bpp = 1;
1307         ddb = CreateBitmap(width, height, 1, 1, NULL);
1308     }
1309     else
1310     {
1311         HDC screen_dc = GetDC(NULL);
1312         bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1313         ddb = CreateCompatibleBitmap(screen_dc, width, height);
1314         ReleaseDC(NULL, screen_dc);
1315     }
1316
1317     /* Set the pixels */
1318     ddb_dc = CreateCompatibleDC(NULL);
1319     old_bmp = SelectObject(ddb_dc, ddb);
1320     for (i = 0; i < width; i++)
1321     {
1322         for (j=0; j < height; j++)
1323         {
1324             BYTE c = (i * width + j) % 256;
1325             SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1326         }
1327     }
1328     SelectObject(ddb_dc, old_bmp);
1329
1330     info  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1331     info2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1332     assert(info);
1333     assert(info2);
1334
1335     info->bmiHeader.biSize = sizeof(info->bmiHeader);
1336     info->bmiHeader.biWidth = width;
1337     info->bmiHeader.biHeight = height;
1338     info->bmiHeader.biPlanes = 1;
1339     info->bmiHeader.biBitCount = bpp;
1340     info->bmiHeader.biCompression = BI_RGB;
1341
1342     dc = CreateCompatibleDC(NULL);
1343
1344     /* Fill in biSizeImage */
1345     GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1346     ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1347
1348     bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1349     bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1350     assert(bits);
1351     assert(bits2);
1352
1353     /* Get the bits */
1354     res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1355     ok(res, "GetDIBits failed\n");
1356
1357     /* Copy the DIB attributes but not the color table */
1358     memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1359
1360     /* Select the DDB into another DC */
1361     old_bmp = SelectObject(ddb_dc, ddb);
1362
1363     /* Get the bits */
1364     res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1365     ok(res, "GetDIBits failed\n");
1366
1367     /* Compare the color table and the bits */
1368     if (bpp <= 8)
1369     {
1370         equalContents = TRUE;
1371         for (i=0; i < (1u << bpp); i++)
1372         {
1373             if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed)
1374                 || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen)
1375                 || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue)
1376                 || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved))
1377             {
1378                 equalContents = FALSE;
1379                 break;
1380             }
1381         }
1382         ok(equalContents, "GetDIBits with DDB selected in DC: Got a different color table\n");
1383     }
1384
1385     equalContents = TRUE;
1386     for (i=0; i < info->bmiHeader.biSizeImage / sizeof(DWORD); i++)
1387     {
1388         if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i])
1389         {
1390             equalContents = FALSE;
1391         }
1392     }
1393     ok(equalContents, "GetDIBits with DDB selected in DC: Got different DIB bits\n");
1394
1395     /* Test the palette */
1396     equalContents = TRUE;
1397     if (info2->bmiHeader.biBitCount <= 8)
1398     {
1399         WORD *colors = (WORD*)info2->bmiColors;
1400
1401         /* Get the palette indices */
1402         res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1403         if (res == 0 && GetLastError() == ERROR_INVALID_PARAMETER) /* Win9x */
1404             res = GetDIBits(dc, ddb, 0, height, NULL, info2, DIB_PAL_COLORS);
1405         ok(res, "GetDIBits failed\n");
1406
1407         for (i=0;i < 1 << info->bmiHeader.biSizeImage; i++)
1408         {
1409             if (colors[i] != i)
1410             {
1411                 equalContents = FALSE;
1412                 break;
1413             }
1414         }
1415     }
1416
1417     ok(equalContents, "GetDIBits with DDB selected in DC: non 1:1 palette indices\n");
1418
1419     HeapFree(GetProcessHeap(), 0, bits2);
1420     HeapFree(GetProcessHeap(), 0, bits);
1421     DeleteDC(dc);
1422
1423     SelectObject(ddb_dc, old_bmp);
1424     DeleteDC(ddb_dc);
1425     DeleteObject(ddb);
1426
1427     HeapFree(GetProcessHeap(), 0, info2);
1428     HeapFree(GetProcessHeap(), 0, info);
1429 }
1430
1431 static void test_GetDIBits(void)
1432 {
1433     /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1434     static const BYTE bmp_bits_1[16 * 2] =
1435     {
1436         0xff,0xff, 0,0, 0xff,0xff, 0,0,
1437         0xff,0xff, 0,0, 0xff,0xff, 0,0,
1438         0xff,0xff, 0,0, 0xff,0xff, 0,0,
1439         0xff,0xff, 0,0, 0xff,0xff, 0,0
1440     };
1441     /* 4-bytes aligned 1-bit DIB data: 16x16 */
1442     static const BYTE dib_bits_1[16 * 4] =
1443     {
1444         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1445         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1446         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1447         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1448     };
1449     static const BYTE dib_bits_1_9x[16 * 4] =
1450     {
1451         0,0,0xaa,0xaa, 0xff,0xff,0xaa,0xaa, 0,0,0xaa,0xaa, 0xff,0xff,0xaa,0xaa,
1452         0,0,0xaa,0xaa, 0xff,0xff,0xaa,0xaa, 0,0,0xaa,0xaa, 0xff,0xff,0xaa,0xaa,
1453         0,0,0xaa,0xaa, 0xff,0xff,0xaa,0xaa, 0,0,0xaa,0xaa, 0xff,0xff,0xaa,0xaa,
1454         0,0,0xaa,0xaa, 0xff,0xff,0xaa,0xaa, 0,0,0xaa,0xaa, 0xff,0xff,0xaa,0xaa
1455     };
1456     /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1457     static const BYTE bmp_bits_24[16 * 16*3] =
1458     {
1459         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1460         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1461         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1462         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1463         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1464         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1465         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1466         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1467         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1468         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1469         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1470         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1471         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1472         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1473         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1474         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1475         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1476         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1477         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1478         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1479         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1480         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1481         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1482         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1483         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1484         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1485         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1486         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1487         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1488         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1489         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1490         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1491     };
1492     /* 4-bytes aligned 24-bit DIB data: 16x16 */
1493     static const BYTE dib_bits_24[16 * 16*3] =
1494     {
1495         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1496         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1497         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1498         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1499         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1500         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1501         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1502         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1503         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1504         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1505         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1506         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1507         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1508         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1509         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1510         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1511         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1512         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1513         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1514         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1515         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1516         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1517         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1518         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1519         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1520         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1521         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1522         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1523         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1524         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1525         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1526         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1527     };
1528     HBITMAP hbmp;
1529     BITMAP bm;
1530     HDC hdc;
1531     int i, bytes, lines;
1532     BYTE buf[1024];
1533     char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1534     BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1535
1536     hdc = GetDC(0);
1537
1538     /* 1-bit source bitmap data */
1539     hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1540     ok(hbmp != 0, "CreateBitmap failed\n");
1541
1542     memset(&bm, 0xAA, sizeof(bm));
1543     bytes = GetObject(hbmp, sizeof(bm), &bm);
1544     ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1545     ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1546     ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1547     ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1548     ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1549     ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1550     ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1551     ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1552
1553     bytes = GetBitmapBits(hbmp, 0, NULL);
1554     ok(bytes == sizeof(bmp_bits_1) || broken(bytes == 0 /* Win9x */), "expected 16*2 got %d bytes\n", bytes);
1555     bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1556     ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1557     ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1558
1559     /* retrieve 1-bit DIB data */
1560     memset(bi, 0, sizeof(*bi));
1561     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1562     bi->bmiHeader.biWidth = bm.bmWidth;
1563     bi->bmiHeader.biHeight = bm.bmHeight;
1564     bi->bmiHeader.biPlanes = 1;
1565     bi->bmiHeader.biBitCount = 1;
1566     bi->bmiHeader.biCompression = BI_RGB;
1567     bi->bmiHeader.biSizeImage = 0;
1568     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1569     SetLastError(0xdeadbeef);
1570     lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1571     ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1572     ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1573        broken(GetLastError() == 0xdeadbeef), /* winnt */
1574        "wrong error %u\n", GetLastError());
1575     ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1576
1577     memset(buf, 0xAA, sizeof(buf));
1578     SetLastError(0xdeadbeef);
1579     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1580     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1581        lines, bm.bmHeight, GetLastError());
1582     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1) ||
1583        broken(bi->bmiHeader.biSizeImage == 0), /* win9x */
1584        "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1585
1586     /* the color table consists of black and white */
1587     ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1588        bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1589        "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1590        bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1591        bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1592     ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1593        bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1594        "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1595        bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1596        bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1597     for (i = 2; i < 256; i++)
1598     {
1599         ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1600            bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1601            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1602            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1603            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1604     }
1605
1606     /* returned bits are DWORD aligned and upside down */
1607     ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)) ||
1608        broken(!memcmp(buf, dib_bits_1_9x, sizeof(dib_bits_1_9x))), /* Win9x, WinME */
1609        "DIB bits don't match\n");
1610
1611     /* Test the palette indices */
1612     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1613     SetLastError(0xdeadbeef);
1614     lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1615     if (lines == 0 && GetLastError() == ERROR_INVALID_PARAMETER)
1616         win_skip("Win9x/WinMe doesn't handle 0 for the number of scan lines\n");
1617     else
1618     {
1619         ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1620         ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1621     }
1622     for (i = 2; i < 256; i++)
1623         ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[1]);
1624
1625     /* retrieve 24-bit DIB data */
1626     memset(bi, 0, sizeof(*bi));
1627     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1628     bi->bmiHeader.biWidth = bm.bmWidth;
1629     bi->bmiHeader.biHeight = bm.bmHeight;
1630     bi->bmiHeader.biPlanes = 1;
1631     bi->bmiHeader.biBitCount = 24;
1632     bi->bmiHeader.biCompression = BI_RGB;
1633     bi->bmiHeader.biSizeImage = 0;
1634     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1635     memset(buf, 0xAA, sizeof(buf));
1636     SetLastError(0xdeadbeef);
1637     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1638     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1639        lines, bm.bmHeight, GetLastError());
1640     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24) ||
1641        broken(bi->bmiHeader.biSizeImage == 0), /* win9x */
1642        "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1643
1644     /* the color table doesn't exist for 24-bit images */
1645     for (i = 0; i < 256; i++)
1646     {
1647         ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1648            bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1649            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1650            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1651            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1652     }
1653
1654     /* returned bits are DWORD aligned and upside down */
1655     ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1656     DeleteObject(hbmp);
1657
1658     /* 24-bit source bitmap data */
1659     hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1660     ok(hbmp != 0, "CreateBitmap failed\n");
1661     SetLastError(0xdeadbeef);
1662     bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1663     lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1664     ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1665        lines, bm.bmHeight, GetLastError());
1666
1667     memset(&bm, 0xAA, sizeof(bm));
1668     bytes = GetObject(hbmp, sizeof(bm), &bm);
1669     ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1670     ok(bm.bmType == 0 ||
1671        broken(bm.bmType == 21072), /* win9x */
1672        "wrong bmType %d\n", bm.bmType);
1673     ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1674     ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1675     ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1676     ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1677     ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1678     ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1679
1680     bytes = GetBitmapBits(hbmp, 0, NULL);
1681     ok(bytes == bm.bmWidthBytes * bm.bmHeight ||
1682        broken(bytes == 0), /* win9x */
1683        "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
1684     bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1685     ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1686        bm.bmWidthBytes * bm.bmHeight, bytes);
1687
1688     /* retrieve 1-bit DIB data */
1689     memset(bi, 0, sizeof(*bi));
1690     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1691     bi->bmiHeader.biWidth = bm.bmWidth;
1692     bi->bmiHeader.biHeight = bm.bmHeight;
1693     bi->bmiHeader.biPlanes = 1;
1694     bi->bmiHeader.biBitCount = 1;
1695     bi->bmiHeader.biCompression = BI_RGB;
1696     bi->bmiHeader.biSizeImage = 0;
1697     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1698     memset(buf, 0xAA, sizeof(buf));
1699     SetLastError(0xdeadbeef);
1700     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1701     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1702        lines, bm.bmHeight, GetLastError());
1703     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1) ||
1704        broken(bi->bmiHeader.biSizeImage == 0), /* win9x */
1705        "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1706
1707     /* the color table consists of black and white */
1708     ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1709        bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1710        "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1711        bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1712        bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1713     ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1714        bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1715        "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1716        bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1717        bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1718     for (i = 2; i < 256; i++)
1719     {
1720         ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1721            bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1722            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1723            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1724            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1725     }
1726
1727     /* returned bits are DWORD aligned and upside down */
1728 todo_wine
1729     ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)) ||
1730        broken(!memcmp(buf, dib_bits_1_9x, sizeof(dib_bits_1_9x))), /* Win9x, WinME */
1731        "DIB bits don't match\n");
1732
1733     /* Test the palette indices */
1734     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1735     SetLastError(0xdeadbeef);
1736     lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1737     if (lines == 0 && GetLastError() == ERROR_INVALID_PARAMETER)
1738         win_skip("Win9x/WinMe doesn't handle 0 for the number of scan lines\n");
1739     else
1740     {
1741         ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1742         ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1743     }
1744     for (i = 2; i < 256; i++)
1745         ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[i]);
1746
1747     /* retrieve 24-bit DIB data */
1748     memset(bi, 0, sizeof(*bi));
1749     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1750     bi->bmiHeader.biWidth = bm.bmWidth;
1751     bi->bmiHeader.biHeight = bm.bmHeight;
1752     bi->bmiHeader.biPlanes = 1;
1753     bi->bmiHeader.biBitCount = 24;
1754     bi->bmiHeader.biCompression = BI_RGB;
1755     bi->bmiHeader.biSizeImage = 0;
1756     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1757     memset(buf, 0xAA, sizeof(buf));
1758     SetLastError(0xdeadbeef);
1759     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1760     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1761        lines, bm.bmHeight, GetLastError());
1762     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24) ||
1763        broken(bi->bmiHeader.biSizeImage == 0), /* win9x */
1764        "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1765
1766     /* the color table doesn't exist for 24-bit images */
1767     for (i = 0; i < 256; i++)
1768     {
1769         ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1770            bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1771            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1772            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1773            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1774     }
1775
1776     /* returned bits are DWORD aligned and upside down */
1777     ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1778     DeleteObject(hbmp);
1779
1780     ReleaseDC(0, hdc);
1781 }
1782
1783 static void test_GetDIBits_BI_BITFIELDS(void)
1784 {
1785     /* Try a screen resolution detection technique
1786      * from the September 1999 issue of Windows Developer's Journal
1787      * which seems to be in widespread use.
1788      * http://www.lesher.ws/highcolor.html
1789      * http://www.lesher.ws/vidfmt.c
1790      * It hinges on being able to retrieve the bitmaps
1791      * for the three primary colors in non-paletted 16 bit mode.
1792      */
1793     char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
1794     DWORD bits[32];
1795     LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
1796     HDC hdc;
1797     HBITMAP hbm;
1798     int ret;
1799
1800     memset(dibinfo, 0, sizeof(dibinfo_buf));
1801     dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1802
1803     hdc = GetDC(NULL);
1804     ok(hdc != NULL, "GetDC failed?\n");
1805     hbm = CreateCompatibleBitmap(hdc, 1, 1);
1806     ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
1807
1808     /* Call GetDIBits to fill in bmiHeader.  */
1809     ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1810     ok(ret == 1, "GetDIBits failed\n");
1811     if (dibinfo->bmiHeader.biBitCount > 8)
1812     {
1813         DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
1814
1815         ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
1816             "compression is %u\n", dibinfo->bmiHeader.biCompression );
1817
1818         ok( !bitmasks[0], "red mask is set\n" );
1819         ok( !bitmasks[1], "green mask is set\n" );
1820         ok( !bitmasks[2], "blue mask is set\n" );
1821
1822         /* test with NULL bits pointer and correct bpp */
1823         dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1824         ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1825         ok(ret == 1, "GetDIBits failed\n");
1826
1827         ok( bitmasks[0] != 0, "red mask is not set\n" );
1828         ok( bitmasks[1] != 0, "green mask is not set\n" );
1829         ok( bitmasks[2] != 0, "blue mask is not set\n" );
1830         ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1831
1832         /* test with valid bits pointer */
1833         memset(dibinfo, 0, sizeof(dibinfo_buf));
1834         dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1835         ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1836         ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1837         dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1838         ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
1839         ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1840
1841         ok( bitmasks[0] != 0, "red mask is not set\n" );
1842         ok( bitmasks[1] != 0, "green mask is not set\n" );
1843         ok( bitmasks[2] != 0, "blue mask is not set\n" );
1844         ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef ||
1845             broken(dibinfo->bmiHeader.biSizeImage == 0xdeadbeef), /* win9x */
1846             "size image not set\n" );
1847
1848         /* now with bits and 0 lines */
1849         memset(dibinfo, 0, sizeof(dibinfo_buf));
1850         dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1851         dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1852         SetLastError(0xdeadbeef);
1853         ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
1854         if (ret == 0 && GetLastError() == ERROR_INVALID_PARAMETER)
1855             win_skip("Win9x/WinMe doesn't handle 0 for the number of scan lines\n");
1856         else
1857         {
1858             ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1859
1860             ok( !bitmasks[0], "red mask is set\n" );
1861             ok( !bitmasks[1], "green mask is set\n" );
1862             ok( !bitmasks[2], "blue mask is set\n" );
1863             ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1864
1865             memset(bitmasks, 0, 3*sizeof(DWORD));
1866             dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1867             ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
1868             ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1869
1870             ok( bitmasks[0] != 0, "red mask is not set\n" );
1871             ok( bitmasks[1] != 0, "green mask is not set\n" );
1872             ok( bitmasks[2] != 0, "blue mask is not set\n" );
1873             ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1874         }
1875     }
1876     else skip("not in 16 bpp BI_BITFIELDS mode, skipping that test\n");
1877
1878     DeleteObject(hbm);
1879     ReleaseDC(NULL, hdc);
1880 }
1881
1882 static void test_select_object(void)
1883 {
1884     HDC hdc;
1885     HBITMAP hbm, hbm_old;
1886     INT planes, bpp, i;
1887     DWORD depths[] = {8, 15, 16, 24, 32};
1888     BITMAP bm;
1889     DWORD bytes;
1890
1891     hdc = GetDC(0);
1892     ok(hdc != 0, "GetDC(0) failed\n");
1893     hbm = CreateCompatibleBitmap(hdc, 10, 10);
1894     ok(hbm != 0, "CreateCompatibleBitmap failed\n");
1895
1896     hbm_old = SelectObject(hdc, hbm);
1897     ok(hbm_old == 0, "SelectObject should fail\n");
1898
1899     DeleteObject(hbm);
1900     ReleaseDC(0, hdc);
1901
1902     hdc = CreateCompatibleDC(0);
1903     ok(hdc != 0, "GetDC(0) failed\n");
1904     hbm = CreateCompatibleBitmap(hdc, 10, 10);
1905     ok(hbm != 0, "CreateCompatibleBitmap failed\n");
1906
1907     hbm_old = SelectObject(hdc, hbm);
1908     ok(hbm_old != 0, "SelectObject failed\n");
1909     hbm_old = SelectObject(hdc, hbm_old);
1910     ok(hbm_old == hbm, "SelectObject failed\n");
1911
1912     DeleteObject(hbm);
1913
1914     /* test an 1-bpp bitmap */
1915     planes = GetDeviceCaps(hdc, PLANES);
1916     bpp = 1;
1917
1918     hbm = CreateBitmap(10, 10, planes, bpp, NULL);
1919     ok(hbm != 0, "CreateBitmap failed\n");
1920
1921     hbm_old = SelectObject(hdc, hbm);
1922     ok(hbm_old != 0, "SelectObject failed\n");
1923     hbm_old = SelectObject(hdc, hbm_old);
1924     ok(hbm_old == hbm, "SelectObject failed\n");
1925
1926     DeleteObject(hbm);
1927
1928     for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
1929         /* test a color bitmap to dc bpp matching */
1930         planes = GetDeviceCaps(hdc, PLANES);
1931         bpp = GetDeviceCaps(hdc, BITSPIXEL);
1932
1933         hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
1934         ok(hbm != 0, "CreateBitmap failed\n");
1935
1936         hbm_old = SelectObject(hdc, hbm);
1937         if(depths[i] == bpp ||
1938           (bpp == 16 && depths[i] == 15)        /* 16 and 15 bpp are compatible */
1939           ) {
1940             ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
1941             SelectObject(hdc, hbm_old);
1942         } else {
1943             ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
1944         }
1945
1946         memset(&bm, 0xAA, sizeof(bm));
1947         bytes = GetObject(hbm, sizeof(bm), &bm);
1948         ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1949         ok(bm.bmType == 0 ||
1950            broken(bm.bmType == 21072), /* win9x */
1951            "wrong bmType %d\n", bm.bmType);
1952         ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
1953         ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
1954         ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1955         ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
1956         if(depths[i] == 15) {
1957             ok(bm.bmBitsPixel == 16 ||
1958                broken(bm.bmBitsPixel == 15), /* Win9x/WinME */
1959                "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
1960         } else {
1961             ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1962         }
1963         ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1964
1965         DeleteObject(hbm);
1966     }
1967
1968     DeleteDC(hdc);
1969 }
1970
1971 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
1972 {
1973     INT ret;
1974     BITMAP bm;
1975
1976     ret = GetObjectType(hbmp);
1977     ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
1978
1979     ret = GetObject(hbmp, 0, 0);
1980     ok_(__FILE__, line)(ret == sizeof(BITMAP) /* XP */ ||
1981                         ret == sizeof(DIBSECTION) /* Win9x */, "object size %d\n", ret);
1982
1983     memset(&bm, 0xDA, sizeof(bm));
1984     SetLastError(0xdeadbeef);
1985     ret = GetObject(hbmp, sizeof(bm), &bm);
1986     if (!ret) /* XP, only for curObj2 */ return;
1987     ok_(__FILE__, line)(ret == sizeof(BITMAP) ||
1988                         ret == sizeof(DIBSECTION) /* Win9x, only for curObj2 */,
1989                         "GetObject returned %d, error %u\n", ret, GetLastError());
1990     ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
1991     ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
1992     ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
1993     ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
1994     ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
1995     ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
1996     ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1997 }
1998
1999 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2000
2001 static void test_CreateBitmap(void)
2002 {
2003     BITMAP bmp;
2004     HDC screenDC = GetDC(0);
2005     HDC hdc = CreateCompatibleDC(screenDC);
2006     UINT i, expect = 0;
2007
2008     /* all of these are the stock monochrome bitmap */
2009     HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2010     HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2011     HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2012     HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2013     HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2014     HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2015
2016     /* these 2 are not the stock monochrome bitmap */
2017     HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2018     HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2019
2020     HBITMAP old1 = SelectObject(hdc, bm2);
2021     HBITMAP old2 = SelectObject(screenDC, bm3);
2022     SelectObject(hdc, old1);
2023     SelectObject(screenDC, old2);
2024
2025     ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2026        "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2027        bm, bm1, bm4, bm5, curObj1, old1);
2028     ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2029 todo_wine
2030     ok(bm != curObj2 || /* WinXP */
2031        broken(bm == curObj2) /* Win9x */,
2032        "0: %p, curObj2 %p\n", bm, curObj2);
2033     ok(old2 == 0, "old2 %p\n", old2);
2034
2035     test_mono_1x1_bmp(bm);
2036     test_mono_1x1_bmp(bm1);
2037     test_mono_1x1_bmp(bm2);
2038     test_mono_1x1_bmp(bm3);
2039     test_mono_1x1_bmp(bm4);
2040     test_mono_1x1_bmp(bm5);
2041     test_mono_1x1_bmp(old1);
2042     test_mono_1x1_bmp(curObj1);
2043
2044     DeleteObject(bm);
2045     DeleteObject(bm1);
2046     DeleteObject(bm2);
2047     DeleteObject(bm3);
2048     DeleteObject(bm4);
2049     DeleteObject(bm5);
2050
2051     DeleteDC(hdc);
2052     ReleaseDC(0, screenDC);
2053
2054     /* show that Windows ignores the provided bm.bmWidthBytes */
2055     bmp.bmType = 0;
2056     bmp.bmWidth = 1;
2057     bmp.bmHeight = 1;
2058     bmp.bmWidthBytes = 28;
2059     bmp.bmPlanes = 1;
2060     bmp.bmBitsPixel = 1;
2061     bmp.bmBits = NULL;
2062     bm = CreateBitmapIndirect(&bmp);
2063     ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2064     test_mono_1x1_bmp(bm);
2065     DeleteObject(bm);
2066
2067     /* Test how the bmBitsPixel field is treated */
2068     for(i = 1; i <= 33; i++) {
2069         bmp.bmType = 0;
2070         bmp.bmWidth = 1;
2071         bmp.bmHeight = 1;
2072         bmp.bmWidthBytes = 28;
2073         bmp.bmPlanes = 1;
2074         bmp.bmBitsPixel = i;
2075         bmp.bmBits = NULL;
2076         SetLastError(0xdeadbeef);
2077         bm = CreateBitmapIndirect(&bmp);
2078         if(i > 32) {
2079             DWORD error = GetLastError();
2080             ok(bm == 0 ||
2081                broken(bm != 0), /* Win9x and WinMe */
2082                "CreateBitmapIndirect for %d bpp succeeded\n", i);
2083             ok(error == ERROR_INVALID_PARAMETER ||
2084                broken(error == 0xdeadbeef), /* Win9x and WinME */
2085                "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2086             DeleteObject(bm);
2087             continue;
2088         }
2089         ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2090         GetObject(bm, sizeof(bmp), &bmp);
2091         if(i == 1) {
2092             expect = 1;
2093         } else if(i <= 4) {
2094             expect = 4;
2095         } else if(i <= 8) {
2096             expect = 8;
2097         } else if(i <= 16) {
2098             expect = 16;
2099         } else if(i <= 24) {
2100             expect = 24;
2101         } else if(i <= 32) {
2102             expect = 32;
2103         }
2104         ok(bmp.bmBitsPixel == expect ||
2105            broken(bmp.bmBitsPixel == i), /* Win9x and WinMe */
2106            "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2107            i, bmp.bmBitsPixel, expect);
2108         DeleteObject(bm);
2109     }
2110 }
2111
2112 static void test_bitmapinfoheadersize(void)
2113 {
2114     HBITMAP hdib;
2115     BITMAPINFO bmi;
2116     BITMAPCOREINFO bci;
2117     HDC hdc = GetDC(0);
2118
2119     memset(&bmi, 0, sizeof(BITMAPINFO));
2120     bmi.bmiHeader.biHeight = 100;
2121     bmi.bmiHeader.biWidth = 512;
2122     bmi.bmiHeader.biBitCount = 24;
2123     bmi.bmiHeader.biPlanes = 1;
2124
2125     bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2126
2127     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2128     ok(hdib == NULL, "CreateDIBSection succeeded\n");
2129
2130     bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2131
2132     SetLastError(0xdeadbeef);
2133     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2134     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2135     DeleteObject(hdib);
2136
2137     bmi.bmiHeader.biSize++;
2138
2139     SetLastError(0xdeadbeef);
2140     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2141     ok(hdib != NULL ||
2142        broken(!hdib), /* Win98, WinMe */
2143        "CreateDIBSection error %d\n", GetLastError());
2144     DeleteObject(hdib);
2145
2146     bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2147
2148     SetLastError(0xdeadbeef);
2149     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2150     ok(hdib != NULL ||
2151        broken(!hdib), /* Win98, WinMe */
2152        "CreateDIBSection error %d\n", GetLastError());
2153     DeleteObject(hdib);
2154
2155     bmi.bmiHeader.biSize++;
2156
2157     SetLastError(0xdeadbeef);
2158     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2159     ok(hdib != NULL ||
2160        broken(!hdib), /* Win98, WinMe */
2161        "CreateDIBSection error %d\n", GetLastError());
2162     DeleteObject(hdib);
2163
2164     bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2165
2166     SetLastError(0xdeadbeef);
2167     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2168     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2169     DeleteObject(hdib);
2170
2171     bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2172
2173     SetLastError(0xdeadbeef);
2174     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2175     ok(hdib != NULL ||
2176        broken(!hdib), /* Win95 */
2177        "CreateDIBSection error %d\n", GetLastError());
2178     DeleteObject(hdib);
2179
2180     memset(&bci, 0, sizeof(BITMAPCOREINFO));
2181     bci.bmciHeader.bcHeight = 100;
2182     bci.bmciHeader.bcWidth = 512;
2183     bci.bmciHeader.bcBitCount = 24;
2184     bci.bmciHeader.bcPlanes = 1;
2185
2186     bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2187
2188     hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2189     ok(hdib == NULL, "CreateDIBSection succeeded\n");
2190
2191     bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2192
2193     SetLastError(0xdeadbeef);
2194     hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2195     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2196     DeleteObject(hdib);
2197
2198     bci.bmciHeader.bcSize++;
2199
2200     hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2201     ok(hdib == NULL, "CreateDIBSection succeeded\n");
2202
2203     bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2204
2205     hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2206     ok(hdib == NULL, "CreateDIBSection succeeded\n");
2207
2208     ReleaseDC(0, hdc);
2209 }
2210
2211 static void test_get16dibits(void)
2212 {
2213     BYTE bits[4 * (16 / sizeof(BYTE))];
2214     HBITMAP hbmp;
2215     HDC screen_dc = GetDC(NULL);
2216     int ret;
2217     BITMAPINFO * info;
2218     int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2219     BYTE *p;
2220     int overwritten_bytes = 0;
2221
2222     memset(bits, 0, sizeof(bits));
2223     hbmp = CreateBitmap(2, 2, 1, 16, bits);
2224     ok(hbmp != NULL, "CreateBitmap failed\n");
2225
2226     info  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2227     assert(info);
2228
2229     memset(info, '!', info_len);
2230     memset(info, 0, sizeof(info->bmiHeader));
2231
2232     info->bmiHeader.biSize = sizeof(info->bmiHeader);
2233     info->bmiHeader.biWidth = 2;
2234     info->bmiHeader.biHeight = 2;
2235     info->bmiHeader.biPlanes = 1;
2236     info->bmiHeader.biCompression = BI_RGB;
2237
2238     ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2239     ok(ret != 0 ||
2240        broken(ret == 0), /* win9x */
2241        "GetDIBits failed got %d\n", ret);
2242
2243     for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2244         if (*p != '!')
2245             overwritten_bytes++;
2246     ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2247
2248     HeapFree(GetProcessHeap(), 0, info);
2249     DeleteObject(hbmp);
2250     ReleaseDC(NULL, screen_dc);
2251 }
2252
2253 static void test_GdiAlphaBlend(void)
2254 {
2255     /* test out-of-bound parameters for GdiAlphaBlend */
2256     HDC hdcNull;
2257
2258     HDC hdcDst;
2259     HBITMAP bmpDst;
2260     HBITMAP oldDst;
2261
2262     BITMAPINFO bmi;
2263     HDC hdcSrc;
2264     HBITMAP bmpSrc;
2265     HBITMAP oldSrc;
2266     LPVOID bits;
2267
2268     BLENDFUNCTION blend;
2269
2270     if (!pGdiAlphaBlend)
2271     {
2272         win_skip("GdiAlphaBlend() is not implemented\n");
2273         return;
2274     }
2275
2276     hdcNull = GetDC(NULL);
2277     hdcDst = CreateCompatibleDC(hdcNull);
2278     bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
2279     hdcSrc = CreateCompatibleDC(hdcNull);
2280
2281     memset(&bmi, 0, sizeof(bmi));  /* as of Wine 0.9.44 we require the src to be a DIB section */
2282     bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
2283     bmi.bmiHeader.biHeight = 20;
2284     bmi.bmiHeader.biWidth = 20;
2285     bmi.bmiHeader.biBitCount = 32;
2286     bmi.bmiHeader.biPlanes = 1;
2287     bmi.bmiHeader.biCompression = BI_RGB;
2288     bmpSrc = CreateDIBSection(hdcDst, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
2289     ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
2290
2291     oldDst = SelectObject(hdcDst, bmpDst);
2292     oldSrc = SelectObject(hdcSrc, bmpSrc);
2293
2294     blend.BlendOp = AC_SRC_OVER;
2295     blend.BlendFlags = 0;
2296     blend.SourceConstantAlpha = 128;
2297     blend.AlphaFormat = 0;
2298
2299     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend), TRUE, BOOL, "%d");
2300     SetLastError(0xdeadbeef);
2301     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), FALSE, BOOL, "%d");
2302     expect_eq(GetLastError(), ERROR_INVALID_PARAMETER, int, "%d");
2303     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), FALSE, BOOL, "%d");
2304     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend), FALSE, BOOL, "%d");
2305     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
2306     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
2307
2308     SetWindowOrgEx(hdcSrc, -10, -10, NULL);
2309     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), TRUE, BOOL, "%d");
2310     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), TRUE, BOOL, "%d");
2311     SetMapMode(hdcSrc, MM_ANISOTROPIC);
2312     ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
2313     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend), TRUE, BOOL, "%d");
2314     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend), TRUE, BOOL, "%d");
2315
2316     SelectObject(hdcDst, oldDst);
2317     SelectObject(hdcSrc, oldSrc);
2318     DeleteObject(bmpSrc);
2319     DeleteObject(bmpDst);
2320     DeleteDC(hdcDst);
2321     DeleteDC(hdcSrc);
2322
2323     ReleaseDC(NULL, hdcNull);
2324
2325 }
2326
2327 static void test_clipping(void)
2328 {
2329     HBITMAP bmpDst;
2330     HBITMAP oldDst;
2331     HBITMAP bmpSrc;
2332     HBITMAP oldSrc;
2333     HRGN hRgn;
2334     LPVOID bits;
2335     BOOL result;
2336
2337     HDC hdcDst = CreateCompatibleDC( NULL );
2338     HDC hdcSrc = CreateCompatibleDC( NULL );
2339
2340     BITMAPINFO bmpinfo={{0}};
2341     bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2342     bmpinfo.bmiHeader.biWidth = 100;
2343     bmpinfo.bmiHeader.biHeight = 100;
2344     bmpinfo.bmiHeader.biPlanes = 1;
2345     bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
2346     bmpinfo.bmiHeader.biCompression = BI_RGB;
2347
2348     bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
2349     ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
2350     oldDst = SelectObject( hdcDst, bmpDst );
2351
2352     bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
2353     ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
2354     oldSrc = SelectObject( hdcSrc, bmpSrc );
2355
2356     result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
2357     ok(result, "BitBlt failed\n");
2358
2359     hRgn = CreateRectRgn( 0,0,0,0 );
2360     SelectClipRgn( hdcDst, hRgn );
2361
2362     result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
2363     ok(result, "BitBlt failed\n");
2364
2365     DeleteObject( bmpDst );
2366     DeleteObject( bmpSrc );
2367     DeleteObject( hRgn );
2368     DeleteDC( hdcDst );
2369     DeleteDC( hdcSrc );
2370 }
2371
2372 START_TEST(bitmap)
2373 {
2374     HMODULE hdll;
2375     is_win9x = GetWindowLongPtrW(GetDesktopWindow(), GWLP_WNDPROC) == 0;
2376
2377     hdll = GetModuleHandle("gdi32.dll");
2378     pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
2379
2380     test_createdibitmap();
2381     test_dibsections();
2382     test_mono_dibsection();
2383     test_bitmap();
2384     test_bmBits();
2385     test_GetDIBits_selected_DIB(1);
2386     test_GetDIBits_selected_DIB(4);
2387     test_GetDIBits_selected_DIB(8);
2388     test_GetDIBits_selected_DDB(TRUE);
2389     test_GetDIBits_selected_DDB(FALSE);
2390     test_GetDIBits();
2391     test_GetDIBits_BI_BITFIELDS();
2392     test_select_object();
2393     test_CreateBitmap();
2394     test_GdiAlphaBlend();
2395     test_bitmapinfoheadersize();
2396     test_get16dibits();
2397     test_clipping();
2398 }