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