d3d9: Implement IDirect3DVertexBuffer9 private data handling on top of wined3d_resource.
[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 INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp )
40 {
41     switch(bpp)
42     {
43     case 1:
44         return 2 * ((bmWidth+15) >> 4);
45
46     case 24:
47         bmWidth *= 3; /* fall through */
48     case 8:
49         return bmWidth + (bmWidth & 1);
50
51     case 32:
52         return bmWidth * 4;
53
54     case 16:
55     case 15:
56         return bmWidth * 2;
57
58     case 4:
59         return 2 * ((bmWidth+3) >> 2);
60
61     default:
62         trace("Unknown depth %d, please report.\n", bpp );
63         assert(0);
64     }
65     return -1;
66 }
67
68 static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHEADER *bmih)
69 {
70     BITMAP bm;
71     BITMAP bma[2];
72     INT ret, width_bytes;
73     BYTE buf[512], buf_cmp[512];
74
75     ret = GetObject(hbm, sizeof(bm), &bm);
76     ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
77
78     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
79     ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
80     ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
81     width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
82     ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
83     ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
84     ok(bm.bmBitsPixel == expected_depth, "wrong bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, expected_depth);
85     ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
86
87     assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
88     assert(sizeof(buf) == sizeof(buf_cmp));
89
90     SetLastError(0xdeadbeef);
91     ret = GetBitmapBits(hbm, 0, NULL);
92     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
93
94     memset(buf_cmp, 0xAA, sizeof(buf_cmp));
95     memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
96
97     memset(buf, 0xAA, sizeof(buf));
98     ret = GetBitmapBits(hbm, sizeof(buf), buf);
99     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
100     ok(!memcmp(buf, buf_cmp, sizeof(buf)),
101         "buffers do not match, depth %d\n", bmih->biBitCount);
102
103     /* test various buffer sizes for GetObject */
104     ret = GetObject(hbm, sizeof(*bma) * 2, bma);
105     ok(ret == sizeof(*bma), "wrong size %d\n", ret);
106
107     ret = GetObject(hbm, sizeof(bm) / 2, &bm);
108     ok(ret == 0, "%d != 0\n", ret);
109
110     ret = GetObject(hbm, 0, &bm);
111     ok(ret == 0, "%d != 0\n", ret);
112
113     ret = GetObject(hbm, 1, &bm);
114     ok(ret == 0, "%d != 0\n", ret);
115
116     ret = GetObject(hbm, 0, NULL);
117     ok(ret == sizeof(bm), "wrong size %d\n", ret);
118 }
119
120 static void test_createdibitmap(void)
121 {
122     HDC hdc, hdcmem;
123     BITMAPINFOHEADER bmih;
124     BITMAPINFO bm;
125     HBITMAP hbm, hbm_colour, hbm_old;
126     INT screen_depth;
127     DWORD pixel;
128
129     hdc = GetDC(0);
130     screen_depth = GetDeviceCaps(hdc, BITSPIXEL);
131     memset(&bmih, 0, sizeof(bmih));
132     bmih.biSize = sizeof(bmih);
133     bmih.biWidth = 10;
134     bmih.biHeight = 10;
135     bmih.biPlanes = 1;
136     bmih.biBitCount = 32;
137     bmih.biCompression = BI_RGB;
138
139     hbm = CreateDIBitmap(hdc, NULL, CBM_INIT, NULL, NULL, 0);
140     ok(hbm == NULL, "CreateDIBitmap should fail\n");
141     hbm = CreateDIBitmap(hdc, NULL, 0, NULL, NULL, 0);
142     ok(hbm == NULL, "CreateDIBitmap should fail\n");
143
144     /* First create an un-initialised bitmap.  The depth of the bitmap
145        should match that of the hdc and not that supplied in bmih.
146     */
147
148     /* First try 32 bits */
149     hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
150     ok(hbm != NULL, "CreateDIBitmap failed\n");
151     test_bitmap_info(hbm, screen_depth, &bmih);
152     DeleteObject(hbm);
153     
154     /* Then 16 */
155     bmih.biBitCount = 16;
156     hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
157     ok(hbm != NULL, "CreateDIBitmap failed\n");
158     test_bitmap_info(hbm, screen_depth, &bmih);
159     DeleteObject(hbm);
160
161     /* Then 1 */
162     bmih.biBitCount = 1;
163     hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
164     ok(hbm != NULL, "CreateDIBitmap failed\n");
165     test_bitmap_info(hbm, screen_depth, &bmih);
166     DeleteObject(hbm);
167
168     /* Now with a monochrome dc we expect a monochrome bitmap */
169     hdcmem = CreateCompatibleDC(hdc);
170
171     /* First try 32 bits */
172     bmih.biBitCount = 32;
173     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
174     ok(hbm != NULL, "CreateDIBitmap failed\n");
175     test_bitmap_info(hbm, 1, &bmih);
176     DeleteObject(hbm);
177     
178     /* Then 16 */
179     bmih.biBitCount = 16;
180     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
181     ok(hbm != NULL, "CreateDIBitmap failed\n");
182     test_bitmap_info(hbm, 1, &bmih);
183     DeleteObject(hbm);
184     
185     /* Then 1 */
186     bmih.biBitCount = 1;
187     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
188     ok(hbm != NULL, "CreateDIBitmap failed\n");
189     test_bitmap_info(hbm, 1, &bmih);
190     DeleteObject(hbm);
191
192     /* Now select a polychrome bitmap into the dc and we expect
193        screen_depth bitmaps again */
194     hbm_colour = CreateCompatibleBitmap(hdc, bmih.biWidth, bmih.biHeight);
195     test_bitmap_info(hbm_colour, screen_depth, &bmih);
196     hbm_old = SelectObject(hdcmem, hbm_colour);
197
198     /* First try 32 bits */
199     bmih.biBitCount = 32;
200     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
201     ok(hbm != NULL, "CreateDIBitmap failed\n");
202     test_bitmap_info(hbm, screen_depth, &bmih);
203     DeleteObject(hbm);
204     
205     /* Then 16 */
206     bmih.biBitCount = 16;
207     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
208     ok(hbm != NULL, "CreateDIBitmap failed\n");
209     test_bitmap_info(hbm, screen_depth, &bmih);
210     DeleteObject(hbm);
211     
212     /* Then 1 */
213     bmih.biBitCount = 1;
214     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
215     ok(hbm != NULL, "CreateDIBitmap failed\n");
216     test_bitmap_info(hbm, screen_depth, &bmih);
217     DeleteObject(hbm);
218
219     SelectObject(hdcmem, hbm_old);
220     DeleteObject(hbm_colour);
221     DeleteDC(hdcmem);
222
223     bmih.biBitCount = 32;
224     hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0);
225     ok(hbm != NULL, "CreateDIBitmap failed\n");
226     test_bitmap_info(hbm, 1, &bmih);
227     DeleteObject(hbm);
228
229     /* Test how formats are converted */
230     pixel = 0xffffffff;
231     bmih.biBitCount = 1;
232     bmih.biWidth = 1;
233     bmih.biHeight = 1;
234
235     memset(&bm, 0, sizeof(bm));
236     bm.bmiHeader.biSize = sizeof(bm.bmiHeader);
237     bm.bmiHeader.biWidth = 1;
238     bm.bmiHeader.biHeight = 1;
239     bm.bmiHeader.biPlanes = 1;
240     bm.bmiHeader.biBitCount= 24;
241     bm.bmiHeader.biCompression= BI_RGB;
242     bm.bmiHeader.biSizeImage = 0;
243     hbm = CreateDIBitmap(hdc, &bmih, CBM_INIT, &pixel, &bm, DIB_RGB_COLORS);
244     ok(hbm != NULL, "CreateDIBitmap failed\n");
245
246     pixel = 0xdeadbeef;
247     bm.bmiHeader.biBitCount= 32;
248     GetDIBits(hdc, hbm, 0, 1, &pixel, &bm, DIB_RGB_COLORS);
249     ok(pixel == 0x00ffffff, "Reading a 32 bit pixel from a DDB returned %08x\n", pixel);
250     DeleteObject(hbm);
251
252     ReleaseDC(0, hdc);
253 }
254
255 static INT DIB_GetWidthBytes( int width, int bpp )
256 {
257     int words;
258
259     switch (bpp)
260     {
261         case 1:  words = (width + 31) / 32; break;
262         case 4:  words = (width + 7) / 8; break;
263         case 8:  words = (width + 3) / 4; break;
264         case 15:
265         case 16: words = (width + 1) / 2; break;
266         case 24: words = (width * 3 + 3)/4; break;
267         case 32: words = width; break;
268
269         default:
270             words=0;
271             trace("Unknown depth %d, please report.\n", bpp );
272             assert(0);
273             break;
274     }
275     return 4 * words;
276 }
277
278 static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
279 {
280     BITMAP bm;
281     BITMAP bma[2];
282     DIBSECTION ds;
283     DIBSECTION dsa[2];
284     INT ret, bm_width_bytes, dib_width_bytes;
285     BYTE *buf;
286
287     ret = GetObject(hbm, sizeof(bm), &bm);
288     ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
289
290     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
291     ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
292     ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
293     dib_width_bytes = DIB_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
294     bm_width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
295     if (bm.bmWidthBytes != dib_width_bytes) /* Win2k bug */
296         ok(bm.bmWidthBytes == bm_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, bm_width_bytes);
297     else
298         ok(bm.bmWidthBytes == dib_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, dib_width_bytes);
299     ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
300     ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount);
301     ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
302
303     buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);
304
305     /* GetBitmapBits returns not 32-bit aligned data */
306     SetLastError(0xdeadbeef);
307     ret = GetBitmapBits(hbm, 0, NULL);
308     ok(ret == bm_width_bytes * bm.bmHeight,
309         "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
310
311     memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
312     ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
313     ok(ret == bm_width_bytes * bm.bmHeight, "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
314
315     HeapFree(GetProcessHeap(), 0, buf);
316
317     /* test various buffer sizes for GetObject */
318     memset(&ds, 0xAA, sizeof(ds));
319     ret = GetObject(hbm, sizeof(*bma) * 2, bma);
320     ok(ret == sizeof(*bma), "wrong size %d\n", ret);
321     ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
322     ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
323     ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
324
325     ret = GetObject(hbm, sizeof(bm) / 2, &bm);
326     ok(ret == 0, "%d != 0\n", ret);
327
328     ret = GetObject(hbm, 0, &bm);
329     ok(ret == 0, "%d != 0\n", ret);
330
331     ret = GetObject(hbm, 1, &bm);
332     ok(ret == 0, "%d != 0\n", ret);
333
334     /* test various buffer sizes for GetObject */
335     ret = GetObject(hbm, 0, NULL);
336     ok(ret == sizeof(bm), "wrong size %d\n", ret);
337
338     ret = GetObject(hbm, sizeof(*dsa) * 2, dsa);
339     ok(ret == sizeof(*dsa), "wrong size %d\n", ret);
340
341     memset(&ds, 0xAA, sizeof(ds));
342     ret = GetObject(hbm, sizeof(ds), &ds);
343     ok(ret == sizeof(ds), "wrong size %d\n", ret);
344
345     ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
346     if (ds.dsBm.bmWidthBytes != bm_width_bytes) /* Win2k bug */
347         ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%u != %u\n",
348            ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
349     ok(bmih->biSizeImage == 0, "%u != 0\n", bmih->biSizeImage);
350     ds.dsBmih.biSizeImage = 0;
351
352     ok(ds.dsBmih.biSize == bmih->biSize, "%u != %u\n", ds.dsBmih.biSize, bmih->biSize);
353     ok(ds.dsBmih.biWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
354     ok(ds.dsBmih.biHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
355     ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes);
356     ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount);
357     ok(ds.dsBmih.biCompression == bmih->biCompression, "%u != %u\n", ds.dsBmih.biCompression, bmih->biCompression);
358     ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%u != %u\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
359     ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%d != %d\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
360     ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%d != %d\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);
361
362     memset(&ds, 0xAA, sizeof(ds));
363     ret = GetObject(hbm, sizeof(ds) - 4, &ds);
364     ok(ret == sizeof(ds.dsBm), "wrong size %d\n", ret);
365     ok(ds.dsBm.bmWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
366     ok(ds.dsBm.bmHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
367     ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);
368
369     ret = GetObject(hbm, 0, &ds);
370     ok(ret == 0, "%d != 0\n", ret);
371
372     ret = GetObject(hbm, 1, &ds);
373     ok(ret == 0, "%d != 0\n", ret);
374 }
375
376 #define test_color_todo(got, exp, txt, todo) \
377     if (!todo && got != exp && screen_depth < 24) { \
378       todo_wine ok(0, #txt " failed at %d-bit screen depth: got 0x%06x expected 0x%06x - skipping DIB tests\n", \
379                    screen_depth, (UINT)got, (UINT)exp); \
380       return; \
381     } else if (todo) todo_wine { ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp); } \
382     else ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp) \
383
384 #define test_color(hdc, color, exp, todo_setp, todo_getp) \
385 { \
386     COLORREF c; \
387     c = SetPixel(hdc, 0, 0, color); \
388     test_color_todo(c, exp, SetPixel, todo_setp); \
389     c = GetPixel(hdc, 0, 0); \
390     test_color_todo(c, exp, GetPixel, todo_getp); \
391 }
392
393 static void test_dib_bits_access( HBITMAP hdib, void *bits )
394 {
395     MEMORY_BASIC_INFORMATION info;
396     char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
397     DWORD data[256];
398     BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
399     HDC hdc;
400     char filename[MAX_PATH];
401     HANDLE file;
402     DWORD written;
403     INT ret;
404
405     ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
406         "VirtualQuery failed\n");
407     ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
408     ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
409     ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
410     ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
411     ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
412     ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
413
414     memset( pbmi, 0, sizeof(bmibuf) );
415     memset( data, 0xcc, sizeof(data) );
416     pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
417     pbmi->bmiHeader.biHeight = 16;
418     pbmi->bmiHeader.biWidth = 16;
419     pbmi->bmiHeader.biBitCount = 32;
420     pbmi->bmiHeader.biPlanes = 1;
421     pbmi->bmiHeader.biCompression = BI_RGB;
422
423     hdc = GetDC(0);
424
425     ret = SetDIBits( hdc, hdib, 0, 16, data, pbmi, DIB_RGB_COLORS );
426     ok(ret == 16, "SetDIBits failed: expected 16 got %d\n", ret);
427
428     ReleaseDC(0, hdc);
429
430     ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
431         "VirtualQuery failed\n");
432     ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
433     ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
434     ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
435     ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
436     ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
437     /* it has been protected now */
438     todo_wine ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
439
440     /* try writing protected bits to a file */
441
442     GetTempFileNameA( ".", "dib", 0, filename );
443     file = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
444                         CREATE_ALWAYS, 0, 0 );
445     ok( file != INVALID_HANDLE_VALUE, "failed to open %s error %u\n", filename, GetLastError() );
446     ret = WriteFile( file, bits, 8192, &written, NULL );
447     ok( ret, "WriteFile failed error %u\n", GetLastError() );
448     if (ret) ok( written == 8192, "only wrote %u bytes\n", written );
449     CloseHandle( file );
450     DeleteFileA( filename );
451 }
452
453 static void test_dibsections(void)
454 {
455     HDC hdc, hdcmem, hdcmem2;
456     HBITMAP hdib, oldbm, hdib2, oldbm2;
457     char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
458     char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
459     BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
460     BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
461     HBITMAP hcoredib;
462     char coreBits[256];
463     BYTE *bits;
464     RGBQUAD rgb[256];
465     int ret;
466     char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
467     LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
468     WORD *index;
469     DWORD *bits32;
470     HPALETTE hpal, oldpal;
471     DIBSECTION dibsec;
472     COLORREF c0, c1;
473     int i;
474     int screen_depth;
475     MEMORY_BASIC_INFORMATION info;
476
477     hdc = GetDC(0);
478     screen_depth = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
479
480     memset(pbmi, 0, sizeof(bmibuf));
481     pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
482     pbmi->bmiHeader.biHeight = 100;
483     pbmi->bmiHeader.biWidth = 512;
484     pbmi->bmiHeader.biBitCount = 24;
485     pbmi->bmiHeader.biPlanes = 1;
486     pbmi->bmiHeader.biCompression = BI_RGB;
487
488     SetLastError(0xdeadbeef);
489
490     /* invalid pointer for BITMAPINFO
491        (*bits should be NULL on error) */
492     bits = (BYTE*)0xdeadbeef;
493     hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
494     ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n");
495
496     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
497     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
498     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
499     ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
500
501     /* test the DIB memory */
502     ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
503         "VirtualQuery failed\n");
504     ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
505     ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
506     ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
507     ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
508     ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
509     ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
510     ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
511
512     test_dib_bits_access( hdib, bits );
513
514     test_dib_info(hdib, bits, &pbmi->bmiHeader);
515     DeleteObject(hdib);
516
517     /* Test a top-down DIB. */
518     pbmi->bmiHeader.biHeight = -100;
519     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
520     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
521     test_dib_info(hdib, bits, &pbmi->bmiHeader);
522     DeleteObject(hdib);
523
524     pbmi->bmiHeader.biHeight = 100;
525     pbmi->bmiHeader.biBitCount = 8;
526     pbmi->bmiHeader.biCompression = BI_RLE8;
527     SetLastError(0xdeadbeef);
528     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
529     ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
530     ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
531
532     for (i = 0; i < 128; i++)
533     {
534         pbmi->bmiHeader.biBitCount = i;
535         pbmi->bmiHeader.biCompression = BI_RGB;
536         hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
537         if (i == 1 || i == 4 || i == 8 || i == 16 || i == 24 || i == 32)
538             ok(hdib != NULL, "CreateDIBSection bpp %u\n", i);
539         else
540             ok(hdib == NULL, "CreateDIBSection bpp %u succeeded\n", i);
541         if (hdib) DeleteObject( hdib );
542     }
543
544     pbmi->bmiHeader.biBitCount = 16;
545     pbmi->bmiHeader.biCompression = BI_BITFIELDS;
546     ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
547     ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
548     ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
549     SetLastError(0xdeadbeef);
550     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
551     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
552
553     /* test the DIB memory */
554     ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
555         "VirtualQuery failed\n");
556     ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
557     ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
558     ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
559     ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
560     ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
561     ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
562     ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
563
564     test_dib_info(hdib, bits, &pbmi->bmiHeader);
565     DeleteObject(hdib);
566
567     memset(pbmi, 0, sizeof(bmibuf));
568     pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
569     pbmi->bmiHeader.biHeight = 16;
570     pbmi->bmiHeader.biWidth = 16;
571     pbmi->bmiHeader.biBitCount = 1;
572     pbmi->bmiHeader.biPlanes = 1;
573     pbmi->bmiHeader.biCompression = BI_RGB;
574     pbmi->bmiColors[0].rgbRed = 0xff;
575     pbmi->bmiColors[0].rgbGreen = 0;
576     pbmi->bmiColors[0].rgbBlue = 0;
577     pbmi->bmiColors[1].rgbRed = 0;
578     pbmi->bmiColors[1].rgbGreen = 0;
579     pbmi->bmiColors[1].rgbBlue = 0xff;
580
581     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
582     ok(hdib != NULL, "CreateDIBSection failed\n");
583     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
584     ok(dibsec.dsBmih.biClrUsed == 2,
585         "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
586
587     /* Test if the old BITMAPCOREINFO structure is supported */    
588         
589     pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
590     pbci->bmciHeader.bcBitCount = 0;
591
592     ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
593     ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
594     ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
595         && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
596     "GetDIBits did't fill in the BITMAPCOREHEADER structure properly\n");
597
598     ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
599     ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
600     ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
601         (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
602         (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
603         "The color table has not been translated to the old BITMAPCOREINFO format\n");
604
605     hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
606     ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
607
608     ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
609     ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
610     ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
611     ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
612         (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
613         (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
614         "The color table has not been translated to the old BITMAPCOREINFO format\n");
615
616     DeleteObject(hcoredib);
617
618     hdcmem = CreateCompatibleDC(hdc);
619     oldbm = SelectObject(hdcmem, hdib);
620
621     ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
622     ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
623     ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
624        "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
625        rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
626        rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
627
628     c0 = RGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen, pbmi->bmiColors[0].rgbBlue);
629     c1 = RGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen, pbmi->bmiColors[1].rgbBlue);
630
631     test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
632     test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
633     test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
634     test_color(hdcmem, PALETTEINDEX(0), c0, 1, 1);
635     test_color(hdcmem, PALETTEINDEX(1), c0, 1, 1);
636     test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
637     test_color(hdcmem, PALETTERGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen,
638         pbmi->bmiColors[0].rgbBlue), c0, 1, 1);
639     test_color(hdcmem, PALETTERGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen,
640         pbmi->bmiColors[1].rgbBlue), c1, 1, 1);
641     test_color(hdcmem, PALETTERGB(0, 0, 0), c0, 1, 1);
642     test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
643     test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1, 1, 1);
644
645     SelectObject(hdcmem, oldbm);
646     DeleteObject(hdib);
647
648     pbmi->bmiColors[0].rgbRed = 0xff;
649     pbmi->bmiColors[0].rgbGreen = 0xff;
650     pbmi->bmiColors[0].rgbBlue = 0xff;
651     pbmi->bmiColors[1].rgbRed = 0;
652     pbmi->bmiColors[1].rgbGreen = 0;
653     pbmi->bmiColors[1].rgbBlue = 0;
654
655     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
656     ok(hdib != NULL, "CreateDIBSection failed\n");
657
658     test_dib_info(hdib, bits, &pbmi->bmiHeader);
659
660     oldbm = SelectObject(hdcmem, hdib);
661
662     ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
663     ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
664     ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
665        "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
666        rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
667        rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
668
669     SelectObject(hdcmem, oldbm);
670     test_dib_info(hdib, bits, &pbmi->bmiHeader);
671     DeleteObject(hdib);
672
673     pbmi->bmiHeader.biBitCount = 4;
674     for (i = 0; i < 16; i++) {
675         pbmi->bmiColors[i].rgbRed = i;
676         pbmi->bmiColors[i].rgbGreen = 16-i;
677         pbmi->bmiColors[i].rgbBlue = 0;
678     }
679     hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
680     ok(hdib != NULL, "CreateDIBSection failed\n");
681     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
682     ok(dibsec.dsBmih.biClrUsed == 16,
683        "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
684     test_dib_info(hdib, bits, &pbmi->bmiHeader);
685     DeleteObject(hdib);
686
687     pbmi->bmiHeader.biBitCount = 8;
688
689     for (i = 0; i < 128; i++) {
690         pbmi->bmiColors[i].rgbRed = 255 - i * 2;
691         pbmi->bmiColors[i].rgbGreen = i * 2;
692         pbmi->bmiColors[i].rgbBlue = 0;
693         pbmi->bmiColors[255 - i].rgbRed = 0;
694         pbmi->bmiColors[255 - i].rgbGreen = i * 2;
695         pbmi->bmiColors[255 - i].rgbBlue = 255 - i * 2;
696     }
697     hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
698     ok(hdib != NULL, "CreateDIBSection failed\n");
699     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
700     ok(dibsec.dsBmih.biClrUsed == 256,
701         "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
702
703     oldbm = SelectObject(hdcmem, hdib);
704
705     for (i = 0; i < 256; i++) {
706         test_color(hdcmem, DIBINDEX(i), 
707             RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
708         test_color(hdcmem, PALETTERGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 
709             RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
710     }
711
712     SelectObject(hdcmem, oldbm);
713     test_dib_info(hdib, bits, &pbmi->bmiHeader);
714     DeleteObject(hdib);
715
716     pbmi->bmiHeader.biBitCount = 1;
717
718     /* Now create a palette and a palette indexed dib section */
719     memset(plogpal, 0, sizeof(logpalbuf));
720     plogpal->palVersion = 0x300;
721     plogpal->palNumEntries = 2;
722     plogpal->palPalEntry[0].peRed = 0xff;
723     plogpal->palPalEntry[0].peBlue = 0xff;
724     plogpal->palPalEntry[1].peGreen = 0xff;
725
726     index = (WORD*)pbmi->bmiColors;
727     *index++ = 0;
728     *index = 1;
729     hpal = CreatePalette(plogpal);
730     ok(hpal != NULL, "CreatePalette failed\n");
731     oldpal = SelectPalette(hdc, hpal, TRUE);
732     hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
733     ok(hdib != NULL, "CreateDIBSection failed\n");
734     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
735     ok(dibsec.dsBmih.biClrUsed == 2, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
736
737     /* The colour table has already been grabbed from the dc, so we select back the
738        old palette */
739
740     SelectPalette(hdc, oldpal, TRUE);
741     oldbm = SelectObject(hdcmem, hdib);
742     oldpal = SelectPalette(hdcmem, hpal, TRUE);
743
744     ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
745     ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
746     ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
747        rgb[1].rgbRed == 0    && rgb[1].rgbBlue == 0    && rgb[1].rgbGreen == 0xff,
748        "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
749        rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
750        rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
751
752     c0 = RGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen, plogpal->palPalEntry[0].peBlue);
753     c1 = RGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen, plogpal->palPalEntry[1].peBlue);
754
755     test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
756     test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
757     test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
758     test_color(hdcmem, PALETTEINDEX(0), c0, 0, 1);
759     test_color(hdcmem, PALETTEINDEX(1), c1, 0, 1);
760     test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
761     test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen,
762         plogpal->palPalEntry[0].peBlue), c0, 1, 1);
763     test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen,
764         plogpal->palPalEntry[1].peBlue), c1, 1, 1);
765     test_color(hdcmem, PALETTERGB(0, 0, 0), c1, 1, 1);
766     test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
767     test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0, 1, 1);
768     test_color(hdcmem, PALETTERGB(0, 1, 0), c1, 1, 1);
769     test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1, 1, 1);
770     test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0, 1, 1);
771
772     /* Bottom and 2nd row from top green, everything else magenta */
773     bits[0] = bits[1] = 0xff;
774     bits[13 * 4] = bits[13*4 + 1] = 0xff;
775
776     test_dib_info(hdib, bits, &pbmi->bmiHeader);
777
778     pbmi->bmiHeader.biBitCount = 32;
779
780     hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
781     ok(hdib2 != NULL, "CreateDIBSection failed\n");
782     hdcmem2 = CreateCompatibleDC(hdc);
783     oldbm2 = SelectObject(hdcmem2, hdib2);
784
785     BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
786
787     ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
788     ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
789
790     SelectObject(hdcmem2, oldbm2);
791     test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
792     DeleteObject(hdib2);
793
794     SelectObject(hdcmem, oldbm);
795     SelectPalette(hdcmem, oldpal, TRUE);
796     DeleteObject(hdib);
797     DeleteObject(hpal);
798
799
800     pbmi->bmiHeader.biBitCount = 8;
801
802     memset(plogpal, 0, sizeof(logpalbuf));
803     plogpal->palVersion = 0x300;
804     plogpal->palNumEntries = 256;
805
806     for (i = 0; i < 128; i++) {
807         plogpal->palPalEntry[i].peRed = 255 - i * 2;
808         plogpal->palPalEntry[i].peBlue = i * 2;
809         plogpal->palPalEntry[i].peGreen = 0;
810         plogpal->palPalEntry[255 - i].peRed = 0;
811         plogpal->palPalEntry[255 - i].peGreen = i * 2;
812         plogpal->palPalEntry[255 - i].peBlue = 255 - i * 2;
813     }
814
815     index = (WORD*)pbmi->bmiColors;
816     for (i = 0; i < 256; i++) {
817         *index++ = i;
818     }
819
820     hpal = CreatePalette(plogpal);
821     ok(hpal != NULL, "CreatePalette failed\n");
822     oldpal = SelectPalette(hdc, hpal, TRUE);
823     hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
824     ok(hdib != NULL, "CreateDIBSection failed\n");
825     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
826     ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
827
828     test_dib_info(hdib, bits, &pbmi->bmiHeader);
829
830     SelectPalette(hdc, oldpal, TRUE);
831     oldbm = SelectObject(hdcmem, hdib);
832     oldpal = SelectPalette(hdcmem, hpal, TRUE);
833
834     ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
835     ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
836     for (i = 0; i < 256; i++) {
837         ok(rgb[i].rgbRed == plogpal->palPalEntry[i].peRed && 
838             rgb[i].rgbBlue == plogpal->palPalEntry[i].peBlue && 
839             rgb[i].rgbGreen == plogpal->palPalEntry[i].peGreen, 
840             "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
841             i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
842     }
843
844     for (i = 0; i < 256; i++) {
845         test_color(hdcmem, DIBINDEX(i), 
846             RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
847         test_color(hdcmem, PALETTEINDEX(i), 
848             RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
849         test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 
850             RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
851     }
852
853     SelectPalette(hdcmem, oldpal, TRUE);
854     SelectObject(hdcmem, oldbm);
855     DeleteObject(hdib);
856     DeleteObject(hpal);
857
858     DeleteDC(hdcmem);
859     DeleteDC(hdcmem2);
860     ReleaseDC(0, hdc);
861 }
862
863 static void test_mono_dibsection(void)
864 {
865     HDC hdc, memdc;
866     HBITMAP old_bm, mono_ds;
867     char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
868     BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
869     BYTE bits[10 * 4];
870     BYTE *ds_bits;
871     int num;
872
873     hdc = GetDC(0);
874
875     memdc = CreateCompatibleDC(hdc);
876
877     memset(pbmi, 0, sizeof(bmibuf));
878     pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
879     pbmi->bmiHeader.biHeight = 10;
880     pbmi->bmiHeader.biWidth = 10;
881     pbmi->bmiHeader.biBitCount = 1;
882     pbmi->bmiHeader.biPlanes = 1;
883     pbmi->bmiHeader.biCompression = BI_RGB;
884     pbmi->bmiColors[0].rgbRed = 0xff;
885     pbmi->bmiColors[0].rgbGreen = 0xff;
886     pbmi->bmiColors[0].rgbBlue = 0xff;
887     pbmi->bmiColors[1].rgbRed = 0x0;
888     pbmi->bmiColors[1].rgbGreen = 0x0;
889     pbmi->bmiColors[1].rgbBlue = 0x0;
890
891     /*
892      * First dib section is 'inverted' ie color[0] is white, color[1] is black
893      */
894
895     mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
896     ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
897     old_bm = SelectObject(memdc, mono_ds);
898
899     /* black border, white interior */
900     Rectangle(memdc, 0, 0, 10, 10);
901     ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
902     ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
903
904     /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
905
906     memset(bits, 0, sizeof(bits));
907     bits[0] = 0xaa;
908
909     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
910     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
911
912     /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
913
914     pbmi->bmiColors[0].rgbRed = 0x0;
915     pbmi->bmiColors[0].rgbGreen = 0x0;
916     pbmi->bmiColors[0].rgbBlue = 0x0;
917     pbmi->bmiColors[1].rgbRed = 0xff;
918     pbmi->bmiColors[1].rgbGreen = 0xff;
919     pbmi->bmiColors[1].rgbBlue = 0xff;
920
921     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
922     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
923
924     SelectObject(memdc, old_bm);
925     DeleteObject(mono_ds);
926
927     /*
928      * Next dib section is 'normal' ie color[0] is black, color[1] is white
929      */
930
931     pbmi->bmiColors[0].rgbRed = 0x0;
932     pbmi->bmiColors[0].rgbGreen = 0x0;
933     pbmi->bmiColors[0].rgbBlue = 0x0;
934     pbmi->bmiColors[1].rgbRed = 0xff;
935     pbmi->bmiColors[1].rgbGreen = 0xff;
936     pbmi->bmiColors[1].rgbBlue = 0xff;
937
938     mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
939     ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
940     old_bm = SelectObject(memdc, mono_ds);
941
942     /* black border, white interior */
943     Rectangle(memdc, 0, 0, 10, 10);
944     ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
945     ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
946
947     /* SetDIBitsToDevice with a normal bmi -> normal dib section */
948
949     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
950     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
951
952     /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
953
954     pbmi->bmiColors[0].rgbRed = 0xff;
955     pbmi->bmiColors[0].rgbGreen = 0xff;
956     pbmi->bmiColors[0].rgbBlue = 0xff;
957     pbmi->bmiColors[1].rgbRed = 0x0;
958     pbmi->bmiColors[1].rgbGreen = 0x0;
959     pbmi->bmiColors[1].rgbBlue = 0x0;
960
961     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
962     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
963
964     /*
965      * Take that 'normal' dibsection and change its colour table to an 'inverted' one
966      */
967
968     pbmi->bmiColors[0].rgbRed = 0xff;
969     pbmi->bmiColors[0].rgbGreen = 0xff;
970     pbmi->bmiColors[0].rgbBlue = 0xff;
971     pbmi->bmiColors[1].rgbRed = 0x0;
972     pbmi->bmiColors[1].rgbGreen = 0x0;
973     pbmi->bmiColors[1].rgbBlue = 0x0;
974     num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors);
975     ok(num == 2, "num = %d\n", num);
976
977     /* black border, white interior */
978     Rectangle(memdc, 0, 0, 10, 10);
979     ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
980     ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
981
982     /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
983
984     memset(bits, 0, sizeof(bits));
985     bits[0] = 0xaa;
986
987     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
988     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
989
990     /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
991
992     pbmi->bmiColors[0].rgbRed = 0x0;
993     pbmi->bmiColors[0].rgbGreen = 0x0;
994     pbmi->bmiColors[0].rgbBlue = 0x0;
995     pbmi->bmiColors[1].rgbRed = 0xff;
996     pbmi->bmiColors[1].rgbGreen = 0xff;
997     pbmi->bmiColors[1].rgbBlue = 0xff;
998
999     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1000     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1001
1002     SelectObject(memdc, old_bm);
1003     DeleteObject(mono_ds);
1004
1005     /*
1006      * Now a dib section with a strange colour map just for fun.  This behaves just like an inverted one.
1007      */
1008  
1009     pbmi->bmiColors[0].rgbRed = 0xff;
1010     pbmi->bmiColors[0].rgbGreen = 0x0;
1011     pbmi->bmiColors[0].rgbBlue = 0x0;
1012     pbmi->bmiColors[1].rgbRed = 0xfe;
1013     pbmi->bmiColors[1].rgbGreen = 0x0;
1014     pbmi->bmiColors[1].rgbBlue = 0x0;
1015
1016     mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1017     ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1018     old_bm = SelectObject(memdc, mono_ds);
1019
1020     /* black border, white interior */
1021     Rectangle(memdc, 0, 0, 10, 10);
1022     ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1023     ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1024
1025     /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1026
1027     pbmi->bmiColors[0].rgbRed = 0x0;
1028     pbmi->bmiColors[0].rgbGreen = 0x0;
1029     pbmi->bmiColors[0].rgbBlue = 0x0;
1030     pbmi->bmiColors[1].rgbRed = 0xff;
1031     pbmi->bmiColors[1].rgbGreen = 0xff;
1032     pbmi->bmiColors[1].rgbBlue = 0xff;
1033
1034     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1035     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1036
1037     /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
1038
1039     pbmi->bmiColors[0].rgbRed = 0xff;
1040     pbmi->bmiColors[0].rgbGreen = 0xff;
1041     pbmi->bmiColors[0].rgbBlue = 0xff;
1042     pbmi->bmiColors[1].rgbRed = 0x0;
1043     pbmi->bmiColors[1].rgbGreen = 0x0;
1044     pbmi->bmiColors[1].rgbBlue = 0x0;
1045
1046     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1047     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1048
1049     SelectObject(memdc, old_bm);
1050     DeleteObject(mono_ds);
1051
1052     DeleteDC(memdc);
1053     ReleaseDC(0, hdc);
1054 }
1055
1056 static void test_bitmap(void)
1057 {
1058     char buf[256], buf_cmp[256];
1059     HBITMAP hbmp, hbmp_old;
1060     HDC hdc;
1061     BITMAP bm;
1062     BITMAP bma[2];
1063     INT ret;
1064
1065     hdc = CreateCompatibleDC(0);
1066     assert(hdc != 0);
1067
1068     SetLastError(0xdeadbeef);
1069     hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1070     if (!hbmp)
1071     {
1072         ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1073            GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1074            "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1075     }
1076     else
1077         DeleteObject(hbmp);
1078
1079     SetLastError(0xdeadbeef);
1080     hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1081     if (!hbmp)
1082     {
1083         ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1084            GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1085            "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1086     }
1087     else
1088         DeleteObject(hbmp);
1089
1090     SetLastError(0xdeadbeef);
1091     hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1092     ok(!hbmp, "CreateBitmap should fail\n");
1093     if (!hbmp)
1094         ok(GetLastError() == ERROR_INVALID_PARAMETER,
1095            "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1096     else
1097         DeleteObject(hbmp);
1098
1099     hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1100     assert(hbmp != NULL);
1101
1102     ret = GetObject(hbmp, sizeof(bm), &bm);
1103     ok(ret == sizeof(bm), "wrong size %d\n", ret);
1104
1105     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1106     ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1107     ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1108     ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1109     ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1110     ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1111     ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1112
1113     assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1114     assert(sizeof(buf) == sizeof(buf_cmp));
1115
1116     ret = GetBitmapBits(hbmp, 0, NULL);
1117     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1118
1119     memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1120     memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1121
1122     memset(buf, 0xAA, sizeof(buf));
1123     ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1124     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1125     ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1126
1127     hbmp_old = SelectObject(hdc, hbmp);
1128
1129     ret = GetObject(hbmp, sizeof(bm), &bm);
1130     ok(ret == sizeof(bm), "wrong size %d\n", ret);
1131
1132     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1133     ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1134     ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1135     ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1136     ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1137     ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1138     ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1139
1140     memset(buf, 0xAA, sizeof(buf));
1141     ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1142     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1143     ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1144
1145     hbmp_old = SelectObject(hdc, hbmp_old);
1146     ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1147
1148     /* test various buffer sizes for GetObject */
1149     ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
1150     ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1151
1152     ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1153     ok(ret == 0, "%d != 0\n", ret);
1154
1155     ret = GetObject(hbmp, 0, &bm);
1156     ok(ret == 0, "%d != 0\n", ret);
1157
1158     ret = GetObject(hbmp, 1, &bm);
1159     ok(ret == 0, "%d != 0\n", ret);
1160
1161     DeleteObject(hbmp);
1162     DeleteDC(hdc);
1163 }
1164
1165 static void test_bmBits(void)
1166 {
1167     BYTE bits[4];
1168     HBITMAP hbmp;
1169     BITMAP bmp;
1170
1171     memset(bits, 0, sizeof(bits));
1172     hbmp = CreateBitmap(2, 2, 1, 4, bits);
1173     ok(hbmp != NULL, "CreateBitmap failed\n");
1174
1175     memset(&bmp, 0xFF, sizeof(bmp));
1176     ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1177        "GetObject failed or returned a wrong structure size\n");
1178     ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1179
1180     DeleteObject(hbmp);
1181 }
1182
1183 static void test_GetDIBits_selected_DIB(UINT bpp)
1184 {
1185     HBITMAP dib;
1186     BITMAPINFO * info;
1187     BITMAPINFO * info2;
1188     void * bits;
1189     void * bits2;
1190     UINT dib_size, dib32_size;
1191     DWORD pixel;
1192     HDC dib_dc, dc;
1193     HBITMAP old_bmp;
1194     BOOL equalContents;
1195     UINT i;
1196     int res;
1197
1198     /* Create a DIB section with a color table */
1199
1200     info  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD));
1201     info2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD));
1202     assert(info);
1203     assert(info2);
1204
1205     info->bmiHeader.biSize = sizeof(info->bmiHeader);
1206
1207     /* Choose width and height such that the row length (in bytes)
1208        is a multiple of 4 (makes things easier) */
1209     info->bmiHeader.biWidth = 32;
1210     info->bmiHeader.biHeight = 32;
1211     info->bmiHeader.biPlanes = 1;
1212     info->bmiHeader.biBitCount = bpp;
1213     info->bmiHeader.biCompression = BI_RGB;
1214
1215     for (i=0; i < (1u << bpp); i++)
1216     {
1217         BYTE c = i * (1 << (8 - bpp));
1218         info->bmiColors[i].rgbRed = c;
1219         info->bmiColors[i].rgbGreen = c;
1220         info->bmiColors[i].rgbBlue = c;
1221         info->bmiColors[i].rgbReserved = 0;
1222     }
1223
1224     dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1225     assert(dib);
1226     dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1227     dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1228
1229     /* Set the bits of the DIB section */
1230     for (i=0; i < dib_size; i++)
1231     {
1232         ((BYTE *)bits)[i] = i % 256;
1233     }
1234
1235     /* Select the DIB into a DC */
1236     dib_dc = CreateCompatibleDC(NULL);
1237     old_bmp = SelectObject(dib_dc, dib);
1238     dc = CreateCompatibleDC(NULL);
1239     bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
1240     assert(bits2);
1241
1242     /* Copy the DIB attributes but not the color table */
1243     memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1244
1245     res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1246     ok(res, "GetDIBits failed\n");
1247
1248     /* Compare the color table and the bits */
1249     equalContents = TRUE;
1250     for (i=0; i < (1u << bpp); i++)
1251     {
1252         if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed)
1253             || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen)
1254             || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue)
1255             || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved))
1256         {
1257             equalContents = FALSE;
1258             break;
1259         }
1260     }
1261     ok(equalContents, "GetDIBits with DIB selected in DC: Invalid DIB color table\n");
1262
1263     equalContents = TRUE;
1264     for (i=0; i < dib_size / sizeof(DWORD); i++)
1265     {
1266         if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i])
1267         {
1268             equalContents = FALSE;
1269             break;
1270         }
1271     }
1272     ok(equalContents, "GetDIBits with %d bpp DIB selected in DC: Invalid DIB bits\n",bpp);
1273
1274     /* Map into a 32bit-DIB */
1275     info2->bmiHeader.biBitCount = 32;
1276     res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1277     ok(res, "GetDIBits failed\n");
1278
1279     /* Check if last pixel was set */
1280     pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
1281     ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
1282
1283     HeapFree(GetProcessHeap(), 0, bits2);
1284     DeleteDC(dc);
1285
1286     SelectObject(dib_dc, old_bmp);
1287     DeleteDC(dib_dc);
1288     DeleteObject(dib);
1289
1290     HeapFree(GetProcessHeap(), 0, info2);
1291     HeapFree(GetProcessHeap(), 0, info);
1292 }
1293
1294 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1295 {
1296     HBITMAP ddb;
1297     BITMAPINFO * info;
1298     BITMAPINFO * info2;
1299     void * bits;
1300     void * bits2;
1301     HDC ddb_dc, dc;
1302     HBITMAP old_bmp;
1303     BOOL equalContents;
1304     UINT width, height;
1305     UINT bpp;
1306     UINT i, j;
1307     int res;
1308
1309     width = height = 16;
1310
1311     /* Create a DDB (device-dependent bitmap) */
1312     if (monochrome)
1313     {
1314         bpp = 1;
1315         ddb = CreateBitmap(width, height, 1, 1, NULL);
1316     }
1317     else
1318     {
1319         HDC screen_dc = GetDC(NULL);
1320         bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1321         ddb = CreateCompatibleBitmap(screen_dc, width, height);
1322         ReleaseDC(NULL, screen_dc);
1323     }
1324
1325     /* Set the pixels */
1326     ddb_dc = CreateCompatibleDC(NULL);
1327     old_bmp = SelectObject(ddb_dc, ddb);
1328     for (i = 0; i < width; i++)
1329     {
1330         for (j=0; j < height; j++)
1331         {
1332             BYTE c = (i * width + j) % 256;
1333             SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1334         }
1335     }
1336     SelectObject(ddb_dc, old_bmp);
1337
1338     info  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1339     info2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1340     assert(info);
1341     assert(info2);
1342
1343     info->bmiHeader.biSize = sizeof(info->bmiHeader);
1344     info->bmiHeader.biWidth = width;
1345     info->bmiHeader.biHeight = height;
1346     info->bmiHeader.biPlanes = 1;
1347     info->bmiHeader.biBitCount = bpp;
1348     info->bmiHeader.biCompression = BI_RGB;
1349
1350     dc = CreateCompatibleDC(NULL);
1351
1352     /* Fill in biSizeImage */
1353     GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1354     ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1355
1356     bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1357     bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1358     assert(bits);
1359     assert(bits2);
1360
1361     /* Get the bits */
1362     res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1363     ok(res, "GetDIBits failed\n");
1364
1365     /* Copy the DIB attributes but not the color table */
1366     memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1367
1368     /* Select the DDB into another DC */
1369     old_bmp = SelectObject(ddb_dc, ddb);
1370
1371     /* Get the bits */
1372     res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1373     ok(res, "GetDIBits failed\n");
1374
1375     /* Compare the color table and the bits */
1376     if (bpp <= 8)
1377     {
1378         equalContents = TRUE;
1379         for (i=0; i < (1u << bpp); i++)
1380         {
1381             if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed)
1382                 || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen)
1383                 || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue)
1384                 || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved))
1385             {
1386                 equalContents = FALSE;
1387                 break;
1388             }
1389         }
1390         ok(equalContents, "GetDIBits with DDB selected in DC: Got a different color table\n");
1391     }
1392
1393     equalContents = TRUE;
1394     for (i=0; i < info->bmiHeader.biSizeImage / sizeof(DWORD); i++)
1395     {
1396         if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i])
1397         {
1398             equalContents = FALSE;
1399         }
1400     }
1401     ok(equalContents, "GetDIBits with DDB selected in DC: Got different DIB bits\n");
1402
1403     /* Test the palette */
1404     equalContents = TRUE;
1405     if (info2->bmiHeader.biBitCount <= 8)
1406     {
1407         WORD *colors = (WORD*)info2->bmiColors;
1408
1409         /* Get the palette indices */
1410         res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1411         ok(res, "GetDIBits failed\n");
1412
1413         for (i=0;i < 1 << info->bmiHeader.biSizeImage; i++)
1414         {
1415             if (colors[i] != i)
1416             {
1417                 equalContents = FALSE;
1418                 break;
1419             }
1420         }
1421     }
1422
1423     ok(equalContents, "GetDIBits with DDB selected in DC: non 1:1 palette indices\n");
1424
1425     HeapFree(GetProcessHeap(), 0, bits2);
1426     HeapFree(GetProcessHeap(), 0, bits);
1427     DeleteDC(dc);
1428
1429     SelectObject(ddb_dc, old_bmp);
1430     DeleteDC(ddb_dc);
1431     DeleteObject(ddb);
1432
1433     HeapFree(GetProcessHeap(), 0, info2);
1434     HeapFree(GetProcessHeap(), 0, info);
1435 }
1436
1437 static void test_GetDIBits(void)
1438 {
1439     /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1440     static const BYTE bmp_bits_1[16 * 2] =
1441     {
1442         0xff,0xff, 0,0, 0xff,0xff, 0,0,
1443         0xff,0xff, 0,0, 0xff,0xff, 0,0,
1444         0xff,0xff, 0,0, 0xff,0xff, 0,0,
1445         0xff,0xff, 0,0, 0xff,0xff, 0,0
1446     };
1447     /* 4-bytes aligned 1-bit DIB data: 16x16 */
1448     static const BYTE dib_bits_1[16 * 4] =
1449     {
1450         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1451         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1452         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1453         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1454     };
1455     /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1456     static const BYTE bmp_bits_24[16 * 16*3] =
1457     {
1458         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1459         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1460         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1461         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1462         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1463         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1464         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1465         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1466         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1467         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1468         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1469         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1470         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1471         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1472         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1473         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1474         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1475         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1476         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1477         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1478         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1479         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1480         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     };
1491     /* 4-bytes aligned 24-bit DIB data: 16x16 */
1492     static const BYTE dib_bits_24[16 * 16*3] =
1493     {
1494         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1495         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1496         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1497         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1498         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1499         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1500         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1501         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1502         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1503         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1504         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1505         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1506         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1507         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1508         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1509         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1510         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1511         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1512         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1513         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1514         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1515         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1516         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1517         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1518         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1519         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1520         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1521         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1522         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1523         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1524         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1525         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1526     };
1527     HBITMAP hbmp;
1528     BITMAP bm;
1529     HDC hdc;
1530     int i, bytes, lines;
1531     BYTE buf[1024];
1532     char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1533     BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1534
1535     hdc = GetDC(0);
1536
1537     /* 1-bit source bitmap data */
1538     hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1539     ok(hbmp != 0, "CreateBitmap failed\n");
1540
1541     memset(&bm, 0xAA, sizeof(bm));
1542     bytes = GetObject(hbmp, sizeof(bm), &bm);
1543     ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1544     ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1545     ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1546     ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1547     ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1548     ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1549     ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1550     ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1551
1552     bytes = GetBitmapBits(hbmp, 0, NULL);
1553     ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1554     bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1555     ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1556     ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1557
1558     /* retrieve 1-bit DIB data */
1559     memset(bi, 0, sizeof(*bi));
1560     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1561     bi->bmiHeader.biWidth = bm.bmWidth;
1562     bi->bmiHeader.biHeight = bm.bmHeight;
1563     bi->bmiHeader.biPlanes = 1;
1564     bi->bmiHeader.biBitCount = 1;
1565     bi->bmiHeader.biCompression = BI_RGB;
1566     bi->bmiHeader.biSizeImage = 0;
1567     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1568     SetLastError(0xdeadbeef);
1569     lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1570     ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1571     ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1572        broken(GetLastError() == 0xdeadbeef), /* winnt */
1573        "wrong error %u\n", GetLastError());
1574     ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1575
1576     memset(buf, 0xAA, sizeof(buf));
1577     SetLastError(0xdeadbeef);
1578     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1579     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1580        lines, bm.bmHeight, GetLastError());
1581     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1582
1583     /* the color table consists of black and white */
1584     ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1585        bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1586        "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1587        bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1588        bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1589     ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1590        bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1591        "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1592        bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1593        bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1594     for (i = 2; i < 256; i++)
1595     {
1596         ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1597            bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1598            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1599            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1600            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1601     }
1602
1603     /* returned bits are DWORD aligned and upside down */
1604     ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1605
1606     /* Test the palette indices */
1607     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1608     SetLastError(0xdeadbeef);
1609     lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1610     ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1611     ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1612     for (i = 2; i < 256; i++)
1613         ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[1]);
1614
1615     /* retrieve 24-bit DIB data */
1616     memset(bi, 0, sizeof(*bi));
1617     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1618     bi->bmiHeader.biWidth = bm.bmWidth;
1619     bi->bmiHeader.biHeight = bm.bmHeight;
1620     bi->bmiHeader.biPlanes = 1;
1621     bi->bmiHeader.biBitCount = 24;
1622     bi->bmiHeader.biCompression = BI_RGB;
1623     bi->bmiHeader.biSizeImage = 0;
1624     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1625     memset(buf, 0xAA, sizeof(buf));
1626     SetLastError(0xdeadbeef);
1627     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1628     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1629        lines, bm.bmHeight, GetLastError());
1630     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1631
1632     /* the color table doesn't exist for 24-bit images */
1633     for (i = 0; i < 256; i++)
1634     {
1635         ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1636            bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1637            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1638            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1639            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1640     }
1641
1642     /* returned bits are DWORD aligned and upside down */
1643     ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1644     DeleteObject(hbmp);
1645
1646     /* 24-bit source bitmap data */
1647     hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1648     ok(hbmp != 0, "CreateBitmap failed\n");
1649     SetLastError(0xdeadbeef);
1650     bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1651     lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1652     ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1653        lines, bm.bmHeight, GetLastError());
1654
1655     memset(&bm, 0xAA, sizeof(bm));
1656     bytes = GetObject(hbmp, sizeof(bm), &bm);
1657     ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1658     ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1659     ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1660     ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1661     ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1662     ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1663     ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1664     ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1665
1666     bytes = GetBitmapBits(hbmp, 0, NULL);
1667     ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
1668     bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1669     ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1670        bm.bmWidthBytes * bm.bmHeight, bytes);
1671
1672     /* retrieve 1-bit DIB data */
1673     memset(bi, 0, sizeof(*bi));
1674     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1675     bi->bmiHeader.biWidth = bm.bmWidth;
1676     bi->bmiHeader.biHeight = bm.bmHeight;
1677     bi->bmiHeader.biPlanes = 1;
1678     bi->bmiHeader.biBitCount = 1;
1679     bi->bmiHeader.biCompression = BI_RGB;
1680     bi->bmiHeader.biSizeImage = 0;
1681     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1682     memset(buf, 0xAA, sizeof(buf));
1683     SetLastError(0xdeadbeef);
1684     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1685     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1686        lines, bm.bmHeight, GetLastError());
1687     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1688
1689     /* the color table consists of black and white */
1690     ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1691        bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1692        "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1693        bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1694        bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1695     ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1696        bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1697        "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1698        bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1699        bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1700     for (i = 2; i < 256; i++)
1701     {
1702         ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1703            bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1704            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1705            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1706            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1707     }
1708
1709     /* returned bits are DWORD aligned and upside down */
1710 todo_wine
1711     ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1712
1713     /* Test the palette indices */
1714     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1715     SetLastError(0xdeadbeef);
1716     lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1717     ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1718     ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1719     for (i = 2; i < 256; i++)
1720         ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[i]);
1721
1722     /* retrieve 24-bit DIB data */
1723     memset(bi, 0, sizeof(*bi));
1724     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1725     bi->bmiHeader.biWidth = bm.bmWidth;
1726     bi->bmiHeader.biHeight = bm.bmHeight;
1727     bi->bmiHeader.biPlanes = 1;
1728     bi->bmiHeader.biBitCount = 24;
1729     bi->bmiHeader.biCompression = BI_RGB;
1730     bi->bmiHeader.biSizeImage = 0;
1731     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1732     memset(buf, 0xAA, sizeof(buf));
1733     SetLastError(0xdeadbeef);
1734     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1735     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1736        lines, bm.bmHeight, GetLastError());
1737     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1738
1739     /* the color table doesn't exist for 24-bit images */
1740     for (i = 0; i < 256; i++)
1741     {
1742         ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1743            bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1744            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1745            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1746            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1747     }
1748
1749     /* returned bits are DWORD aligned and upside down */
1750     ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1751     DeleteObject(hbmp);
1752
1753     ReleaseDC(0, hdc);
1754 }
1755
1756 static void test_GetDIBits_BI_BITFIELDS(void)
1757 {
1758     /* Try a screen resolution detection technique
1759      * from the September 1999 issue of Windows Developer's Journal
1760      * which seems to be in widespread use.
1761      * http://www.lesher.ws/highcolor.html
1762      * http://www.lesher.ws/vidfmt.c
1763      * It hinges on being able to retrieve the bitmaps
1764      * for the three primary colors in non-paletted 16 bit mode.
1765      */
1766     char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
1767     DWORD bits[32];
1768     LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
1769     DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
1770     HDC hdc;
1771     HBITMAP hbm;
1772     int ret;
1773     void *ptr;
1774
1775     memset(dibinfo, 0, sizeof(dibinfo_buf));
1776     dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1777
1778     hdc = GetDC(NULL);
1779     ok(hdc != NULL, "GetDC failed?\n");
1780     hbm = CreateCompatibleBitmap(hdc, 1, 1);
1781     ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
1782
1783     /* Call GetDIBits to fill in bmiHeader.  */
1784     ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1785     ok(ret == 1, "GetDIBits failed\n");
1786     if (dibinfo->bmiHeader.biBitCount > 8)
1787     {
1788         ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
1789             "compression is %u\n", dibinfo->bmiHeader.biCompression );
1790
1791         ok( !bitmasks[0], "red mask is set\n" );
1792         ok( !bitmasks[1], "green mask is set\n" );
1793         ok( !bitmasks[2], "blue mask is set\n" );
1794
1795         /* test with NULL bits pointer and correct bpp */
1796         dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1797         ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1798         ok(ret == 1, "GetDIBits failed\n");
1799
1800         ok( bitmasks[0] != 0, "red mask is not set\n" );
1801         ok( bitmasks[1] != 0, "green mask is not set\n" );
1802         ok( bitmasks[2] != 0, "blue mask is not set\n" );
1803         ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1804
1805         /* test with valid bits pointer */
1806         memset(dibinfo, 0, sizeof(dibinfo_buf));
1807         dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1808         ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1809         ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1810         dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1811         ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
1812         ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1813
1814         ok( bitmasks[0] != 0, "red mask is not set\n" );
1815         ok( bitmasks[1] != 0, "green mask is not set\n" );
1816         ok( bitmasks[2] != 0, "blue mask is not set\n" );
1817         ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1818
1819         /* now with bits and 0 lines */
1820         memset(dibinfo, 0, sizeof(dibinfo_buf));
1821         dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1822         dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1823         SetLastError(0xdeadbeef);
1824         ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
1825         ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1826
1827         ok( !bitmasks[0], "red mask is set\n" );
1828         ok( !bitmasks[1], "green mask is set\n" );
1829         ok( !bitmasks[2], "blue mask is set\n" );
1830         ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1831
1832         memset(bitmasks, 0, 3*sizeof(DWORD));
1833         dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1834         ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
1835         ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1836
1837         ok( bitmasks[0] != 0, "red mask is not set\n" );
1838         ok( bitmasks[1] != 0, "green mask is not set\n" );
1839         ok( bitmasks[2] != 0, "blue mask is not set\n" );
1840         ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1841     }
1842     else skip("not in 16 bpp BI_BITFIELDS mode, skipping that test\n");
1843
1844     DeleteObject(hbm);
1845
1846     /* same thing now with a 32-bpp DIB section */
1847
1848     dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1849     dibinfo->bmiHeader.biWidth = 1;
1850     dibinfo->bmiHeader.biHeight = 1;
1851     dibinfo->bmiHeader.biPlanes = 1;
1852     dibinfo->bmiHeader.biBitCount = 32;
1853     dibinfo->bmiHeader.biCompression = BI_RGB;
1854     dibinfo->bmiHeader.biSizeImage = 0;
1855     dibinfo->bmiHeader.biXPelsPerMeter = 0;
1856     dibinfo->bmiHeader.biYPelsPerMeter = 0;
1857     dibinfo->bmiHeader.biClrUsed = 0;
1858     dibinfo->bmiHeader.biClrImportant = 0;
1859     bitmasks[0] = 0x0000ff;
1860     bitmasks[1] = 0x00ff00;
1861     bitmasks[2] = 0xff0000;
1862     hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
1863     ok( hbm != 0, "failed to create bitmap\n" );
1864
1865     memset(dibinfo, 0, sizeof(dibinfo_buf));
1866     dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1867     ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
1868     ok(ret == 1, "GetDIBits failed\n");
1869     ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
1870
1871     ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
1872         "compression is %u\n", dibinfo->bmiHeader.biCompression );
1873     ok( !bitmasks[0], "red mask is set\n" );
1874     ok( !bitmasks[1], "green mask is set\n" );
1875     ok( !bitmasks[2], "blue mask is set\n" );
1876
1877     dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1878     ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
1879     ok(ret == 1, "GetDIBits failed\n");
1880     ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
1881     ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
1882     ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
1883     ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
1884     ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1885
1886     DeleteObject(hbm);
1887
1888     dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1889     dibinfo->bmiHeader.biWidth = 1;
1890     dibinfo->bmiHeader.biHeight = 1;
1891     dibinfo->bmiHeader.biPlanes = 1;
1892     dibinfo->bmiHeader.biBitCount = 32;
1893     dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
1894     dibinfo->bmiHeader.biSizeImage = 0;
1895     dibinfo->bmiHeader.biXPelsPerMeter = 0;
1896     dibinfo->bmiHeader.biYPelsPerMeter = 0;
1897     dibinfo->bmiHeader.biClrUsed = 0;
1898     dibinfo->bmiHeader.biClrImportant = 0;
1899     bitmasks[0] = 0x0000ff;
1900     bitmasks[1] = 0x00ff00;
1901     bitmasks[2] = 0xff0000;
1902     hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
1903     ok( hbm != 0, "failed to create bitmap\n" );
1904
1905     if (hbm)
1906     {
1907         memset(dibinfo, 0, sizeof(dibinfo_buf));
1908         dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1909         ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
1910         ok(ret == 1, "GetDIBits failed\n");
1911
1912         ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
1913             "compression is %u\n", dibinfo->bmiHeader.biCompression );
1914         ok( !bitmasks[0], "red mask is set\n" );
1915         ok( !bitmasks[1], "green mask is set\n" );
1916         ok( !bitmasks[2], "blue mask is set\n" );
1917
1918         dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1919         ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
1920         ok(ret == 1, "GetDIBits failed\n");
1921         ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
1922         ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
1923         ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
1924         ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1925
1926         DeleteObject(hbm);
1927     }
1928
1929     /* 24-bpp DIB sections don't have bitfields */
1930
1931     dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1932     dibinfo->bmiHeader.biWidth = 1;
1933     dibinfo->bmiHeader.biHeight = 1;
1934     dibinfo->bmiHeader.biPlanes = 1;
1935     dibinfo->bmiHeader.biBitCount = 24;
1936     dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
1937     dibinfo->bmiHeader.biSizeImage = 0;
1938     dibinfo->bmiHeader.biXPelsPerMeter = 0;
1939     dibinfo->bmiHeader.biYPelsPerMeter = 0;
1940     dibinfo->bmiHeader.biClrUsed = 0;
1941     dibinfo->bmiHeader.biClrImportant = 0;
1942     hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
1943     ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
1944     dibinfo->bmiHeader.biCompression = BI_RGB;
1945     hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
1946     ok( hbm != 0, "failed to create bitmap\n" );
1947
1948     memset(dibinfo, 0, sizeof(dibinfo_buf));
1949     dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1950     ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
1951     ok(ret == 1, "GetDIBits failed\n");
1952     ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
1953
1954     ok( dibinfo->bmiHeader.biCompression == BI_RGB,
1955         "compression is %u\n", dibinfo->bmiHeader.biCompression );
1956     ok( !bitmasks[0], "red mask is set\n" );
1957     ok( !bitmasks[1], "green mask is set\n" );
1958     ok( !bitmasks[2], "blue mask is set\n" );
1959
1960     dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1961     ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
1962     ok(ret == 1, "GetDIBits failed\n");
1963     ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
1964     ok( !bitmasks[0], "red mask is set\n" );
1965     ok( !bitmasks[1], "green mask is set\n" );
1966     ok( !bitmasks[2], "blue mask is set\n" );
1967     ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1968
1969     DeleteObject(hbm);
1970     ReleaseDC(NULL, hdc);
1971 }
1972
1973 static void test_select_object(void)
1974 {
1975     HDC hdc;
1976     HBITMAP hbm, hbm_old;
1977     INT planes, bpp, i;
1978     DWORD depths[] = {8, 15, 16, 24, 32};
1979     BITMAP bm;
1980     DWORD bytes;
1981
1982     hdc = GetDC(0);
1983     ok(hdc != 0, "GetDC(0) failed\n");
1984     hbm = CreateCompatibleBitmap(hdc, 10, 10);
1985     ok(hbm != 0, "CreateCompatibleBitmap failed\n");
1986
1987     hbm_old = SelectObject(hdc, hbm);
1988     ok(hbm_old == 0, "SelectObject should fail\n");
1989
1990     DeleteObject(hbm);
1991     ReleaseDC(0, hdc);
1992
1993     hdc = CreateCompatibleDC(0);
1994     ok(hdc != 0, "GetDC(0) failed\n");
1995     hbm = CreateCompatibleBitmap(hdc, 10, 10);
1996     ok(hbm != 0, "CreateCompatibleBitmap failed\n");
1997
1998     hbm_old = SelectObject(hdc, hbm);
1999     ok(hbm_old != 0, "SelectObject failed\n");
2000     hbm_old = SelectObject(hdc, hbm_old);
2001     ok(hbm_old == hbm, "SelectObject failed\n");
2002
2003     DeleteObject(hbm);
2004
2005     /* test an 1-bpp bitmap */
2006     planes = GetDeviceCaps(hdc, PLANES);
2007     bpp = 1;
2008
2009     hbm = CreateBitmap(10, 10, planes, bpp, NULL);
2010     ok(hbm != 0, "CreateBitmap failed\n");
2011
2012     hbm_old = SelectObject(hdc, hbm);
2013     ok(hbm_old != 0, "SelectObject failed\n");
2014     hbm_old = SelectObject(hdc, hbm_old);
2015     ok(hbm_old == hbm, "SelectObject failed\n");
2016
2017     DeleteObject(hbm);
2018
2019     for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
2020         /* test a color bitmap to dc bpp matching */
2021         planes = GetDeviceCaps(hdc, PLANES);
2022         bpp = GetDeviceCaps(hdc, BITSPIXEL);
2023
2024         hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
2025         ok(hbm != 0, "CreateBitmap failed\n");
2026
2027         hbm_old = SelectObject(hdc, hbm);
2028         if(depths[i] == bpp ||
2029           (bpp == 16 && depths[i] == 15)        /* 16 and 15 bpp are compatible */
2030           ) {
2031             ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
2032             SelectObject(hdc, hbm_old);
2033         } else {
2034             ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
2035         }
2036
2037         memset(&bm, 0xAA, sizeof(bm));
2038         bytes = GetObject(hbm, sizeof(bm), &bm);
2039         ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2040         ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2041         ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
2042         ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
2043         ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2044         ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
2045         if(depths[i] == 15) {
2046             ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
2047         } else {
2048             ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2049         }
2050         ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2051
2052         DeleteObject(hbm);
2053     }
2054
2055     DeleteDC(hdc);
2056 }
2057
2058 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
2059 {
2060     INT ret;
2061     BITMAP bm;
2062
2063     ret = GetObjectType(hbmp);
2064     ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
2065
2066     ret = GetObject(hbmp, 0, 0);
2067     ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
2068
2069     memset(&bm, 0xDA, sizeof(bm));
2070     SetLastError(0xdeadbeef);
2071     ret = GetObject(hbmp, sizeof(bm), &bm);
2072     if (!ret) /* XP, only for curObj2 */ return;
2073     ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
2074     ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2075     ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2076     ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2077     ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2078     ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2079     ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2080     ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2081 }
2082
2083 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2084
2085 static void test_CreateBitmap(void)
2086 {
2087     BITMAP bmp;
2088     HDC screenDC = GetDC(0);
2089     HDC hdc = CreateCompatibleDC(screenDC);
2090     UINT i, expect = 0;
2091
2092     /* all of these are the stock monochrome bitmap */
2093     HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2094     HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2095     HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2096     HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2097     HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2098     HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2099
2100     /* these 2 are not the stock monochrome bitmap */
2101     HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2102     HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2103
2104     HBITMAP old1 = SelectObject(hdc, bm2);
2105     HBITMAP old2 = SelectObject(screenDC, bm3);
2106     SelectObject(hdc, old1);
2107     SelectObject(screenDC, old2);
2108
2109     ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2110        "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2111        bm, bm1, bm4, bm5, curObj1, old1);
2112     ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2113 todo_wine
2114     ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
2115     ok(old2 == 0, "old2 %p\n", old2);
2116
2117     test_mono_1x1_bmp(bm);
2118     test_mono_1x1_bmp(bm1);
2119     test_mono_1x1_bmp(bm2);
2120     test_mono_1x1_bmp(bm3);
2121     test_mono_1x1_bmp(bm4);
2122     test_mono_1x1_bmp(bm5);
2123     test_mono_1x1_bmp(old1);
2124     test_mono_1x1_bmp(curObj1);
2125
2126     DeleteObject(bm);
2127     DeleteObject(bm1);
2128     DeleteObject(bm2);
2129     DeleteObject(bm3);
2130     DeleteObject(bm4);
2131     DeleteObject(bm5);
2132
2133     DeleteDC(hdc);
2134     ReleaseDC(0, screenDC);
2135
2136     /* show that Windows ignores the provided bm.bmWidthBytes */
2137     bmp.bmType = 0;
2138     bmp.bmWidth = 1;
2139     bmp.bmHeight = 1;
2140     bmp.bmWidthBytes = 28;
2141     bmp.bmPlanes = 1;
2142     bmp.bmBitsPixel = 1;
2143     bmp.bmBits = NULL;
2144     bm = CreateBitmapIndirect(&bmp);
2145     ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2146     test_mono_1x1_bmp(bm);
2147     DeleteObject(bm);
2148
2149     /* Test how the bmBitsPixel field is treated */
2150     for(i = 1; i <= 33; i++) {
2151         bmp.bmType = 0;
2152         bmp.bmWidth = 1;
2153         bmp.bmHeight = 1;
2154         bmp.bmWidthBytes = 28;
2155         bmp.bmPlanes = 1;
2156         bmp.bmBitsPixel = i;
2157         bmp.bmBits = NULL;
2158         SetLastError(0xdeadbeef);
2159         bm = CreateBitmapIndirect(&bmp);
2160         if(i > 32) {
2161             DWORD error = GetLastError();
2162             ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
2163             ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2164             DeleteObject(bm);
2165             continue;
2166         }
2167         ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2168         GetObject(bm, sizeof(bmp), &bmp);
2169         if(i == 1) {
2170             expect = 1;
2171         } else if(i <= 4) {
2172             expect = 4;
2173         } else if(i <= 8) {
2174             expect = 8;
2175         } else if(i <= 16) {
2176             expect = 16;
2177         } else if(i <= 24) {
2178             expect = 24;
2179         } else if(i <= 32) {
2180             expect = 32;
2181         }
2182         ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2183            i, bmp.bmBitsPixel, expect);
2184         DeleteObject(bm);
2185     }
2186 }
2187
2188 static void test_bitmapinfoheadersize(void)
2189 {
2190     HBITMAP hdib;
2191     BITMAPINFO bmi;
2192     BITMAPCOREINFO bci;
2193     HDC hdc = GetDC(0);
2194
2195     memset(&bmi, 0, sizeof(BITMAPINFO));
2196     bmi.bmiHeader.biHeight = 100;
2197     bmi.bmiHeader.biWidth = 512;
2198     bmi.bmiHeader.biBitCount = 24;
2199     bmi.bmiHeader.biPlanes = 1;
2200
2201     bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2202
2203     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2204     ok(hdib == NULL, "CreateDIBSection succeeded\n");
2205
2206     bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2207
2208     SetLastError(0xdeadbeef);
2209     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2210     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2211     DeleteObject(hdib);
2212
2213     bmi.bmiHeader.biSize++;
2214
2215     SetLastError(0xdeadbeef);
2216     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2217     ok(hdib != NULL ||
2218        broken(!hdib), /* Win98, WinMe */
2219        "CreateDIBSection error %d\n", GetLastError());
2220     DeleteObject(hdib);
2221
2222     bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2223
2224     SetLastError(0xdeadbeef);
2225     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2226     ok(hdib != NULL ||
2227        broken(!hdib), /* Win98, WinMe */
2228        "CreateDIBSection error %d\n", GetLastError());
2229     DeleteObject(hdib);
2230
2231     bmi.bmiHeader.biSize++;
2232
2233     SetLastError(0xdeadbeef);
2234     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2235     ok(hdib != NULL ||
2236        broken(!hdib), /* Win98, WinMe */
2237        "CreateDIBSection error %d\n", GetLastError());
2238     DeleteObject(hdib);
2239
2240     bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2241
2242     SetLastError(0xdeadbeef);
2243     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2244     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2245     DeleteObject(hdib);
2246
2247     bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2248
2249     SetLastError(0xdeadbeef);
2250     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2251     ok(hdib != NULL ||
2252        broken(!hdib), /* Win95 */
2253        "CreateDIBSection error %d\n", GetLastError());
2254     DeleteObject(hdib);
2255
2256     memset(&bci, 0, sizeof(BITMAPCOREINFO));
2257     bci.bmciHeader.bcHeight = 100;
2258     bci.bmciHeader.bcWidth = 512;
2259     bci.bmciHeader.bcBitCount = 24;
2260     bci.bmciHeader.bcPlanes = 1;
2261
2262     bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2263
2264     hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2265     ok(hdib == NULL, "CreateDIBSection succeeded\n");
2266
2267     bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2268
2269     SetLastError(0xdeadbeef);
2270     hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2271     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2272     DeleteObject(hdib);
2273
2274     bci.bmciHeader.bcSize++;
2275
2276     hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2277     ok(hdib == NULL, "CreateDIBSection succeeded\n");
2278
2279     bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2280
2281     hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2282     ok(hdib == NULL, "CreateDIBSection succeeded\n");
2283
2284     ReleaseDC(0, hdc);
2285 }
2286
2287 static void test_get16dibits(void)
2288 {
2289     BYTE bits[4 * (16 / sizeof(BYTE))];
2290     HBITMAP hbmp;
2291     HDC screen_dc = GetDC(NULL);
2292     int ret;
2293     BITMAPINFO * info;
2294     int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2295     BYTE *p;
2296     int overwritten_bytes = 0;
2297
2298     memset(bits, 0, sizeof(bits));
2299     hbmp = CreateBitmap(2, 2, 1, 16, bits);
2300     ok(hbmp != NULL, "CreateBitmap failed\n");
2301
2302     info  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2303     assert(info);
2304
2305     memset(info, '!', info_len);
2306     memset(info, 0, sizeof(info->bmiHeader));
2307
2308     info->bmiHeader.biSize = sizeof(info->bmiHeader);
2309     info->bmiHeader.biWidth = 2;
2310     info->bmiHeader.biHeight = 2;
2311     info->bmiHeader.biPlanes = 1;
2312     info->bmiHeader.biCompression = BI_RGB;
2313
2314     ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2315     ok(ret != 0, "GetDIBits failed got %d\n", ret);
2316
2317     for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2318         if (*p != '!')
2319             overwritten_bytes++;
2320     ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2321
2322     HeapFree(GetProcessHeap(), 0, info);
2323     DeleteObject(hbmp);
2324     ReleaseDC(NULL, screen_dc);
2325 }
2326
2327 static BOOL compare_buffers_no_alpha(UINT32 *a, UINT32 *b, int length)
2328 {
2329     int i;
2330     for(i = 0; i < length; i++)
2331         if((a[i] & 0x00FFFFFF) != (b[i] & 0x00FFFFFF))
2332             return FALSE;
2333     return TRUE;
2334 }
2335
2336 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2337                                DWORD dwRop, UINT32 expected, int line)
2338 {
2339     *srcBuffer = 0xFEDCBA98;
2340     *dstBuffer = 0x89ABCDEF;
2341     Rectangle(hdcSrc, 0, 0, 1, 1);  /* A null operation to ensure dibs are coerced to X11 */
2342     BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
2343     ok(expected == *dstBuffer,
2344         "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2345         dwRop, expected, *dstBuffer, line);
2346 }
2347
2348 static void test_BitBlt(void)
2349 {
2350     HBITMAP bmpDst, bmpSrc;
2351     HBITMAP oldDst, oldSrc;
2352     HDC hdcScreen, hdcDst, hdcSrc;
2353     UINT32 *dstBuffer, *srcBuffer;
2354     HBRUSH hBrush, hOldBrush;
2355     BITMAPINFO bitmapInfo;
2356
2357     memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2358     bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2359     bitmapInfo.bmiHeader.biWidth = 1;
2360     bitmapInfo.bmiHeader.biHeight = 1;
2361     bitmapInfo.bmiHeader.biPlanes = 1;
2362     bitmapInfo.bmiHeader.biBitCount = 32;
2363     bitmapInfo.bmiHeader.biCompression = BI_RGB;
2364     bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2365
2366     hdcScreen = CreateCompatibleDC(0);
2367     hdcDst = CreateCompatibleDC(hdcScreen);
2368     hdcSrc = CreateCompatibleDC(hdcDst);
2369
2370     /* Setup the destination dib section */
2371     bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
2372         NULL, 0);
2373     oldDst = SelectObject(hdcDst, bmpDst);
2374
2375     hBrush = CreateSolidBrush(0x012345678);
2376     hOldBrush = SelectObject(hdcDst, hBrush);
2377
2378     /* Setup the source dib section */
2379     bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
2380         NULL, 0);
2381     oldSrc = SelectObject(hdcSrc, bmpSrc);
2382
2383     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2384     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2385     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2386     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2387     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2388     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2389     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2390     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2391     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2392     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2393     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2394     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2395     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2396     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2397     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2398
2399     /* Tidy up */
2400     SelectObject(hdcSrc, oldSrc);
2401     DeleteObject(bmpSrc);
2402     DeleteDC(hdcSrc);
2403
2404     SelectObject(hdcDst, hOldBrush);
2405     DeleteObject(hBrush);
2406     SelectObject(hdcDst, oldDst);
2407     DeleteObject(bmpDst);
2408     DeleteDC(hdcDst);
2409
2410
2411     DeleteDC(hdcScreen);
2412 }
2413
2414 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2415                                    DWORD dwRop, UINT32 expected, int line)
2416 {
2417     *srcBuffer = 0xFEDCBA98;
2418     *dstBuffer = 0x89ABCDEF;
2419     StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
2420     ok(expected == *dstBuffer,
2421         "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2422         dwRop, expected, *dstBuffer, line);
2423 }
2424
2425 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2426                                      int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2427                                      int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2428                                      UINT32 expected[4], UINT32 legacy_expected[4], int line)
2429 {
2430     memset(dstBuffer, 0, 16);
2431     StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2432                hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
2433     ok(memcmp(dstBuffer, expected, 16) == 0 ||
2434         broken(compare_buffers_no_alpha(dstBuffer, legacy_expected, 4)),
2435         "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2436         "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2437         expected[0], expected[1], expected[2], expected[3],
2438         dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2439         nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2440         nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2441 }
2442
2443 static void test_StretchBlt(void)
2444 {
2445     HBITMAP bmpDst, bmpSrc;
2446     HBITMAP oldDst, oldSrc;
2447     HDC hdcScreen, hdcDst, hdcSrc;
2448     UINT32 *dstBuffer, *srcBuffer;
2449     HBRUSH hBrush, hOldBrush;
2450     BITMAPINFO biDst, biSrc;
2451     UINT32 expected[4], legacy_expected[4];
2452
2453     memset(&biDst, 0, sizeof(BITMAPINFO));
2454     biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2455     biDst.bmiHeader.biWidth = 2;
2456     biDst.bmiHeader.biHeight = -2;
2457     biDst.bmiHeader.biPlanes = 1;
2458     biDst.bmiHeader.biBitCount = 32;
2459     biDst.bmiHeader.biCompression = BI_RGB;
2460     memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
2461
2462     hdcScreen = CreateCompatibleDC(0);
2463     hdcDst = CreateCompatibleDC(hdcScreen);
2464     hdcSrc = CreateCompatibleDC(hdcDst);
2465
2466     /* Pixel Tests */
2467     bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2468         NULL, 0);
2469     oldDst = SelectObject(hdcDst, bmpDst);
2470
2471     bmpSrc = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&srcBuffer,
2472         NULL, 0);
2473     oldSrc = SelectObject(hdcSrc, bmpSrc);
2474
2475     hBrush = CreateSolidBrush(0x012345678);
2476     hOldBrush = SelectObject(hdcDst, hBrush);
2477
2478     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2479     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2480     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2481     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2482     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2483     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2484     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2485     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2486     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2487     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2488     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2489     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2490     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2491     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2492     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2493
2494     SelectObject(hdcDst, hOldBrush);
2495     DeleteObject(hBrush);
2496
2497     /* Top-down to top-down tests */
2498     srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2499     srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
2500
2501     expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2502     expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2503     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2504                              0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2505
2506     expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2507     expected[2] = 0x00000000, expected[3] = 0x00000000;
2508     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2509                              0, 0, 1, 1, 0, 0, 1, 1, expected, expected, __LINE__);
2510
2511     expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
2512     expected[2] = 0xCAFED00D, expected[3] = 0xCAFED00D;
2513     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2514                              0, 0, 2, 2, 0, 0, 1, 1, expected, expected, __LINE__);
2515
2516     expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2517     expected[2] = 0x00000000, expected[3] = 0x00000000;
2518     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2519                              0, 0, 1, 1, 0, 0, 2, 2, expected, expected, __LINE__);
2520
2521     expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2522     expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2523     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2524                              0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2525
2526     expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2527     expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2528     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2529                              1, 1, -2, -2, 0, 0, 2, 2, expected, expected, __LINE__);
2530
2531     /* This result seems broken. One might expect the following result:
2532      * 0xCAFED00D 0xFEEDFACE
2533      * 0xFEDCBA98 0x76543210
2534      */
2535     expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2536     expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2537     legacy_expected[0] = 0xCAFED00D, legacy_expected[1] = 0x00000000;
2538     legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
2539     todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2540                                        1, 1, -2, -2, 1, 1, -2, -2, expected,
2541                                        legacy_expected, __LINE__);
2542
2543     expected[0] = 0x00000000, expected[1] = 0x00000000;
2544     expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
2545     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2546                              1, 1, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2547
2548     SelectObject(hdcDst, oldDst);
2549     DeleteObject(bmpDst);
2550
2551     /* Top-down to bottom-up tests */
2552     biDst.bmiHeader.biHeight = 2;
2553     bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2554         NULL, 0);
2555     oldDst = SelectObject(hdcDst, bmpDst);
2556
2557     expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2558     expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
2559     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2560                              0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2561
2562     expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2563     expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2564     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2565                              0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2566
2567     SelectObject(hdcSrc, oldSrc);
2568     DeleteObject(bmpSrc);
2569
2570     /* Bottom-up to bottom-up tests */
2571     biSrc.bmiHeader.biHeight = 2;
2572     bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2573         NULL, 0);
2574     srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2575     srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
2576     oldSrc = SelectObject(hdcSrc, bmpSrc);
2577
2578     expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2579     expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2580     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2581                              0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2582
2583     expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2584     expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2585     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2586                              0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2587
2588     SelectObject(hdcDst, oldDst);
2589     DeleteObject(bmpDst);
2590
2591     /* Bottom-up to top-down tests */
2592     biDst.bmiHeader.biHeight = -2;
2593     bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2594         NULL, 0);
2595     oldDst = SelectObject(hdcDst, bmpDst);
2596
2597     expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2598     expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
2599     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2600                              0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2601
2602     expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2603     expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2604     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2605                              0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2606
2607     /* Tidy up */
2608     SelectObject(hdcSrc, oldSrc);
2609     DeleteObject(bmpSrc);
2610     DeleteDC(hdcSrc);
2611
2612     SelectObject(hdcDst, oldDst);
2613     DeleteObject(bmpDst);
2614     DeleteDC(hdcDst);
2615
2616     DeleteDC(hdcScreen);
2617 }
2618
2619 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
2620                                       DWORD dwRop, UINT32 expected, int line)
2621 {
2622     const UINT32 buffer[2] = { 0xFEDCBA98, 0 };
2623     BITMAPINFO bitmapInfo;
2624
2625     memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2626     bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2627     bitmapInfo.bmiHeader.biWidth = 2;
2628     bitmapInfo.bmiHeader.biHeight = 1;
2629     bitmapInfo.bmiHeader.biPlanes = 1;
2630     bitmapInfo.bmiHeader.biBitCount = 32;
2631     bitmapInfo.bmiHeader.biCompression = BI_RGB;
2632     bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer);
2633
2634     *dstBuffer = 0x89ABCDEF;
2635
2636     StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop);
2637     ok(expected == *dstBuffer,
2638         "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2639         dwRop, expected, *dstBuffer, line);
2640 }
2641
2642 static void check_StretchDIBits_stretch(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
2643                                         int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2644                                         int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2645                                         UINT32 expected[4], UINT32 legacy_expected[4], int line)
2646 {
2647     BITMAPINFO bitmapInfo;
2648
2649     memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2650     bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2651     bitmapInfo.bmiHeader.biWidth = 2;
2652     bitmapInfo.bmiHeader.biHeight = -2;
2653     bitmapInfo.bmiHeader.biPlanes = 1;
2654     bitmapInfo.bmiHeader.biBitCount = 32;
2655     bitmapInfo.bmiHeader.biCompression = BI_RGB;
2656
2657     memset(dstBuffer, 0, 16);
2658     StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2659                   nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2660                   srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
2661     ok(memcmp(dstBuffer, expected, 16) == 0,
2662         "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2663         "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2664         expected[0], expected[1], expected[2], expected[3],
2665         dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2666         nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2667         nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2668 }
2669
2670 static void test_StretchDIBits(void)
2671 {
2672     HBITMAP bmpDst;
2673     HBITMAP oldDst;
2674     HDC hdcScreen, hdcDst;
2675     UINT32 *dstBuffer, srcBuffer[4];
2676     HBRUSH hBrush, hOldBrush;
2677     BITMAPINFO biDst;
2678     UINT32 expected[4], legacy_expected[4];
2679
2680     memset(&biDst, 0, sizeof(BITMAPINFO));
2681     biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2682     biDst.bmiHeader.biWidth = 2;
2683     biDst.bmiHeader.biHeight = -2;
2684     biDst.bmiHeader.biPlanes = 1;
2685     biDst.bmiHeader.biBitCount = 32;
2686     biDst.bmiHeader.biCompression = BI_RGB;
2687
2688     hdcScreen = CreateCompatibleDC(0);
2689     hdcDst = CreateCompatibleDC(hdcScreen);
2690
2691     /* Pixel Tests */
2692     bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2693         NULL, 0);
2694     oldDst = SelectObject(hdcDst, bmpDst);
2695
2696     hBrush = CreateSolidBrush(0x012345678);
2697     hOldBrush = SelectObject(hdcDst, hBrush);
2698
2699     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2700     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2701     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2702     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2703     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2704     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2705     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2706     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2707     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2708     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2709     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2710     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2711     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2712     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2713     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2714
2715     SelectObject(hdcDst, hOldBrush);
2716     DeleteObject(hBrush);
2717
2718     /* Top-down destination tests */
2719     srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2720     srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
2721
2722     expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2723     expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2724     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2725                                 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2726
2727     expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2728     expected[2] = 0x00000000, expected[3] = 0x00000000;
2729     legacy_expected[0] = 0xFEDCBA98, legacy_expected[1] = 0x00000000;
2730     legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
2731     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2732                                 0, 0, 1, 1, 0, 0, 1, 1, expected, legacy_expected, __LINE__);
2733
2734     expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
2735     expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
2736     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2737                                 0, 0, 2, 2, 0, 0, 1, 1, expected, expected, __LINE__);
2738
2739     expected[0] = 0x42441000, expected[1] = 0x00000000;
2740     expected[2] = 0x00000000, expected[3] = 0x00000000;
2741     legacy_expected[0] = 0x00543210, legacy_expected[1] = 0x00000000;
2742     legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
2743     todo_wine check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2744                                 0, 0, 1, 1, 0, 0, 2, 2, expected, legacy_expected, __LINE__);
2745
2746     expected[0] = 0x00000000, expected[1] = 0x00000000;
2747     expected[2] = 0x00000000, expected[3] = 0x00000000;
2748     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2749                                 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2750
2751     expected[0] = 0x00000000, expected[1] = 0x00000000;
2752     expected[2] = 0x00000000, expected[3] = 0x00000000;
2753     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2754                                 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2755
2756     expected[0] = 0x00000000, expected[1] = 0x00000000;
2757     expected[2] = 0x00000000, expected[3] = 0x00000000;
2758     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2759                                 1, 1, -2, -2, 1, 1, -2, -2, expected, expected, __LINE__);
2760
2761     expected[0] = 0x00000000, expected[1] = 0x00000000;
2762     expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
2763     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2764                                 1, 1, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2765
2766     SelectObject(hdcDst, oldDst);
2767     DeleteObject(bmpDst);
2768
2769     /* Bottom up destination tests */
2770     biDst.bmiHeader.biHeight = 2;
2771     bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2772         NULL, 0);
2773     oldDst = SelectObject(hdcDst, bmpDst);
2774
2775     expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2776     expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
2777     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2778                                 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2779
2780     /* Tidy up */
2781     SelectObject(hdcDst, oldDst);
2782     DeleteObject(bmpDst);
2783     DeleteDC(hdcDst);
2784
2785     DeleteDC(hdcScreen);
2786 }
2787
2788 static void test_GdiAlphaBlend(void)
2789 {
2790     /* test out-of-bound parameters for GdiAlphaBlend */
2791     HDC hdcNull;
2792
2793     HDC hdcDst;
2794     HBITMAP bmpDst;
2795     HBITMAP oldDst;
2796
2797     BITMAPINFO bmi;
2798     HDC hdcSrc;
2799     HBITMAP bmpSrc;
2800     HBITMAP oldSrc;
2801     LPVOID bits;
2802
2803     BLENDFUNCTION blend;
2804
2805     if (!pGdiAlphaBlend)
2806     {
2807         win_skip("GdiAlphaBlend() is not implemented\n");
2808         return;
2809     }
2810
2811     hdcNull = GetDC(NULL);
2812     hdcDst = CreateCompatibleDC(hdcNull);
2813     bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
2814     hdcSrc = CreateCompatibleDC(hdcNull);
2815
2816     memset(&bmi, 0, sizeof(bmi));  /* as of Wine 0.9.44 we require the src to be a DIB section */
2817     bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
2818     bmi.bmiHeader.biHeight = 20;
2819     bmi.bmiHeader.biWidth = 20;
2820     bmi.bmiHeader.biBitCount = 32;
2821     bmi.bmiHeader.biPlanes = 1;
2822     bmi.bmiHeader.biCompression = BI_RGB;
2823     bmpSrc = CreateDIBSection(hdcDst, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
2824     ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
2825
2826     oldDst = SelectObject(hdcDst, bmpDst);
2827     oldSrc = SelectObject(hdcSrc, bmpSrc);
2828
2829     blend.BlendOp = AC_SRC_OVER;
2830     blend.BlendFlags = 0;
2831     blend.SourceConstantAlpha = 128;
2832     blend.AlphaFormat = 0;
2833
2834     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend), TRUE, BOOL, "%d");
2835     SetLastError(0xdeadbeef);
2836     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), FALSE, BOOL, "%d");
2837     expect_eq(GetLastError(), ERROR_INVALID_PARAMETER, int, "%d");
2838     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), FALSE, BOOL, "%d");
2839     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend), FALSE, BOOL, "%d");
2840     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
2841     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
2842
2843     SetWindowOrgEx(hdcSrc, -10, -10, NULL);
2844     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), TRUE, BOOL, "%d");
2845     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), TRUE, BOOL, "%d");
2846     SetMapMode(hdcSrc, MM_ANISOTROPIC);
2847     ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
2848     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend), TRUE, BOOL, "%d");
2849     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend), TRUE, BOOL, "%d");
2850
2851     SetLastError(0xdeadbeef);
2852     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend), FALSE, BOOL, "%d");
2853     expect_eq(GetLastError(), 0xdeadbeef, int, "%d");
2854
2855     SelectObject(hdcDst, oldDst);
2856     SelectObject(hdcSrc, oldSrc);
2857     DeleteObject(bmpSrc);
2858     DeleteObject(bmpDst);
2859     DeleteDC(hdcDst);
2860     DeleteDC(hdcSrc);
2861
2862     ReleaseDC(NULL, hdcNull);
2863
2864 }
2865
2866 static void test_clipping(void)
2867 {
2868     HBITMAP bmpDst;
2869     HBITMAP bmpSrc;
2870     HRGN hRgn;
2871     LPVOID bits;
2872     BOOL result;
2873
2874     HDC hdcDst = CreateCompatibleDC( NULL );
2875     HDC hdcSrc = CreateCompatibleDC( NULL );
2876
2877     BITMAPINFO bmpinfo={{0}};
2878     bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2879     bmpinfo.bmiHeader.biWidth = 100;
2880     bmpinfo.bmiHeader.biHeight = 100;
2881     bmpinfo.bmiHeader.biPlanes = 1;
2882     bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
2883     bmpinfo.bmiHeader.biCompression = BI_RGB;
2884
2885     bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
2886     ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
2887     SelectObject( hdcDst, bmpDst );
2888
2889     bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
2890     ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
2891     SelectObject( hdcSrc, bmpSrc );
2892
2893     result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
2894     ok(result, "BitBlt failed\n");
2895
2896     hRgn = CreateRectRgn( 0,0,0,0 );
2897     SelectClipRgn( hdcDst, hRgn );
2898
2899     result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
2900     ok(result, "BitBlt failed\n");
2901
2902     DeleteObject( bmpDst );
2903     DeleteObject( bmpSrc );
2904     DeleteObject( hRgn );
2905     DeleteDC( hdcDst );
2906     DeleteDC( hdcSrc );
2907 }
2908
2909 static void test_32bit_bitmap_blt(void)
2910 {
2911     BITMAPINFO biDst;
2912     HBITMAP bmpSrc, bmpDst;
2913     HBITMAP oldSrc, oldDst;
2914     HDC hdcSrc, hdcDst, hdcScreen;
2915     UINT32 *dstBuffer;
2916     DWORD colorSrc = 0x11223344;
2917
2918     memset(&biDst, 0, sizeof(BITMAPINFO));
2919     biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2920     biDst.bmiHeader.biWidth = 2;
2921     biDst.bmiHeader.biHeight = -2;
2922     biDst.bmiHeader.biPlanes = 1;
2923     biDst.bmiHeader.biBitCount = 32;
2924     biDst.bmiHeader.biCompression = BI_RGB;
2925
2926     hdcScreen = CreateCompatibleDC(0);
2927     if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
2928     {
2929         DeleteDC(hdcScreen);
2930         trace("Skipping 32-bit DDB test\n");
2931         return;
2932     }
2933
2934     hdcSrc = CreateCompatibleDC(hdcScreen);
2935     bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
2936     oldSrc = SelectObject(hdcSrc, bmpSrc);
2937
2938     hdcDst = CreateCompatibleDC(hdcScreen);
2939     bmpDst = CreateDIBSection(hdcDst, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
2940     oldDst = SelectObject(hdcDst, bmpDst);
2941
2942     StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
2943     ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
2944
2945     /* Tidy up */
2946     SelectObject(hdcDst, oldDst);
2947     DeleteObject(bmpDst);
2948     DeleteDC(hdcDst);
2949
2950     SelectObject(hdcSrc, oldSrc);
2951     DeleteObject(bmpSrc);
2952     DeleteDC(hdcSrc);
2953
2954     DeleteDC(hdcScreen);
2955 }
2956
2957 /*
2958  * Used by test_GetDIBits_top_down to create the bitmap to test against.
2959  */
2960 static void setup_picture(char *picture, int bpp)
2961 {
2962     int i;
2963
2964     switch(bpp)
2965     {
2966         case 16:
2967         case 32:
2968             /*Set the first byte in each pixel to the index of that pixel.*/
2969             for (i = 0; i < 4; i++)
2970                 picture[i * (bpp / 8)] = i;
2971             break;
2972         case 24:
2973             picture[0] = 0;
2974             picture[3] = 1;
2975             /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
2976             picture[8] = 2;
2977             picture[11] = 3;
2978             break;
2979     }
2980 }
2981
2982 static void test_GetDIBits_top_down(int bpp)
2983 {
2984     BITMAPINFO bi;
2985     HBITMAP bmptb, bmpbt;
2986     HDC hdc;
2987     int pictureOut[4];
2988     int *picture;
2989     int statusCode;
2990
2991     bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
2992     bi.bmiHeader.biWidth=2;
2993     bi.bmiHeader.biHeight=2;
2994     bi.bmiHeader.biPlanes=1;
2995     bi.bmiHeader.biBitCount=bpp;
2996     bi.bmiHeader.biCompression=BI_RGB;
2997
2998     /*Get the device context for the screen.*/
2999     hdc = GetDC(NULL);
3000     ok(hdc != NULL, "Could not get a handle to a device context.\n");
3001
3002     /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
3003     bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3004     ok(bmpbt != NULL, "Could not create a DIB section.\n");
3005     /*Now that we have a pointer to the pixels, we write to them.*/
3006     setup_picture((char*)picture, bpp);
3007     /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
3008     bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
3009     bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3010     ok(bmptb != NULL, "Could not create a DIB section.\n");
3011     /*Write to this top to bottom bitmap.*/
3012     setup_picture((char*)picture, bpp);
3013
3014     bi.bmiHeader.biWidth = 1;
3015
3016     bi.bmiHeader.biHeight = 2;
3017     statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3018     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3019     /*Check the first byte of the pixel.*/
3020     ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3021     statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3022     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3023     ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3024     /*Check second scanline.*/
3025     statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3026     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3027     ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3028     statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3029     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3030     ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3031     /*Check both scanlines.*/
3032     statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3033     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3034     ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3035     ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3036     statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3037     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3038     ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3039     ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3040
3041     /*Make destination bitmap top-down.*/
3042     bi.bmiHeader.biHeight = -2;
3043     statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3044     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3045     ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3046     statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3047     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3048     ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3049     /*Check second scanline.*/
3050     statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3051     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3052     ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3053     statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3054     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3055     ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3056     /*Check both scanlines.*/
3057     statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3058     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3059     ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3060     ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3061     statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3062     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3063     ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3064     ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3065
3066     DeleteObject(bmpbt);
3067     DeleteObject(bmptb);
3068 }
3069
3070 START_TEST(bitmap)
3071 {
3072     HMODULE hdll;
3073
3074     hdll = GetModuleHandle("gdi32.dll");
3075     pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
3076
3077     test_createdibitmap();
3078     test_dibsections();
3079     test_mono_dibsection();
3080     test_bitmap();
3081     test_bmBits();
3082     test_GetDIBits_selected_DIB(1);
3083     test_GetDIBits_selected_DIB(4);
3084     test_GetDIBits_selected_DIB(8);
3085     test_GetDIBits_selected_DDB(TRUE);
3086     test_GetDIBits_selected_DDB(FALSE);
3087     test_GetDIBits();
3088     test_GetDIBits_BI_BITFIELDS();
3089     test_select_object();
3090     test_CreateBitmap();
3091     test_BitBlt();
3092     test_StretchBlt();
3093     test_StretchDIBits();
3094     test_GdiAlphaBlend();
3095     test_32bit_bitmap_blt();
3096     test_bitmapinfoheadersize();
3097     test_get16dibits();
3098     test_clipping();
3099     test_GetDIBits_top_down(16);
3100     test_GetDIBits_top_down(24);
3101     test_GetDIBits_top_down(32);
3102 }