mshtml: Rename call_event to fire_event.
[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 static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
37
38 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
39
40 static INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp )
41 {
42     switch(bpp)
43     {
44     case 1:
45         return 2 * ((bmWidth+15) >> 4);
46
47     case 24:
48         bmWidth *= 3; /* fall through */
49     case 8:
50         return bmWidth + (bmWidth & 1);
51
52     case 32:
53         return bmWidth * 4;
54
55     case 16:
56     case 15:
57         return bmWidth * 2;
58
59     case 4:
60         return 2 * ((bmWidth+3) >> 2);
61
62     default:
63         trace("Unknown depth %d, please report.\n", bpp );
64         assert(0);
65     }
66     return -1;
67 }
68
69 static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHEADER *bmih)
70 {
71     BITMAP bm;
72     BITMAP bma[2];
73     INT ret, width_bytes;
74     BYTE buf[512], buf_cmp[512];
75
76     ret = GetObject(hbm, sizeof(bm), &bm);
77     ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
78
79     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
80     ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
81     ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
82     width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
83     ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
84     ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
85     ok(bm.bmBitsPixel == expected_depth, "wrong bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, expected_depth);
86     ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
87
88     assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
89     assert(sizeof(buf) == sizeof(buf_cmp));
90
91     SetLastError(0xdeadbeef);
92     ret = GetBitmapBits(hbm, 0, NULL);
93     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
94
95     memset(buf_cmp, 0xAA, sizeof(buf_cmp));
96     memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
97
98     memset(buf, 0xAA, sizeof(buf));
99     ret = GetBitmapBits(hbm, sizeof(buf), buf);
100     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
101     ok(!memcmp(buf, buf_cmp, sizeof(buf)),
102         "buffers do not match, depth %d\n", bmih->biBitCount);
103
104     /* test various buffer sizes for GetObject */
105     ret = GetObject(hbm, sizeof(*bma) * 2, bma);
106     ok(ret == sizeof(*bma), "wrong size %d\n", ret);
107
108     ret = GetObject(hbm, sizeof(bm) / 2, &bm);
109     ok(ret == 0, "%d != 0\n", ret);
110
111     ret = GetObject(hbm, 0, &bm);
112     ok(ret == 0, "%d != 0\n", ret);
113
114     ret = GetObject(hbm, 1, &bm);
115     ok(ret == 0, "%d != 0\n", ret);
116
117     ret = GetObject(hbm, 0, NULL);
118     ok(ret == sizeof(bm), "wrong size %d\n", ret);
119 }
120
121 static void test_createdibitmap(void)
122 {
123     HDC hdc, hdcmem;
124     BITMAPINFOHEADER bmih;
125     BITMAPINFO bm;
126     HBITMAP hbm, hbm_colour, hbm_old;
127     INT screen_depth;
128     DWORD pixel;
129
130     hdc = GetDC(0);
131     screen_depth = GetDeviceCaps(hdc, BITSPIXEL);
132     memset(&bmih, 0, sizeof(bmih));
133     bmih.biSize = sizeof(bmih);
134     bmih.biWidth = 10;
135     bmih.biHeight = 10;
136     bmih.biPlanes = 1;
137     bmih.biBitCount = 32;
138     bmih.biCompression = BI_RGB;
139
140     hbm = CreateDIBitmap(hdc, NULL, CBM_INIT, NULL, NULL, 0);
141     ok(hbm == NULL, "CreateDIBitmap should fail\n");
142     hbm = CreateDIBitmap(hdc, NULL, 0, NULL, NULL, 0);
143     ok(hbm == NULL, "CreateDIBitmap should fail\n");
144
145     /* First create an un-initialised bitmap.  The depth of the bitmap
146        should match that of the hdc and not that supplied in bmih.
147     */
148
149     /* First try 32 bits */
150     hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
151     ok(hbm != NULL, "CreateDIBitmap failed\n");
152     test_bitmap_info(hbm, screen_depth, &bmih);
153     DeleteObject(hbm);
154     
155     /* Then 16 */
156     bmih.biBitCount = 16;
157     hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
158     ok(hbm != NULL, "CreateDIBitmap failed\n");
159     test_bitmap_info(hbm, screen_depth, &bmih);
160     DeleteObject(hbm);
161
162     /* Then 1 */
163     bmih.biBitCount = 1;
164     hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
165     ok(hbm != NULL, "CreateDIBitmap failed\n");
166     test_bitmap_info(hbm, screen_depth, &bmih);
167     DeleteObject(hbm);
168
169     /* Now with a monochrome dc we expect a monochrome bitmap */
170     hdcmem = CreateCompatibleDC(hdc);
171
172     /* First try 32 bits */
173     bmih.biBitCount = 32;
174     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
175     ok(hbm != NULL, "CreateDIBitmap failed\n");
176     test_bitmap_info(hbm, 1, &bmih);
177     DeleteObject(hbm);
178     
179     /* Then 16 */
180     bmih.biBitCount = 16;
181     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
182     ok(hbm != NULL, "CreateDIBitmap failed\n");
183     test_bitmap_info(hbm, 1, &bmih);
184     DeleteObject(hbm);
185     
186     /* Then 1 */
187     bmih.biBitCount = 1;
188     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
189     ok(hbm != NULL, "CreateDIBitmap failed\n");
190     test_bitmap_info(hbm, 1, &bmih);
191     DeleteObject(hbm);
192
193     /* Now select a polychrome bitmap into the dc and we expect
194        screen_depth bitmaps again */
195     hbm_colour = CreateCompatibleBitmap(hdc, bmih.biWidth, bmih.biHeight);
196     test_bitmap_info(hbm_colour, screen_depth, &bmih);
197     hbm_old = SelectObject(hdcmem, hbm_colour);
198
199     /* First try 32 bits */
200     bmih.biBitCount = 32;
201     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
202     ok(hbm != NULL, "CreateDIBitmap failed\n");
203     test_bitmap_info(hbm, screen_depth, &bmih);
204     DeleteObject(hbm);
205     
206     /* Then 16 */
207     bmih.biBitCount = 16;
208     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
209     ok(hbm != NULL, "CreateDIBitmap failed\n");
210     test_bitmap_info(hbm, screen_depth, &bmih);
211     DeleteObject(hbm);
212     
213     /* Then 1 */
214     bmih.biBitCount = 1;
215     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
216     ok(hbm != NULL, "CreateDIBitmap failed\n");
217     test_bitmap_info(hbm, screen_depth, &bmih);
218     DeleteObject(hbm);
219
220     SelectObject(hdcmem, hbm_old);
221     DeleteObject(hbm_colour);
222     DeleteDC(hdcmem);
223
224     bmih.biBitCount = 32;
225     hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0);
226     ok(hbm != NULL, "CreateDIBitmap failed\n");
227     test_bitmap_info(hbm, 1, &bmih);
228     DeleteObject(hbm);
229
230     /* Test how formats are converted */
231     pixel = 0xffffffff;
232     bmih.biBitCount = 1;
233     bmih.biWidth = 1;
234     bmih.biHeight = 1;
235
236     memset(&bm, 0, sizeof(bm));
237     bm.bmiHeader.biSize = sizeof(bm.bmiHeader);
238     bm.bmiHeader.biWidth = 1;
239     bm.bmiHeader.biHeight = 1;
240     bm.bmiHeader.biPlanes = 1;
241     bm.bmiHeader.biBitCount= 24;
242     bm.bmiHeader.biCompression= BI_RGB;
243     bm.bmiHeader.biSizeImage = 0;
244     hbm = CreateDIBitmap(hdc, &bmih, CBM_INIT, &pixel, &bm, DIB_RGB_COLORS);
245     ok(hbm != NULL, "CreateDIBitmap failed\n");
246
247     pixel = 0xdeadbeef;
248     bm.bmiHeader.biBitCount= 32;
249     GetDIBits(hdc, hbm, 0, 1, &pixel, &bm, DIB_RGB_COLORS);
250     ok(pixel == 0x00ffffff, "Reading a 32 bit pixel from a DDB returned %08x\n", pixel);
251     DeleteObject(hbm);
252
253     ReleaseDC(0, hdc);
254 }
255
256 static INT DIB_GetWidthBytes( int width, int bpp )
257 {
258     int words;
259
260     switch (bpp)
261     {
262         case 1:  words = (width + 31) / 32; break;
263         case 4:  words = (width + 7) / 8; break;
264         case 8:  words = (width + 3) / 4; break;
265         case 15:
266         case 16: words = (width + 1) / 2; break;
267         case 24: words = (width * 3 + 3)/4; break;
268         case 32: words = width; break;
269
270         default:
271             words=0;
272             trace("Unknown depth %d, please report.\n", bpp );
273             assert(0);
274             break;
275     }
276     return 4 * words;
277 }
278
279 static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
280 {
281     BITMAP bm;
282     BITMAP bma[2];
283     DIBSECTION ds;
284     DIBSECTION dsa[2];
285     INT ret, bm_width_bytes, dib_width_bytes;
286     BYTE *buf;
287
288     ret = GetObject(hbm, sizeof(bm), &bm);
289     ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
290
291     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
292     ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
293     ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
294     dib_width_bytes = DIB_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
295     bm_width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
296     if (bm.bmWidthBytes != dib_width_bytes) /* Win2k bug */
297         ok(bm.bmWidthBytes == bm_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, bm_width_bytes);
298     else
299         ok(bm.bmWidthBytes == dib_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, dib_width_bytes);
300     ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
301     ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount);
302     ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
303
304     buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);
305
306     /* GetBitmapBits returns not 32-bit aligned data */
307     SetLastError(0xdeadbeef);
308     ret = GetBitmapBits(hbm, 0, NULL);
309     ok(ret == bm_width_bytes * bm.bmHeight,
310         "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
311
312     memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
313     ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
314     ok(ret == bm_width_bytes * bm.bmHeight, "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
315
316     HeapFree(GetProcessHeap(), 0, buf);
317
318     /* test various buffer sizes for GetObject */
319     memset(&ds, 0xAA, sizeof(ds));
320     ret = GetObject(hbm, sizeof(*bma) * 2, bma);
321     ok(ret == sizeof(*bma), "wrong size %d\n", ret);
322     ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
323     ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
324     ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
325
326     ret = GetObject(hbm, sizeof(bm) / 2, &bm);
327     ok(ret == 0, "%d != 0\n", ret);
328
329     ret = GetObject(hbm, 0, &bm);
330     ok(ret == 0, "%d != 0\n", ret);
331
332     ret = GetObject(hbm, 1, &bm);
333     ok(ret == 0, "%d != 0\n", ret);
334
335     /* test various buffer sizes for GetObject */
336     ret = GetObject(hbm, 0, NULL);
337     ok(ret == sizeof(bm), "wrong size %d\n", ret);
338
339     ret = GetObject(hbm, sizeof(*dsa) * 2, dsa);
340     ok(ret == sizeof(*dsa), "wrong size %d\n", ret);
341
342     memset(&ds, 0xAA, sizeof(ds));
343     ret = GetObject(hbm, sizeof(ds), &ds);
344     ok(ret == sizeof(ds), "wrong size %d\n", ret);
345
346     ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
347     if (ds.dsBm.bmWidthBytes != bm_width_bytes) /* Win2k bug */
348         ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%u != %u\n",
349            ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
350     ok(bmih->biSizeImage == 0, "%u != 0\n", bmih->biSizeImage);
351     ds.dsBmih.biSizeImage = 0;
352
353     ok(ds.dsBmih.biSize == bmih->biSize, "%u != %u\n", ds.dsBmih.biSize, bmih->biSize);
354     ok(ds.dsBmih.biWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
355     ok(ds.dsBmih.biHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
356     ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes);
357     ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount);
358     ok(ds.dsBmih.biCompression == bmih->biCompression ||
359        ((bmih->biBitCount == 32) && broken(ds.dsBmih.biCompression == BI_BITFIELDS)), /* nt4 sp1 and 2 */
360        "%u != %u\n", ds.dsBmih.biCompression, bmih->biCompression);
361     ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%u != %u\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
362     ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%d != %d\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
363     ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%d != %d\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);
364
365     memset(&ds, 0xAA, sizeof(ds));
366     ret = GetObject(hbm, sizeof(ds) - 4, &ds);
367     ok(ret == sizeof(ds.dsBm), "wrong size %d\n", ret);
368     ok(ds.dsBm.bmWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
369     ok(ds.dsBm.bmHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
370     ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);
371
372     ret = GetObject(hbm, 0, &ds);
373     ok(ret == 0, "%d != 0\n", ret);
374
375     ret = GetObject(hbm, 1, &ds);
376     ok(ret == 0, "%d != 0\n", ret);
377 }
378
379 #define test_color_todo(got, exp, txt, todo) \
380     if (!todo && got != exp && screen_depth < 24) { \
381       todo_wine ok(0, #txt " failed at %d-bit screen depth: got 0x%06x expected 0x%06x - skipping DIB tests\n", \
382                    screen_depth, (UINT)got, (UINT)exp); \
383       return; \
384     } else if (todo) todo_wine { ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp); } \
385     else ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp) \
386
387 #define test_color(hdc, color, exp, todo_setp, todo_getp) \
388 { \
389     COLORREF c; \
390     c = SetPixel(hdc, 0, 0, color); \
391     test_color_todo(c, exp, SetPixel, todo_setp); \
392     c = GetPixel(hdc, 0, 0); \
393     test_color_todo(c, exp, GetPixel, todo_getp); \
394 }
395
396 static void test_dib_bits_access( HBITMAP hdib, void *bits )
397 {
398     MEMORY_BASIC_INFORMATION info;
399     char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
400     DWORD data[256];
401     BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
402     HDC hdc;
403     char filename[MAX_PATH];
404     HANDLE file;
405     DWORD written;
406     INT ret;
407
408     ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
409         "VirtualQuery failed\n");
410     ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
411     ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
412     ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
413     ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
414     ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
415     ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
416
417     memset( pbmi, 0, sizeof(bmibuf) );
418     memset( data, 0xcc, sizeof(data) );
419     pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
420     pbmi->bmiHeader.biHeight = 16;
421     pbmi->bmiHeader.biWidth = 16;
422     pbmi->bmiHeader.biBitCount = 32;
423     pbmi->bmiHeader.biPlanes = 1;
424     pbmi->bmiHeader.biCompression = BI_RGB;
425
426     hdc = GetDC(0);
427
428     ret = SetDIBits( hdc, hdib, 0, 16, data, pbmi, DIB_RGB_COLORS );
429     ok(ret == 16, "SetDIBits failed: expected 16 got %d\n", ret);
430
431     ReleaseDC(0, hdc);
432
433     ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
434         "VirtualQuery failed\n");
435     ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
436     ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
437     ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
438     ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
439     ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
440     /* it has been protected now */
441     todo_wine ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
442
443     /* try writing protected bits to a file */
444
445     GetTempFileNameA( ".", "dib", 0, filename );
446     file = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
447                         CREATE_ALWAYS, 0, 0 );
448     ok( file != INVALID_HANDLE_VALUE, "failed to open %s error %u\n", filename, GetLastError() );
449     ret = WriteFile( file, bits, 8192, &written, NULL );
450     ok( ret, "WriteFile failed error %u\n", GetLastError() );
451     if (ret) ok( written == 8192, "only wrote %u bytes\n", written );
452     CloseHandle( file );
453     DeleteFileA( filename );
454 }
455
456 static void test_dibsections(void)
457 {
458     HDC hdc, hdcmem, hdcmem2;
459     HBITMAP hdib, oldbm, hdib2, oldbm2;
460     char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
461     char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
462     BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
463     BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
464     HBITMAP hcoredib;
465     char coreBits[256];
466     BYTE *bits;
467     RGBQUAD rgb[256];
468     int ret;
469     char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
470     LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
471     WORD *index;
472     DWORD *bits32;
473     HPALETTE hpal, oldpal;
474     DIBSECTION dibsec;
475     COLORREF c0, c1;
476     int i;
477     int screen_depth;
478     MEMORY_BASIC_INFORMATION info;
479
480     hdc = GetDC(0);
481     screen_depth = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
482
483     memset(pbmi, 0, sizeof(bmibuf));
484     pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
485     pbmi->bmiHeader.biHeight = 100;
486     pbmi->bmiHeader.biWidth = 512;
487     pbmi->bmiHeader.biBitCount = 24;
488     pbmi->bmiHeader.biPlanes = 1;
489     pbmi->bmiHeader.biCompression = BI_RGB;
490
491     SetLastError(0xdeadbeef);
492
493     /* invalid pointer for BITMAPINFO
494        (*bits should be NULL on error) */
495     bits = (BYTE*)0xdeadbeef;
496     hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
497     ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n");
498
499     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
500     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
501     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
502     ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
503
504     /* test the DIB memory */
505     ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
506         "VirtualQuery failed\n");
507     ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
508     ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
509     ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
510     ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
511     ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
512     ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
513     ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
514
515     test_dib_bits_access( hdib, bits );
516
517     test_dib_info(hdib, bits, &pbmi->bmiHeader);
518     DeleteObject(hdib);
519
520     /* Test a top-down DIB. */
521     pbmi->bmiHeader.biHeight = -100;
522     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
523     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
524     test_dib_info(hdib, bits, &pbmi->bmiHeader);
525     DeleteObject(hdib);
526
527     pbmi->bmiHeader.biHeight = 100;
528     pbmi->bmiHeader.biBitCount = 8;
529     pbmi->bmiHeader.biCompression = BI_RLE8;
530     SetLastError(0xdeadbeef);
531     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
532     ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
533     ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
534
535     for (i = 0; i < 128; i++)
536     {
537         pbmi->bmiHeader.biBitCount = i;
538         pbmi->bmiHeader.biCompression = BI_RGB;
539         hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
540         if (i == 1 || i == 4 || i == 8 || i == 16 || i == 24 || i == 32)
541             ok(hdib != NULL, "CreateDIBSection bpp %u\n", i);
542         else
543             ok(hdib == NULL, "CreateDIBSection bpp %u succeeded\n", i);
544         if (hdib) DeleteObject( hdib );
545     }
546
547     pbmi->bmiHeader.biBitCount = 16;
548     pbmi->bmiHeader.biCompression = BI_BITFIELDS;
549     ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
550     ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
551     ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
552     SetLastError(0xdeadbeef);
553     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
554     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
555
556     /* test the DIB memory */
557     ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
558         "VirtualQuery failed\n");
559     ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
560     ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
561     ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
562     ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
563     ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
564     ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
565     ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
566
567     test_dib_info(hdib, bits, &pbmi->bmiHeader);
568     DeleteObject(hdib);
569
570     memset(pbmi, 0, sizeof(bmibuf));
571     pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
572     pbmi->bmiHeader.biHeight = 16;
573     pbmi->bmiHeader.biWidth = 16;
574     pbmi->bmiHeader.biBitCount = 1;
575     pbmi->bmiHeader.biPlanes = 1;
576     pbmi->bmiHeader.biCompression = BI_RGB;
577     pbmi->bmiColors[0].rgbRed = 0xff;
578     pbmi->bmiColors[0].rgbGreen = 0;
579     pbmi->bmiColors[0].rgbBlue = 0;
580     pbmi->bmiColors[1].rgbRed = 0;
581     pbmi->bmiColors[1].rgbGreen = 0;
582     pbmi->bmiColors[1].rgbBlue = 0xff;
583
584     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
585     ok(hdib != NULL, "CreateDIBSection failed\n");
586     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
587     ok(dibsec.dsBmih.biClrUsed == 2,
588         "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
589
590     /* Test if the old BITMAPCOREINFO structure is supported */    
591         
592     pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
593     pbci->bmciHeader.bcBitCount = 0;
594
595     ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
596     ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
597     ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
598         && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
599     "GetDIBits did't fill in the BITMAPCOREHEADER structure properly\n");
600
601     ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
602     ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
603     ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
604         (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
605         (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
606         "The color table has not been translated to the old BITMAPCOREINFO format\n");
607
608     hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
609     ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
610
611     ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
612     ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
613     ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
614     ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
615         (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
616         (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
617         "The color table has not been translated to the old BITMAPCOREINFO format\n");
618
619     DeleteObject(hcoredib);
620
621     hdcmem = CreateCompatibleDC(hdc);
622     oldbm = SelectObject(hdcmem, hdib);
623
624     ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
625     ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
626     ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
627        "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
628        rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
629        rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
630
631     c0 = RGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen, pbmi->bmiColors[0].rgbBlue);
632     c1 = RGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen, pbmi->bmiColors[1].rgbBlue);
633
634     test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
635     test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
636     test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
637     test_color(hdcmem, PALETTEINDEX(0), c0, 1, 1);
638     test_color(hdcmem, PALETTEINDEX(1), c0, 1, 1);
639     test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
640     test_color(hdcmem, PALETTERGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen,
641         pbmi->bmiColors[0].rgbBlue), c0, 1, 1);
642     test_color(hdcmem, PALETTERGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen,
643         pbmi->bmiColors[1].rgbBlue), c1, 1, 1);
644     test_color(hdcmem, PALETTERGB(0, 0, 0), c0, 1, 1);
645     test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
646     test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1, 1, 1);
647
648     SelectObject(hdcmem, oldbm);
649     DeleteObject(hdib);
650
651     pbmi->bmiColors[0].rgbRed = 0xff;
652     pbmi->bmiColors[0].rgbGreen = 0xff;
653     pbmi->bmiColors[0].rgbBlue = 0xff;
654     pbmi->bmiColors[1].rgbRed = 0;
655     pbmi->bmiColors[1].rgbGreen = 0;
656     pbmi->bmiColors[1].rgbBlue = 0;
657
658     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
659     ok(hdib != NULL, "CreateDIBSection failed\n");
660
661     test_dib_info(hdib, bits, &pbmi->bmiHeader);
662
663     oldbm = SelectObject(hdcmem, hdib);
664
665     ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
666     ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
667     ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
668        "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
669        rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
670        rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
671
672     SelectObject(hdcmem, oldbm);
673     test_dib_info(hdib, bits, &pbmi->bmiHeader);
674     DeleteObject(hdib);
675
676     pbmi->bmiHeader.biBitCount = 4;
677     for (i = 0; i < 16; i++) {
678         pbmi->bmiColors[i].rgbRed = i;
679         pbmi->bmiColors[i].rgbGreen = 16-i;
680         pbmi->bmiColors[i].rgbBlue = 0;
681     }
682     hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
683     ok(hdib != NULL, "CreateDIBSection failed\n");
684     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
685     ok(dibsec.dsBmih.biClrUsed == 16,
686        "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
687     test_dib_info(hdib, bits, &pbmi->bmiHeader);
688     DeleteObject(hdib);
689
690     pbmi->bmiHeader.biBitCount = 8;
691
692     for (i = 0; i < 128; i++) {
693         pbmi->bmiColors[i].rgbRed = 255 - i * 2;
694         pbmi->bmiColors[i].rgbGreen = i * 2;
695         pbmi->bmiColors[i].rgbBlue = 0;
696         pbmi->bmiColors[255 - i].rgbRed = 0;
697         pbmi->bmiColors[255 - i].rgbGreen = i * 2;
698         pbmi->bmiColors[255 - i].rgbBlue = 255 - i * 2;
699     }
700     hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
701     ok(hdib != NULL, "CreateDIBSection failed\n");
702     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
703     ok(dibsec.dsBmih.biClrUsed == 256,
704         "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
705
706     oldbm = SelectObject(hdcmem, hdib);
707
708     for (i = 0; i < 256; i++) {
709         test_color(hdcmem, DIBINDEX(i), 
710             RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
711         test_color(hdcmem, PALETTERGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 
712             RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
713     }
714
715     SelectObject(hdcmem, oldbm);
716     test_dib_info(hdib, bits, &pbmi->bmiHeader);
717     DeleteObject(hdib);
718
719     pbmi->bmiHeader.biBitCount = 1;
720
721     /* Now create a palette and a palette indexed dib section */
722     memset(plogpal, 0, sizeof(logpalbuf));
723     plogpal->palVersion = 0x300;
724     plogpal->palNumEntries = 2;
725     plogpal->palPalEntry[0].peRed = 0xff;
726     plogpal->palPalEntry[0].peBlue = 0xff;
727     plogpal->palPalEntry[1].peGreen = 0xff;
728
729     index = (WORD*)pbmi->bmiColors;
730     *index++ = 0;
731     *index = 1;
732     hpal = CreatePalette(plogpal);
733     ok(hpal != NULL, "CreatePalette failed\n");
734     oldpal = SelectPalette(hdc, hpal, TRUE);
735     hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
736     ok(hdib != NULL, "CreateDIBSection failed\n");
737     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
738     ok(dibsec.dsBmih.biClrUsed == 2, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
739
740     /* The colour table has already been grabbed from the dc, so we select back the
741        old palette */
742
743     SelectPalette(hdc, oldpal, TRUE);
744     oldbm = SelectObject(hdcmem, hdib);
745     oldpal = SelectPalette(hdcmem, hpal, TRUE);
746
747     ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
748     ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
749     ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
750        rgb[1].rgbRed == 0    && rgb[1].rgbBlue == 0    && rgb[1].rgbGreen == 0xff,
751        "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
752        rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
753        rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
754
755     c0 = RGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen, plogpal->palPalEntry[0].peBlue);
756     c1 = RGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen, plogpal->palPalEntry[1].peBlue);
757
758     test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
759     test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
760     test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
761     test_color(hdcmem, PALETTEINDEX(0), c0, 0, 1);
762     test_color(hdcmem, PALETTEINDEX(1), c1, 0, 1);
763     test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
764     test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen,
765         plogpal->palPalEntry[0].peBlue), c0, 1, 1);
766     test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen,
767         plogpal->palPalEntry[1].peBlue), c1, 1, 1);
768     test_color(hdcmem, PALETTERGB(0, 0, 0), c1, 1, 1);
769     test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
770     test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0, 1, 1);
771     test_color(hdcmem, PALETTERGB(0, 1, 0), c1, 1, 1);
772     test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1, 1, 1);
773     test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0, 1, 1);
774
775     /* Bottom and 2nd row from top green, everything else magenta */
776     bits[0] = bits[1] = 0xff;
777     bits[13 * 4] = bits[13*4 + 1] = 0xff;
778
779     test_dib_info(hdib, bits, &pbmi->bmiHeader);
780
781     pbmi->bmiHeader.biBitCount = 32;
782
783     hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
784     ok(hdib2 != NULL, "CreateDIBSection failed\n");
785     hdcmem2 = CreateCompatibleDC(hdc);
786     oldbm2 = SelectObject(hdcmem2, hdib2);
787
788     BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
789
790     ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
791     ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
792
793     SelectObject(hdcmem2, oldbm2);
794     test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
795     DeleteObject(hdib2);
796
797     SelectObject(hdcmem, oldbm);
798     SelectPalette(hdcmem, oldpal, TRUE);
799     DeleteObject(hdib);
800     DeleteObject(hpal);
801
802
803     pbmi->bmiHeader.biBitCount = 8;
804
805     memset(plogpal, 0, sizeof(logpalbuf));
806     plogpal->palVersion = 0x300;
807     plogpal->palNumEntries = 256;
808
809     for (i = 0; i < 128; i++) {
810         plogpal->palPalEntry[i].peRed = 255 - i * 2;
811         plogpal->palPalEntry[i].peBlue = i * 2;
812         plogpal->palPalEntry[i].peGreen = 0;
813         plogpal->palPalEntry[255 - i].peRed = 0;
814         plogpal->palPalEntry[255 - i].peGreen = i * 2;
815         plogpal->palPalEntry[255 - i].peBlue = 255 - i * 2;
816     }
817
818     index = (WORD*)pbmi->bmiColors;
819     for (i = 0; i < 256; i++) {
820         *index++ = i;
821     }
822
823     hpal = CreatePalette(plogpal);
824     ok(hpal != NULL, "CreatePalette failed\n");
825     oldpal = SelectPalette(hdc, hpal, TRUE);
826     hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
827     ok(hdib != NULL, "CreateDIBSection failed\n");
828     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
829     ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
830
831     test_dib_info(hdib, bits, &pbmi->bmiHeader);
832
833     SelectPalette(hdc, oldpal, TRUE);
834     oldbm = SelectObject(hdcmem, hdib);
835     oldpal = SelectPalette(hdcmem, hpal, TRUE);
836
837     ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
838     ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
839     for (i = 0; i < 256; i++) {
840         ok(rgb[i].rgbRed == plogpal->palPalEntry[i].peRed && 
841             rgb[i].rgbBlue == plogpal->palPalEntry[i].peBlue && 
842             rgb[i].rgbGreen == plogpal->palPalEntry[i].peGreen, 
843             "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
844             i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
845     }
846
847     for (i = 0; i < 256; i++) {
848         test_color(hdcmem, DIBINDEX(i), 
849             RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
850         test_color(hdcmem, PALETTEINDEX(i), 
851             RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
852         test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 
853             RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
854     }
855
856     SelectPalette(hdcmem, oldpal, TRUE);
857     SelectObject(hdcmem, oldbm);
858     DeleteObject(hdib);
859     DeleteObject(hpal);
860
861     DeleteDC(hdcmem);
862     DeleteDC(hdcmem2);
863     ReleaseDC(0, hdc);
864 }
865
866 static void test_mono_dibsection(void)
867 {
868     HDC hdc, memdc;
869     HBITMAP old_bm, mono_ds;
870     char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
871     BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
872     BYTE bits[10 * 4];
873     BYTE *ds_bits;
874     int num;
875
876     hdc = GetDC(0);
877
878     memdc = CreateCompatibleDC(hdc);
879
880     memset(pbmi, 0, sizeof(bmibuf));
881     pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
882     pbmi->bmiHeader.biHeight = 10;
883     pbmi->bmiHeader.biWidth = 10;
884     pbmi->bmiHeader.biBitCount = 1;
885     pbmi->bmiHeader.biPlanes = 1;
886     pbmi->bmiHeader.biCompression = BI_RGB;
887     pbmi->bmiColors[0].rgbRed = 0xff;
888     pbmi->bmiColors[0].rgbGreen = 0xff;
889     pbmi->bmiColors[0].rgbBlue = 0xff;
890     pbmi->bmiColors[1].rgbRed = 0x0;
891     pbmi->bmiColors[1].rgbGreen = 0x0;
892     pbmi->bmiColors[1].rgbBlue = 0x0;
893
894     /*
895      * First dib section is 'inverted' ie color[0] is white, color[1] is black
896      */
897
898     mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
899     ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
900     old_bm = SelectObject(memdc, mono_ds);
901
902     /* black border, white interior */
903     Rectangle(memdc, 0, 0, 10, 10);
904     ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
905     ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
906
907     /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
908
909     memset(bits, 0, sizeof(bits));
910     bits[0] = 0xaa;
911
912     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
913     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
914
915     /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
916
917     pbmi->bmiColors[0].rgbRed = 0x0;
918     pbmi->bmiColors[0].rgbGreen = 0x0;
919     pbmi->bmiColors[0].rgbBlue = 0x0;
920     pbmi->bmiColors[1].rgbRed = 0xff;
921     pbmi->bmiColors[1].rgbGreen = 0xff;
922     pbmi->bmiColors[1].rgbBlue = 0xff;
923
924     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
925     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
926
927     SelectObject(memdc, old_bm);
928     DeleteObject(mono_ds);
929
930     /*
931      * Next dib section is 'normal' ie color[0] is black, color[1] is white
932      */
933
934     pbmi->bmiColors[0].rgbRed = 0x0;
935     pbmi->bmiColors[0].rgbGreen = 0x0;
936     pbmi->bmiColors[0].rgbBlue = 0x0;
937     pbmi->bmiColors[1].rgbRed = 0xff;
938     pbmi->bmiColors[1].rgbGreen = 0xff;
939     pbmi->bmiColors[1].rgbBlue = 0xff;
940
941     mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
942     ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
943     old_bm = SelectObject(memdc, mono_ds);
944
945     /* black border, white interior */
946     Rectangle(memdc, 0, 0, 10, 10);
947     ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
948     ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
949
950     /* SetDIBitsToDevice with a normal bmi -> normal dib section */
951
952     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
953     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
954
955     /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
956
957     pbmi->bmiColors[0].rgbRed = 0xff;
958     pbmi->bmiColors[0].rgbGreen = 0xff;
959     pbmi->bmiColors[0].rgbBlue = 0xff;
960     pbmi->bmiColors[1].rgbRed = 0x0;
961     pbmi->bmiColors[1].rgbGreen = 0x0;
962     pbmi->bmiColors[1].rgbBlue = 0x0;
963
964     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
965     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
966
967     /*
968      * Take that 'normal' dibsection and change its colour table to an 'inverted' one
969      */
970
971     pbmi->bmiColors[0].rgbRed = 0xff;
972     pbmi->bmiColors[0].rgbGreen = 0xff;
973     pbmi->bmiColors[0].rgbBlue = 0xff;
974     pbmi->bmiColors[1].rgbRed = 0x0;
975     pbmi->bmiColors[1].rgbGreen = 0x0;
976     pbmi->bmiColors[1].rgbBlue = 0x0;
977     num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors);
978     ok(num == 2, "num = %d\n", num);
979
980     /* black border, white interior */
981     Rectangle(memdc, 0, 0, 10, 10);
982     ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
983     ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
984
985     /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
986
987     memset(bits, 0, sizeof(bits));
988     bits[0] = 0xaa;
989
990     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
991     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
992
993     /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
994
995     pbmi->bmiColors[0].rgbRed = 0x0;
996     pbmi->bmiColors[0].rgbGreen = 0x0;
997     pbmi->bmiColors[0].rgbBlue = 0x0;
998     pbmi->bmiColors[1].rgbRed = 0xff;
999     pbmi->bmiColors[1].rgbGreen = 0xff;
1000     pbmi->bmiColors[1].rgbBlue = 0xff;
1001
1002     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1003     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1004
1005     SelectObject(memdc, old_bm);
1006     DeleteObject(mono_ds);
1007
1008     /*
1009      * Now a dib section with a strange colour map just for fun.  This behaves just like an inverted one.
1010      */
1011  
1012     pbmi->bmiColors[0].rgbRed = 0xff;
1013     pbmi->bmiColors[0].rgbGreen = 0x0;
1014     pbmi->bmiColors[0].rgbBlue = 0x0;
1015     pbmi->bmiColors[1].rgbRed = 0xfe;
1016     pbmi->bmiColors[1].rgbGreen = 0x0;
1017     pbmi->bmiColors[1].rgbBlue = 0x0;
1018
1019     mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1020     ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1021     old_bm = SelectObject(memdc, mono_ds);
1022
1023     /* black border, white interior */
1024     Rectangle(memdc, 0, 0, 10, 10);
1025     ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1026     ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1027
1028     /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1029
1030     pbmi->bmiColors[0].rgbRed = 0x0;
1031     pbmi->bmiColors[0].rgbGreen = 0x0;
1032     pbmi->bmiColors[0].rgbBlue = 0x0;
1033     pbmi->bmiColors[1].rgbRed = 0xff;
1034     pbmi->bmiColors[1].rgbGreen = 0xff;
1035     pbmi->bmiColors[1].rgbBlue = 0xff;
1036
1037     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1038     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1039
1040     /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
1041
1042     pbmi->bmiColors[0].rgbRed = 0xff;
1043     pbmi->bmiColors[0].rgbGreen = 0xff;
1044     pbmi->bmiColors[0].rgbBlue = 0xff;
1045     pbmi->bmiColors[1].rgbRed = 0x0;
1046     pbmi->bmiColors[1].rgbGreen = 0x0;
1047     pbmi->bmiColors[1].rgbBlue = 0x0;
1048
1049     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1050     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1051
1052     SelectObject(memdc, old_bm);
1053     DeleteObject(mono_ds);
1054
1055     DeleteDC(memdc);
1056     ReleaseDC(0, hdc);
1057 }
1058
1059 static void test_bitmap(void)
1060 {
1061     char buf[256], buf_cmp[256];
1062     HBITMAP hbmp, hbmp_old;
1063     HDC hdc;
1064     BITMAP bm;
1065     BITMAP bma[2];
1066     INT ret;
1067
1068     hdc = CreateCompatibleDC(0);
1069     assert(hdc != 0);
1070
1071     SetLastError(0xdeadbeef);
1072     hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1073     if (!hbmp)
1074     {
1075         ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1076            GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1077            "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1078     }
1079     else
1080         DeleteObject(hbmp);
1081
1082     SetLastError(0xdeadbeef);
1083     hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1084     if (!hbmp)
1085     {
1086         ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1087            GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1088            "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1089     }
1090     else
1091         DeleteObject(hbmp);
1092
1093     SetLastError(0xdeadbeef);
1094     hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1095     ok(!hbmp, "CreateBitmap should fail\n");
1096     if (!hbmp)
1097         ok(GetLastError() == ERROR_INVALID_PARAMETER,
1098            "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1099     else
1100         DeleteObject(hbmp);
1101
1102     hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1103     assert(hbmp != NULL);
1104
1105     ret = GetObject(hbmp, sizeof(bm), &bm);
1106     ok(ret == sizeof(bm), "wrong size %d\n", ret);
1107
1108     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1109     ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1110     ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1111     ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1112     ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1113     ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1114     ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1115
1116     assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1117     assert(sizeof(buf) == sizeof(buf_cmp));
1118
1119     ret = GetBitmapBits(hbmp, 0, NULL);
1120     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1121
1122     memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1123     memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1124
1125     memset(buf, 0xAA, sizeof(buf));
1126     ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1127     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1128     ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1129
1130     hbmp_old = SelectObject(hdc, hbmp);
1131
1132     ret = GetObject(hbmp, sizeof(bm), &bm);
1133     ok(ret == sizeof(bm), "wrong size %d\n", ret);
1134
1135     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1136     ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1137     ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1138     ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1139     ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1140     ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1141     ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1142
1143     memset(buf, 0xAA, sizeof(buf));
1144     ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1145     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1146     ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1147
1148     hbmp_old = SelectObject(hdc, hbmp_old);
1149     ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1150
1151     /* test various buffer sizes for GetObject */
1152     ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
1153     ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1154
1155     ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1156     ok(ret == 0, "%d != 0\n", ret);
1157
1158     ret = GetObject(hbmp, 0, &bm);
1159     ok(ret == 0, "%d != 0\n", ret);
1160
1161     ret = GetObject(hbmp, 1, &bm);
1162     ok(ret == 0, "%d != 0\n", ret);
1163
1164     DeleteObject(hbmp);
1165     DeleteDC(hdc);
1166 }
1167
1168 static void test_bmBits(void)
1169 {
1170     BYTE bits[4];
1171     HBITMAP hbmp;
1172     BITMAP bmp;
1173
1174     memset(bits, 0, sizeof(bits));
1175     hbmp = CreateBitmap(2, 2, 1, 4, bits);
1176     ok(hbmp != NULL, "CreateBitmap failed\n");
1177
1178     memset(&bmp, 0xFF, sizeof(bmp));
1179     ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1180        "GetObject failed or returned a wrong structure size\n");
1181     ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1182
1183     DeleteObject(hbmp);
1184 }
1185
1186 static void test_GetDIBits_selected_DIB(UINT bpp)
1187 {
1188     HBITMAP dib;
1189     BITMAPINFO * info;
1190     BITMAPINFO * info2;
1191     void * bits;
1192     void * bits2;
1193     UINT dib_size, dib32_size;
1194     DWORD pixel;
1195     HDC dib_dc, dc;
1196     HBITMAP old_bmp;
1197     BOOL equalContents;
1198     UINT i;
1199     int res;
1200
1201     /* Create a DIB section with a color table */
1202
1203     info  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD));
1204     info2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD));
1205     assert(info);
1206     assert(info2);
1207
1208     info->bmiHeader.biSize = sizeof(info->bmiHeader);
1209
1210     /* Choose width and height such that the row length (in bytes)
1211        is a multiple of 4 (makes things easier) */
1212     info->bmiHeader.biWidth = 32;
1213     info->bmiHeader.biHeight = 32;
1214     info->bmiHeader.biPlanes = 1;
1215     info->bmiHeader.biBitCount = bpp;
1216     info->bmiHeader.biCompression = BI_RGB;
1217
1218     for (i=0; i < (1u << bpp); i++)
1219     {
1220         BYTE c = i * (1 << (8 - bpp));
1221         info->bmiColors[i].rgbRed = c;
1222         info->bmiColors[i].rgbGreen = c;
1223         info->bmiColors[i].rgbBlue = c;
1224         info->bmiColors[i].rgbReserved = 0;
1225     }
1226
1227     dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1228     assert(dib);
1229     dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1230     dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1231
1232     /* Set the bits of the DIB section */
1233     for (i=0; i < dib_size; i++)
1234     {
1235         ((BYTE *)bits)[i] = i % 256;
1236     }
1237
1238     /* Select the DIB into a DC */
1239     dib_dc = CreateCompatibleDC(NULL);
1240     old_bmp = SelectObject(dib_dc, dib);
1241     dc = CreateCompatibleDC(NULL);
1242     bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
1243     assert(bits2);
1244
1245     /* Copy the DIB attributes but not the color table */
1246     memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1247
1248     res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1249     ok(res, "GetDIBits failed\n");
1250
1251     /* Compare the color table and the bits */
1252     equalContents = TRUE;
1253     for (i=0; i < (1u << bpp); i++)
1254     {
1255         if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed)
1256             || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen)
1257             || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue)
1258             || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved))
1259         {
1260             equalContents = FALSE;
1261             break;
1262         }
1263     }
1264     ok(equalContents, "GetDIBits with DIB selected in DC: Invalid DIB color table\n");
1265
1266     equalContents = TRUE;
1267     for (i=0; i < dib_size / sizeof(DWORD); i++)
1268     {
1269         if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i])
1270         {
1271             equalContents = FALSE;
1272             break;
1273         }
1274     }
1275     ok(equalContents, "GetDIBits with %d bpp DIB selected in DC: Invalid DIB bits\n",bpp);
1276
1277     /* Map into a 32bit-DIB */
1278     info2->bmiHeader.biBitCount = 32;
1279     res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1280     ok(res, "GetDIBits failed\n");
1281
1282     /* Check if last pixel was set */
1283     pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
1284     ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
1285
1286     HeapFree(GetProcessHeap(), 0, bits2);
1287     DeleteDC(dc);
1288
1289     SelectObject(dib_dc, old_bmp);
1290     DeleteDC(dib_dc);
1291     DeleteObject(dib);
1292
1293     HeapFree(GetProcessHeap(), 0, info2);
1294     HeapFree(GetProcessHeap(), 0, info);
1295 }
1296
1297 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1298 {
1299     HBITMAP ddb;
1300     BITMAPINFO * info;
1301     BITMAPINFO * info2;
1302     void * bits;
1303     void * bits2;
1304     HDC ddb_dc, dc;
1305     HBITMAP old_bmp;
1306     BOOL equalContents;
1307     UINT width, height;
1308     UINT bpp;
1309     UINT i, j;
1310     int res;
1311
1312     width = height = 16;
1313
1314     /* Create a DDB (device-dependent bitmap) */
1315     if (monochrome)
1316     {
1317         bpp = 1;
1318         ddb = CreateBitmap(width, height, 1, 1, NULL);
1319     }
1320     else
1321     {
1322         HDC screen_dc = GetDC(NULL);
1323         bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1324         ddb = CreateCompatibleBitmap(screen_dc, width, height);
1325         ReleaseDC(NULL, screen_dc);
1326     }
1327
1328     /* Set the pixels */
1329     ddb_dc = CreateCompatibleDC(NULL);
1330     old_bmp = SelectObject(ddb_dc, ddb);
1331     for (i = 0; i < width; i++)
1332     {
1333         for (j=0; j < height; j++)
1334         {
1335             BYTE c = (i * width + j) % 256;
1336             SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1337         }
1338     }
1339     SelectObject(ddb_dc, old_bmp);
1340
1341     info  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1342     info2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1343     assert(info);
1344     assert(info2);
1345
1346     info->bmiHeader.biSize = sizeof(info->bmiHeader);
1347     info->bmiHeader.biWidth = width;
1348     info->bmiHeader.biHeight = height;
1349     info->bmiHeader.biPlanes = 1;
1350     info->bmiHeader.biBitCount = bpp;
1351     info->bmiHeader.biCompression = BI_RGB;
1352
1353     dc = CreateCompatibleDC(NULL);
1354
1355     /* Fill in biSizeImage */
1356     GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1357     ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1358
1359     bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1360     bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1361     assert(bits);
1362     assert(bits2);
1363
1364     /* Get the bits */
1365     res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1366     ok(res, "GetDIBits failed\n");
1367
1368     /* Copy the DIB attributes but not the color table */
1369     memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1370
1371     /* Select the DDB into another DC */
1372     old_bmp = SelectObject(ddb_dc, ddb);
1373
1374     /* Get the bits */
1375     res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1376     ok(res, "GetDIBits failed\n");
1377
1378     /* Compare the color table and the bits */
1379     if (bpp <= 8)
1380     {
1381         equalContents = TRUE;
1382         for (i=0; i < (1u << bpp); i++)
1383         {
1384             if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed)
1385                 || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen)
1386                 || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue)
1387                 || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved))
1388             {
1389                 equalContents = FALSE;
1390                 break;
1391             }
1392         }
1393         ok(equalContents, "GetDIBits with DDB selected in DC: Got a different color table\n");
1394     }
1395
1396     equalContents = TRUE;
1397     for (i=0; i < info->bmiHeader.biSizeImage / sizeof(DWORD); i++)
1398     {
1399         if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i])
1400         {
1401             equalContents = FALSE;
1402         }
1403     }
1404     ok(equalContents, "GetDIBits with DDB selected in DC: Got different DIB bits\n");
1405
1406     /* Test the palette */
1407     equalContents = TRUE;
1408     if (info2->bmiHeader.biBitCount <= 8)
1409     {
1410         WORD *colors = (WORD*)info2->bmiColors;
1411
1412         /* Get the palette indices */
1413         res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1414         ok(res, "GetDIBits failed\n");
1415
1416         for (i=0;i < 1 << info->bmiHeader.biSizeImage; i++)
1417         {
1418             if (colors[i] != i)
1419             {
1420                 equalContents = FALSE;
1421                 break;
1422             }
1423         }
1424     }
1425
1426     ok(equalContents, "GetDIBits with DDB selected in DC: non 1:1 palette indices\n");
1427
1428     HeapFree(GetProcessHeap(), 0, bits2);
1429     HeapFree(GetProcessHeap(), 0, bits);
1430     DeleteDC(dc);
1431
1432     SelectObject(ddb_dc, old_bmp);
1433     DeleteDC(ddb_dc);
1434     DeleteObject(ddb);
1435
1436     HeapFree(GetProcessHeap(), 0, info2);
1437     HeapFree(GetProcessHeap(), 0, info);
1438 }
1439
1440 static void test_GetDIBits(void)
1441 {
1442     /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1443     static const BYTE bmp_bits_1[16 * 2] =
1444     {
1445         0xff,0xff, 0,0, 0xff,0xff, 0,0,
1446         0xff,0xff, 0,0, 0xff,0xff, 0,0,
1447         0xff,0xff, 0,0, 0xff,0xff, 0,0,
1448         0xff,0xff, 0,0, 0xff,0xff, 0,0
1449     };
1450     /* 4-bytes aligned 1-bit DIB data: 16x16 */
1451     static const BYTE dib_bits_1[16 * 4] =
1452     {
1453         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1454         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1455         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1456         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1457     };
1458     /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1459     static const BYTE bmp_bits_24[16 * 16*3] =
1460     {
1461         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1462         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         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1464         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         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1466         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         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1468         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         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1470         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         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1472         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         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1474         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         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1476         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         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1490         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1491         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1492         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1493     };
1494     /* 4-bytes aligned 24-bit DIB data: 16x16 */
1495     static const BYTE dib_bits_24[16 * 16*3] =
1496     {
1497         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1498         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         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1500         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         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1502         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         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1504         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         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1506         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         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1508         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         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1510         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         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1512         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         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1526         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1527         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1528         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1529     };
1530     HBITMAP hbmp;
1531     BITMAP bm;
1532     HDC hdc;
1533     int i, bytes, lines;
1534     BYTE buf[1024];
1535     char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1536     BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1537     PALETTEENTRY pal_ents[20];
1538
1539     hdc = GetDC(0);
1540
1541     /* 1-bit source bitmap data */
1542     hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1543     ok(hbmp != 0, "CreateBitmap failed\n");
1544
1545     memset(&bm, 0xAA, sizeof(bm));
1546     bytes = GetObject(hbmp, sizeof(bm), &bm);
1547     ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1548     ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1549     ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1550     ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1551     ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1552     ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1553     ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1554     ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1555
1556     bytes = GetBitmapBits(hbmp, 0, NULL);
1557     ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1558     bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1559     ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1560     ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1561
1562     /* retrieve 1-bit DIB data */
1563     memset(bi, 0, sizeof(*bi));
1564     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1565     bi->bmiHeader.biWidth = bm.bmWidth;
1566     bi->bmiHeader.biHeight = bm.bmHeight;
1567     bi->bmiHeader.biPlanes = 1;
1568     bi->bmiHeader.biBitCount = 1;
1569     bi->bmiHeader.biCompression = BI_RGB;
1570     bi->bmiHeader.biSizeImage = 0;
1571     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1572     SetLastError(0xdeadbeef);
1573     lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1574     ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1575     ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1576        broken(GetLastError() == 0xdeadbeef), /* winnt */
1577        "wrong error %u\n", GetLastError());
1578     ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1579
1580     memset(buf, 0xAA, sizeof(buf));
1581     SetLastError(0xdeadbeef);
1582     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1583     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1584        lines, bm.bmHeight, GetLastError());
1585     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1586
1587     /* the color table consists of black and white */
1588     ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1589        bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1590        "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1591        bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1592        bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1593     ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1594        bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1595        "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1596        bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1597        bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1598     for (i = 2; i < 256; i++)
1599     {
1600         ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1601            bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1602            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1603            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1604            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1605     }
1606
1607     /* returned bits are DWORD aligned and upside down */
1608     ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1609
1610     /* Test the palette indices */
1611     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1612     SetLastError(0xdeadbeef);
1613     lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1614     ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1615     ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1616     for (i = 2; i < 256; i++)
1617         ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[1]);
1618
1619     /* retrieve 24-bit DIB data */
1620     memset(bi, 0, sizeof(*bi));
1621     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1622     bi->bmiHeader.biWidth = bm.bmWidth;
1623     bi->bmiHeader.biHeight = bm.bmHeight;
1624     bi->bmiHeader.biPlanes = 1;
1625     bi->bmiHeader.biBitCount = 24;
1626     bi->bmiHeader.biCompression = BI_RGB;
1627     bi->bmiHeader.biSizeImage = 0;
1628     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1629     memset(buf, 0xAA, sizeof(buf));
1630     SetLastError(0xdeadbeef);
1631     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1632     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1633        lines, bm.bmHeight, GetLastError());
1634     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1635
1636     /* the color table doesn't exist for 24-bit images */
1637     for (i = 0; i < 256; i++)
1638     {
1639         ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1640            bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1641            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1642            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1643            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1644     }
1645
1646     /* returned bits are DWORD aligned and upside down */
1647     ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1648     DeleteObject(hbmp);
1649
1650     /* 24-bit source bitmap data */
1651     hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1652     ok(hbmp != 0, "CreateBitmap failed\n");
1653     SetLastError(0xdeadbeef);
1654     bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1655     lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1656     ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1657        lines, bm.bmHeight, GetLastError());
1658
1659     memset(&bm, 0xAA, sizeof(bm));
1660     bytes = GetObject(hbmp, sizeof(bm), &bm);
1661     ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1662     ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1663     ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1664     ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1665     ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1666     ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1667     ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1668     ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1669
1670     bytes = GetBitmapBits(hbmp, 0, NULL);
1671     ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
1672     bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1673     ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1674        bm.bmWidthBytes * bm.bmHeight, bytes);
1675
1676     /* retrieve 1-bit DIB data */
1677     memset(bi, 0, sizeof(*bi));
1678     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1679     bi->bmiHeader.biWidth = bm.bmWidth;
1680     bi->bmiHeader.biHeight = bm.bmHeight;
1681     bi->bmiHeader.biPlanes = 1;
1682     bi->bmiHeader.biBitCount = 1;
1683     bi->bmiHeader.biCompression = BI_RGB;
1684     bi->bmiHeader.biSizeImage = 0;
1685     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1686     memset(buf, 0xAA, sizeof(buf));
1687     SetLastError(0xdeadbeef);
1688     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1689     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1690        lines, bm.bmHeight, GetLastError());
1691     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1692
1693     /* the color table consists of black and white */
1694     ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1695        bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1696        "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1697        bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1698        bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1699     ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1700        bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1701        "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1702        bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1703        bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1704     for (i = 2; i < 256; i++)
1705     {
1706         ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1707            bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1708            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1709            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1710            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1711     }
1712
1713     /* returned bits are DWORD aligned and upside down */
1714     ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1715
1716     /* Test the palette indices */
1717     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1718     SetLastError(0xdeadbeef);
1719     lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1720     ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1721     ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1722     for (i = 2; i < 256; i++)
1723         ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[i]);
1724
1725     /* retrieve 4-bit DIB data */
1726     memset(bi, 0, sizeof(*bi));
1727     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1728     bi->bmiHeader.biWidth = bm.bmWidth;
1729     bi->bmiHeader.biHeight = bm.bmHeight;
1730     bi->bmiHeader.biPlanes = 1;
1731     bi->bmiHeader.biBitCount = 4;
1732     bi->bmiHeader.biCompression = BI_RGB;
1733     bi->bmiHeader.biSizeImage = 0;
1734     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1735     memset(buf, 0xAA, sizeof(buf));
1736     SetLastError(0xdeadbeef);
1737     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1738     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1739        lines, bm.bmHeight, GetLastError());
1740
1741     GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
1742
1743     for (i = 0; i < 16; i++)
1744     {
1745         RGBQUAD expect;
1746         int entry = i < 8 ? i : i + 4;
1747
1748         if(entry == 7) entry = 12;
1749         else if(entry == 12) entry = 7;
1750
1751         expect.rgbRed   = pal_ents[entry].peRed;
1752         expect.rgbGreen = pal_ents[entry].peGreen;
1753         expect.rgbBlue  = pal_ents[entry].peBlue;
1754         expect.rgbReserved = 0;
1755
1756         ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
1757            "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
1758            expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
1759            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1760            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1761     }
1762
1763     /* retrieve 8-bit DIB data */
1764     memset(bi, 0, sizeof(*bi));
1765     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1766     bi->bmiHeader.biWidth = bm.bmWidth;
1767     bi->bmiHeader.biHeight = bm.bmHeight;
1768     bi->bmiHeader.biPlanes = 1;
1769     bi->bmiHeader.biBitCount = 8;
1770     bi->bmiHeader.biCompression = BI_RGB;
1771     bi->bmiHeader.biSizeImage = 0;
1772     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1773     memset(buf, 0xAA, sizeof(buf));
1774     SetLastError(0xdeadbeef);
1775     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1776     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1777        lines, bm.bmHeight, GetLastError());
1778
1779     GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
1780
1781     for (i = 0; i < 256; i++)
1782     {
1783         RGBQUAD expect;
1784
1785         if (i < 10 || i >= 246)
1786         {
1787             int entry = i < 10 ? i : i - 236;
1788             expect.rgbRed   = pal_ents[entry].peRed;
1789             expect.rgbGreen = pal_ents[entry].peGreen;
1790             expect.rgbBlue  = pal_ents[entry].peBlue;
1791         }
1792         else
1793         {
1794             expect.rgbRed   = (i & 0x07) << 5;
1795             expect.rgbGreen = (i & 0x38) << 2;
1796             expect.rgbBlue  =  i & 0xc0;
1797         }
1798         expect.rgbReserved = 0;
1799
1800         ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
1801            "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
1802            expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
1803            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1804            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1805     }
1806
1807     /* retrieve 24-bit DIB data */
1808     memset(bi, 0, sizeof(*bi));
1809     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1810     bi->bmiHeader.biWidth = bm.bmWidth;
1811     bi->bmiHeader.biHeight = bm.bmHeight;
1812     bi->bmiHeader.biPlanes = 1;
1813     bi->bmiHeader.biBitCount = 24;
1814     bi->bmiHeader.biCompression = BI_RGB;
1815     bi->bmiHeader.biSizeImage = 0;
1816     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1817     memset(buf, 0xAA, sizeof(buf));
1818     SetLastError(0xdeadbeef);
1819     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1820     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1821        lines, bm.bmHeight, GetLastError());
1822     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1823
1824     /* the color table doesn't exist for 24-bit images */
1825     for (i = 0; i < 256; i++)
1826     {
1827         ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1828            bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1829            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1830            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1831            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1832     }
1833
1834     /* returned bits are DWORD aligned and upside down */
1835     ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1836     DeleteObject(hbmp);
1837
1838     ReleaseDC(0, hdc);
1839 }
1840
1841 static void test_GetDIBits_BI_BITFIELDS(void)
1842 {
1843     /* Try a screen resolution detection technique
1844      * from the September 1999 issue of Windows Developer's Journal
1845      * which seems to be in widespread use.
1846      * http://www.lesher.ws/highcolor.html
1847      * http://www.lesher.ws/vidfmt.c
1848      * It hinges on being able to retrieve the bitmaps
1849      * for the three primary colors in non-paletted 16 bit mode.
1850      */
1851     char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
1852     DWORD bits[32];
1853     LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
1854     DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
1855     HDC hdc;
1856     HBITMAP hbm;
1857     int ret;
1858     void *ptr;
1859
1860     memset(dibinfo, 0, sizeof(dibinfo_buf));
1861     dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1862
1863     hdc = GetDC(NULL);
1864     ok(hdc != NULL, "GetDC failed?\n");
1865     hbm = CreateCompatibleBitmap(hdc, 1, 1);
1866     ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
1867
1868     /* Call GetDIBits to fill in bmiHeader.  */
1869     ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1870     ok(ret == 1, "GetDIBits failed\n");
1871     if (dibinfo->bmiHeader.biBitCount > 8)
1872     {
1873         ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
1874             broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
1875             "compression is %u (%d bpp)\n", dibinfo->bmiHeader.biCompression, dibinfo->bmiHeader.biBitCount );
1876
1877         if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
1878         {
1879             ok( !bitmasks[0], "red mask is set\n" );
1880             ok( !bitmasks[1], "green mask is set\n" );
1881             ok( !bitmasks[2], "blue mask is set\n" );
1882
1883             /* test with NULL bits pointer and correct bpp */
1884             dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1885             ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1886             ok(ret == 1, "GetDIBits failed\n");
1887
1888             ok( bitmasks[0] != 0, "red mask is not set\n" );
1889             ok( bitmasks[1] != 0, "green mask is not set\n" );
1890             ok( bitmasks[2] != 0, "blue mask is not set\n" );
1891             ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1892
1893             /* test with valid bits pointer */
1894             memset(dibinfo, 0, sizeof(dibinfo_buf));
1895             dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1896             ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1897             ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1898             dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1899             ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
1900             ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1901
1902             ok( bitmasks[0] != 0, "red mask is not set\n" );
1903             ok( bitmasks[1] != 0, "green mask is not set\n" );
1904             ok( bitmasks[2] != 0, "blue mask is not set\n" );
1905             ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1906
1907             /* now with bits and 0 lines */
1908             memset(dibinfo, 0, sizeof(dibinfo_buf));
1909             dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1910             dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1911             SetLastError(0xdeadbeef);
1912             ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
1913             ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1914
1915             ok( !bitmasks[0], "red mask is set\n" );
1916             ok( !bitmasks[1], "green mask is set\n" );
1917             ok( !bitmasks[2], "blue mask is set\n" );
1918             ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1919
1920             memset(bitmasks, 0, 3*sizeof(DWORD));
1921             dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1922             ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
1923             ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1924
1925             ok( bitmasks[0] != 0, "red mask is not set\n" );
1926             ok( bitmasks[1] != 0, "green mask is not set\n" );
1927             ok( bitmasks[2] != 0, "blue mask is not set\n" );
1928             ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1929         }
1930     }
1931     else skip("bitmap in colortable mode, skipping BI_BITFIELDS tests\n");
1932
1933     DeleteObject(hbm);
1934
1935     /* same thing now with a 32-bpp DIB section */
1936
1937     dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1938     dibinfo->bmiHeader.biWidth = 1;
1939     dibinfo->bmiHeader.biHeight = 1;
1940     dibinfo->bmiHeader.biPlanes = 1;
1941     dibinfo->bmiHeader.biBitCount = 32;
1942     dibinfo->bmiHeader.biCompression = BI_RGB;
1943     dibinfo->bmiHeader.biSizeImage = 0;
1944     dibinfo->bmiHeader.biXPelsPerMeter = 0;
1945     dibinfo->bmiHeader.biYPelsPerMeter = 0;
1946     dibinfo->bmiHeader.biClrUsed = 0;
1947     dibinfo->bmiHeader.biClrImportant = 0;
1948     bitmasks[0] = 0x0000ff;
1949     bitmasks[1] = 0x00ff00;
1950     bitmasks[2] = 0xff0000;
1951     hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
1952     ok( hbm != 0, "failed to create bitmap\n" );
1953
1954     memset(dibinfo, 0, sizeof(dibinfo_buf));
1955     dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1956     ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
1957     ok(ret == 1, "GetDIBits failed\n");
1958     ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
1959
1960     ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
1961         broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
1962         "compression is %u\n", dibinfo->bmiHeader.biCompression );
1963     ok( !bitmasks[0], "red mask is set\n" );
1964     ok( !bitmasks[1], "green mask is set\n" );
1965     ok( !bitmasks[2], "blue mask is set\n" );
1966
1967     dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1968     ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
1969     ok(ret == 1, "GetDIBits failed\n");
1970     ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
1971     ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
1972         broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
1973         "compression is %u\n", dibinfo->bmiHeader.biCompression );
1974     if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
1975     {
1976         ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
1977         ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
1978         ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
1979     }
1980     ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1981
1982     DeleteObject(hbm);
1983
1984     dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1985     dibinfo->bmiHeader.biWidth = 1;
1986     dibinfo->bmiHeader.biHeight = 1;
1987     dibinfo->bmiHeader.biPlanes = 1;
1988     dibinfo->bmiHeader.biBitCount = 32;
1989     dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
1990     dibinfo->bmiHeader.biSizeImage = 0;
1991     dibinfo->bmiHeader.biXPelsPerMeter = 0;
1992     dibinfo->bmiHeader.biYPelsPerMeter = 0;
1993     dibinfo->bmiHeader.biClrUsed = 0;
1994     dibinfo->bmiHeader.biClrImportant = 0;
1995     bitmasks[0] = 0x0000ff;
1996     bitmasks[1] = 0x00ff00;
1997     bitmasks[2] = 0xff0000;
1998     hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
1999     ok( hbm != 0, "failed to create bitmap\n" );
2000
2001     if (hbm)
2002     {
2003         memset(dibinfo, 0, sizeof(dibinfo_buf));
2004         dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2005         ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2006         ok(ret == 1, "GetDIBits failed\n");
2007
2008         ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
2009             "compression is %u\n", dibinfo->bmiHeader.biCompression );
2010         ok( !bitmasks[0], "red mask is set\n" );
2011         ok( !bitmasks[1], "green mask is set\n" );
2012         ok( !bitmasks[2], "blue mask is set\n" );
2013
2014         dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2015         ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2016         ok(ret == 1, "GetDIBits failed\n");
2017         ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
2018         ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2019         ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
2020         ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2021
2022         DeleteObject(hbm);
2023     }
2024
2025     /* 24-bpp DIB sections don't have bitfields */
2026
2027     dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2028     dibinfo->bmiHeader.biWidth = 1;
2029     dibinfo->bmiHeader.biHeight = 1;
2030     dibinfo->bmiHeader.biPlanes = 1;
2031     dibinfo->bmiHeader.biBitCount = 24;
2032     dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2033     dibinfo->bmiHeader.biSizeImage = 0;
2034     dibinfo->bmiHeader.biXPelsPerMeter = 0;
2035     dibinfo->bmiHeader.biYPelsPerMeter = 0;
2036     dibinfo->bmiHeader.biClrUsed = 0;
2037     dibinfo->bmiHeader.biClrImportant = 0;
2038     hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2039     ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
2040     dibinfo->bmiHeader.biCompression = BI_RGB;
2041     hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2042     ok( hbm != 0, "failed to create bitmap\n" );
2043
2044     memset(dibinfo, 0, sizeof(dibinfo_buf));
2045     dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2046     ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2047     ok(ret == 1, "GetDIBits failed\n");
2048     ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2049
2050     ok( dibinfo->bmiHeader.biCompression == BI_RGB,
2051         "compression is %u\n", dibinfo->bmiHeader.biCompression );
2052     ok( !bitmasks[0], "red mask is set\n" );
2053     ok( !bitmasks[1], "green mask is set\n" );
2054     ok( !bitmasks[2], "blue mask is set\n" );
2055
2056     dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2057     ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2058     ok(ret == 1, "GetDIBits failed\n");
2059     ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2060     ok( !bitmasks[0], "red mask is set\n" );
2061     ok( !bitmasks[1], "green mask is set\n" );
2062     ok( !bitmasks[2], "blue mask is set\n" );
2063     ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2064
2065     DeleteObject(hbm);
2066     ReleaseDC(NULL, hdc);
2067 }
2068
2069 static void test_select_object(void)
2070 {
2071     HDC hdc;
2072     HBITMAP hbm, hbm_old;
2073     INT planes, bpp, i;
2074     DWORD depths[] = {8, 15, 16, 24, 32};
2075     BITMAP bm;
2076     DWORD bytes;
2077
2078     hdc = GetDC(0);
2079     ok(hdc != 0, "GetDC(0) failed\n");
2080     hbm = CreateCompatibleBitmap(hdc, 10, 10);
2081     ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2082
2083     hbm_old = SelectObject(hdc, hbm);
2084     ok(hbm_old == 0, "SelectObject should fail\n");
2085
2086     DeleteObject(hbm);
2087     ReleaseDC(0, hdc);
2088
2089     hdc = CreateCompatibleDC(0);
2090     ok(hdc != 0, "GetDC(0) failed\n");
2091     hbm = CreateCompatibleBitmap(hdc, 10, 10);
2092     ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2093
2094     hbm_old = SelectObject(hdc, hbm);
2095     ok(hbm_old != 0, "SelectObject failed\n");
2096     hbm_old = SelectObject(hdc, hbm_old);
2097     ok(hbm_old == hbm, "SelectObject failed\n");
2098
2099     DeleteObject(hbm);
2100
2101     /* test an 1-bpp bitmap */
2102     planes = GetDeviceCaps(hdc, PLANES);
2103     bpp = 1;
2104
2105     hbm = CreateBitmap(10, 10, planes, bpp, NULL);
2106     ok(hbm != 0, "CreateBitmap failed\n");
2107
2108     hbm_old = SelectObject(hdc, hbm);
2109     ok(hbm_old != 0, "SelectObject failed\n");
2110     hbm_old = SelectObject(hdc, hbm_old);
2111     ok(hbm_old == hbm, "SelectObject failed\n");
2112
2113     DeleteObject(hbm);
2114
2115     for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
2116         /* test a color bitmap to dc bpp matching */
2117         planes = GetDeviceCaps(hdc, PLANES);
2118         bpp = GetDeviceCaps(hdc, BITSPIXEL);
2119
2120         hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
2121         ok(hbm != 0, "CreateBitmap failed\n");
2122
2123         hbm_old = SelectObject(hdc, hbm);
2124         if(depths[i] == bpp ||
2125           (bpp == 16 && depths[i] == 15)        /* 16 and 15 bpp are compatible */
2126           ) {
2127             ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
2128             SelectObject(hdc, hbm_old);
2129         } else {
2130             ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
2131         }
2132
2133         memset(&bm, 0xAA, sizeof(bm));
2134         bytes = GetObject(hbm, sizeof(bm), &bm);
2135         ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2136         ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2137         ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
2138         ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
2139         ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2140         ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
2141         if(depths[i] == 15) {
2142             ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
2143         } else {
2144             ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2145         }
2146         ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2147
2148         DeleteObject(hbm);
2149     }
2150
2151     DeleteDC(hdc);
2152 }
2153
2154 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
2155 {
2156     INT ret;
2157     BITMAP bm;
2158
2159     ret = GetObjectType(hbmp);
2160     ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
2161
2162     ret = GetObject(hbmp, 0, 0);
2163     ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
2164
2165     memset(&bm, 0xDA, sizeof(bm));
2166     SetLastError(0xdeadbeef);
2167     ret = GetObject(hbmp, sizeof(bm), &bm);
2168     if (!ret) /* XP, only for curObj2 */ return;
2169     ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
2170     ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2171     ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2172     ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2173     ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2174     ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2175     ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2176     ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2177 }
2178
2179 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2180
2181 static void test_CreateBitmap(void)
2182 {
2183     BITMAP bmp;
2184     HDC screenDC = GetDC(0);
2185     HDC hdc = CreateCompatibleDC(screenDC);
2186     UINT i, expect = 0;
2187
2188     /* all of these are the stock monochrome bitmap */
2189     HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2190     HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2191     HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2192     HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2193     HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2194     HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2195
2196     /* these 2 are not the stock monochrome bitmap */
2197     HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2198     HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2199
2200     HBITMAP old1 = SelectObject(hdc, bm2);
2201     HBITMAP old2 = SelectObject(screenDC, bm3);
2202     SelectObject(hdc, old1);
2203     SelectObject(screenDC, old2);
2204
2205     ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2206        "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2207        bm, bm1, bm4, bm5, curObj1, old1);
2208     ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2209 todo_wine
2210     ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
2211     ok(old2 == 0, "old2 %p\n", old2);
2212
2213     test_mono_1x1_bmp(bm);
2214     test_mono_1x1_bmp(bm1);
2215     test_mono_1x1_bmp(bm2);
2216     test_mono_1x1_bmp(bm3);
2217     test_mono_1x1_bmp(bm4);
2218     test_mono_1x1_bmp(bm5);
2219     test_mono_1x1_bmp(old1);
2220     test_mono_1x1_bmp(curObj1);
2221
2222     DeleteObject(bm);
2223     DeleteObject(bm1);
2224     DeleteObject(bm2);
2225     DeleteObject(bm3);
2226     DeleteObject(bm4);
2227     DeleteObject(bm5);
2228
2229     DeleteDC(hdc);
2230     ReleaseDC(0, screenDC);
2231
2232     /* show that Windows ignores the provided bm.bmWidthBytes */
2233     bmp.bmType = 0;
2234     bmp.bmWidth = 1;
2235     bmp.bmHeight = 1;
2236     bmp.bmWidthBytes = 28;
2237     bmp.bmPlanes = 1;
2238     bmp.bmBitsPixel = 1;
2239     bmp.bmBits = NULL;
2240     bm = CreateBitmapIndirect(&bmp);
2241     ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2242     test_mono_1x1_bmp(bm);
2243     DeleteObject(bm);
2244
2245     /* Test how the bmBitsPixel field is treated */
2246     for(i = 1; i <= 33; i++) {
2247         bmp.bmType = 0;
2248         bmp.bmWidth = 1;
2249         bmp.bmHeight = 1;
2250         bmp.bmWidthBytes = 28;
2251         bmp.bmPlanes = 1;
2252         bmp.bmBitsPixel = i;
2253         bmp.bmBits = NULL;
2254         SetLastError(0xdeadbeef);
2255         bm = CreateBitmapIndirect(&bmp);
2256         if(i > 32) {
2257             DWORD error = GetLastError();
2258             ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
2259             ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2260             DeleteObject(bm);
2261             continue;
2262         }
2263         ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2264         GetObject(bm, sizeof(bmp), &bmp);
2265         if(i == 1) {
2266             expect = 1;
2267         } else if(i <= 4) {
2268             expect = 4;
2269         } else if(i <= 8) {
2270             expect = 8;
2271         } else if(i <= 16) {
2272             expect = 16;
2273         } else if(i <= 24) {
2274             expect = 24;
2275         } else if(i <= 32) {
2276             expect = 32;
2277         }
2278         ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2279            i, bmp.bmBitsPixel, expect);
2280         DeleteObject(bm);
2281     }
2282 }
2283
2284 static void test_bitmapinfoheadersize(void)
2285 {
2286     HBITMAP hdib;
2287     BITMAPINFO bmi;
2288     BITMAPCOREINFO bci;
2289     HDC hdc = GetDC(0);
2290
2291     memset(&bmi, 0, sizeof(BITMAPINFO));
2292     bmi.bmiHeader.biHeight = 100;
2293     bmi.bmiHeader.biWidth = 512;
2294     bmi.bmiHeader.biBitCount = 24;
2295     bmi.bmiHeader.biPlanes = 1;
2296
2297     bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2298
2299     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2300     ok(hdib == NULL, "CreateDIBSection succeeded\n");
2301
2302     bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2303
2304     SetLastError(0xdeadbeef);
2305     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2306     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2307     DeleteObject(hdib);
2308
2309     bmi.bmiHeader.biSize++;
2310
2311     SetLastError(0xdeadbeef);
2312     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2313     ok(hdib != NULL ||
2314        broken(!hdib), /* Win98, WinMe */
2315        "CreateDIBSection error %d\n", GetLastError());
2316     DeleteObject(hdib);
2317
2318     bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2319
2320     SetLastError(0xdeadbeef);
2321     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2322     ok(hdib != NULL ||
2323        broken(!hdib), /* Win98, WinMe */
2324        "CreateDIBSection error %d\n", GetLastError());
2325     DeleteObject(hdib);
2326
2327     bmi.bmiHeader.biSize++;
2328
2329     SetLastError(0xdeadbeef);
2330     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2331     ok(hdib != NULL ||
2332        broken(!hdib), /* Win98, WinMe */
2333        "CreateDIBSection error %d\n", GetLastError());
2334     DeleteObject(hdib);
2335
2336     bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2337
2338     SetLastError(0xdeadbeef);
2339     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2340     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2341     DeleteObject(hdib);
2342
2343     bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2344
2345     SetLastError(0xdeadbeef);
2346     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2347     ok(hdib != NULL ||
2348        broken(!hdib), /* Win95 */
2349        "CreateDIBSection error %d\n", GetLastError());
2350     DeleteObject(hdib);
2351
2352     memset(&bci, 0, sizeof(BITMAPCOREINFO));
2353     bci.bmciHeader.bcHeight = 100;
2354     bci.bmciHeader.bcWidth = 512;
2355     bci.bmciHeader.bcBitCount = 24;
2356     bci.bmciHeader.bcPlanes = 1;
2357
2358     bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2359
2360     hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2361     ok(hdib == NULL, "CreateDIBSection succeeded\n");
2362
2363     bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2364
2365     SetLastError(0xdeadbeef);
2366     hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2367     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2368     DeleteObject(hdib);
2369
2370     bci.bmciHeader.bcSize++;
2371
2372     hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2373     ok(hdib == NULL, "CreateDIBSection succeeded\n");
2374
2375     bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2376
2377     hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2378     ok(hdib == NULL, "CreateDIBSection succeeded\n");
2379
2380     ReleaseDC(0, hdc);
2381 }
2382
2383 static void test_get16dibits(void)
2384 {
2385     BYTE bits[4 * (16 / sizeof(BYTE))];
2386     HBITMAP hbmp;
2387     HDC screen_dc = GetDC(NULL);
2388     int ret;
2389     BITMAPINFO * info;
2390     int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2391     BYTE *p;
2392     int overwritten_bytes = 0;
2393
2394     memset(bits, 0, sizeof(bits));
2395     hbmp = CreateBitmap(2, 2, 1, 16, bits);
2396     ok(hbmp != NULL, "CreateBitmap failed\n");
2397
2398     info  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2399     assert(info);
2400
2401     memset(info, '!', info_len);
2402     memset(info, 0, sizeof(info->bmiHeader));
2403
2404     info->bmiHeader.biSize = sizeof(info->bmiHeader);
2405     info->bmiHeader.biWidth = 2;
2406     info->bmiHeader.biHeight = 2;
2407     info->bmiHeader.biPlanes = 1;
2408     info->bmiHeader.biCompression = BI_RGB;
2409
2410     ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2411     ok(ret != 0, "GetDIBits failed got %d\n", ret);
2412
2413     for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2414         if (*p != '!')
2415             overwritten_bytes++;
2416     ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2417
2418     HeapFree(GetProcessHeap(), 0, info);
2419     DeleteObject(hbmp);
2420     ReleaseDC(NULL, screen_dc);
2421 }
2422
2423 static BOOL compare_buffers_no_alpha(UINT32 *a, UINT32 *b, int length)
2424 {
2425     int i;
2426     for(i = 0; i < length; i++)
2427         if((a[i] & 0x00FFFFFF) != (b[i] & 0x00FFFFFF))
2428             return FALSE;
2429     return TRUE;
2430 }
2431
2432 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2433                                DWORD dwRop, UINT32 expected, int line)
2434 {
2435     *srcBuffer = 0xFEDCBA98;
2436     *dstBuffer = 0x89ABCDEF;
2437     Rectangle(hdcSrc, 0, 0, 1, 1);  /* A null operation to ensure dibs are coerced to X11 */
2438     BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
2439     ok(expected == *dstBuffer,
2440         "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2441         dwRop, expected, *dstBuffer, line);
2442 }
2443
2444 static void test_BitBlt(void)
2445 {
2446     HBITMAP bmpDst, bmpSrc;
2447     HBITMAP oldDst, oldSrc;
2448     HDC hdcScreen, hdcDst, hdcSrc;
2449     UINT32 *dstBuffer, *srcBuffer;
2450     HBRUSH hBrush, hOldBrush;
2451     BITMAPINFO bitmapInfo;
2452
2453     memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2454     bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2455     bitmapInfo.bmiHeader.biWidth = 1;
2456     bitmapInfo.bmiHeader.biHeight = 1;
2457     bitmapInfo.bmiHeader.biPlanes = 1;
2458     bitmapInfo.bmiHeader.biBitCount = 32;
2459     bitmapInfo.bmiHeader.biCompression = BI_RGB;
2460     bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2461
2462     hdcScreen = CreateCompatibleDC(0);
2463     hdcDst = CreateCompatibleDC(hdcScreen);
2464     hdcSrc = CreateCompatibleDC(hdcDst);
2465
2466     /* Setup the destination dib section */
2467     bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
2468         NULL, 0);
2469     oldDst = SelectObject(hdcDst, bmpDst);
2470
2471     hBrush = CreateSolidBrush(0x012345678);
2472     hOldBrush = SelectObject(hdcDst, hBrush);
2473
2474     /* Setup the source dib section */
2475     bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
2476         NULL, 0);
2477     oldSrc = SelectObject(hdcSrc, bmpSrc);
2478
2479     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2480     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2481     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2482     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2483     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2484     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2485     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2486     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2487     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2488     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2489     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2490     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2491     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2492     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2493     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2494
2495     /* Tidy up */
2496     SelectObject(hdcSrc, oldSrc);
2497     DeleteObject(bmpSrc);
2498     DeleteDC(hdcSrc);
2499
2500     SelectObject(hdcDst, hOldBrush);
2501     DeleteObject(hBrush);
2502     SelectObject(hdcDst, oldDst);
2503     DeleteObject(bmpDst);
2504     DeleteDC(hdcDst);
2505
2506
2507     DeleteDC(hdcScreen);
2508 }
2509
2510 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2511                                    DWORD dwRop, UINT32 expected, int line)
2512 {
2513     *srcBuffer = 0xFEDCBA98;
2514     *dstBuffer = 0x89ABCDEF;
2515     StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
2516     ok(expected == *dstBuffer,
2517         "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2518         dwRop, expected, *dstBuffer, line);
2519 }
2520
2521 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2522                                      int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2523                                      int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2524                                      UINT32 expected[4], UINT32 legacy_expected[4], int line)
2525 {
2526     memset(dstBuffer, 0, 16);
2527     StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2528                hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
2529     ok(memcmp(dstBuffer, expected, 16) == 0 ||
2530         broken(compare_buffers_no_alpha(dstBuffer, legacy_expected, 4)),
2531         "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2532         "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2533         expected[0], expected[1], expected[2], expected[3],
2534         dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2535         nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2536         nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2537 }
2538
2539 static void test_StretchBlt(void)
2540 {
2541     HBITMAP bmpDst, bmpSrc;
2542     HBITMAP oldDst, oldSrc;
2543     HDC hdcScreen, hdcDst, hdcSrc;
2544     UINT32 *dstBuffer, *srcBuffer;
2545     HBRUSH hBrush, hOldBrush;
2546     BITMAPINFO biDst, biSrc;
2547     UINT32 expected[4], legacy_expected[4];
2548
2549     memset(&biDst, 0, sizeof(BITMAPINFO));
2550     biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2551     biDst.bmiHeader.biWidth = 2;
2552     biDst.bmiHeader.biHeight = -2;
2553     biDst.bmiHeader.biPlanes = 1;
2554     biDst.bmiHeader.biBitCount = 32;
2555     biDst.bmiHeader.biCompression = BI_RGB;
2556     memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
2557
2558     hdcScreen = CreateCompatibleDC(0);
2559     hdcDst = CreateCompatibleDC(hdcScreen);
2560     hdcSrc = CreateCompatibleDC(hdcDst);
2561
2562     /* Pixel Tests */
2563     bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2564         NULL, 0);
2565     oldDst = SelectObject(hdcDst, bmpDst);
2566
2567     bmpSrc = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&srcBuffer,
2568         NULL, 0);
2569     oldSrc = SelectObject(hdcSrc, bmpSrc);
2570
2571     hBrush = CreateSolidBrush(0x012345678);
2572     hOldBrush = SelectObject(hdcDst, hBrush);
2573
2574     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2575     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2576     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2577     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2578     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2579     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2580     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2581     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2582     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2583     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2584     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2585     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2586     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2587     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2588     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2589
2590     SelectObject(hdcDst, hOldBrush);
2591     DeleteObject(hBrush);
2592
2593     /* Top-down to top-down tests */
2594     srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2595     srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
2596
2597     expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2598     expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2599     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2600                              0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2601
2602     expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2603     expected[2] = 0x00000000, expected[3] = 0x00000000;
2604     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2605                              0, 0, 1, 1, 0, 0, 1, 1, expected, expected, __LINE__);
2606
2607     expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
2608     expected[2] = 0xCAFED00D, expected[3] = 0xCAFED00D;
2609     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2610                              0, 0, 2, 2, 0, 0, 1, 1, expected, expected, __LINE__);
2611
2612     expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2613     expected[2] = 0x00000000, expected[3] = 0x00000000;
2614     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2615                              0, 0, 1, 1, 0, 0, 2, 2, expected, expected, __LINE__);
2616
2617     expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2618     expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2619     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2620                              0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2621
2622     expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2623     expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2624     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2625                              1, 1, -2, -2, 0, 0, 2, 2, expected, expected, __LINE__);
2626
2627     /* This result seems broken. One might expect the following result:
2628      * 0xCAFED00D 0xFEEDFACE
2629      * 0xFEDCBA98 0x76543210
2630      */
2631     expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2632     expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2633     legacy_expected[0] = 0xCAFED00D, legacy_expected[1] = 0x00000000;
2634     legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
2635     todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2636                                        1, 1, -2, -2, 1, 1, -2, -2, expected,
2637                                        legacy_expected, __LINE__);
2638
2639     expected[0] = 0x00000000, expected[1] = 0x00000000;
2640     expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
2641     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2642                              1, 1, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2643
2644     SelectObject(hdcDst, oldDst);
2645     DeleteObject(bmpDst);
2646
2647     /* Top-down to bottom-up tests */
2648     biDst.bmiHeader.biHeight = 2;
2649     bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2650         NULL, 0);
2651     oldDst = SelectObject(hdcDst, bmpDst);
2652
2653     expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2654     expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
2655     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2656                              0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2657
2658     expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2659     expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2660     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2661                              0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2662
2663     SelectObject(hdcSrc, oldSrc);
2664     DeleteObject(bmpSrc);
2665
2666     /* Bottom-up to bottom-up tests */
2667     biSrc.bmiHeader.biHeight = 2;
2668     bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2669         NULL, 0);
2670     srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2671     srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
2672     oldSrc = SelectObject(hdcSrc, bmpSrc);
2673
2674     expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2675     expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2676     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2677                              0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2678
2679     expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2680     expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2681     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2682                              0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2683
2684     SelectObject(hdcDst, oldDst);
2685     DeleteObject(bmpDst);
2686
2687     /* Bottom-up to top-down tests */
2688     biDst.bmiHeader.biHeight = -2;
2689     bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2690         NULL, 0);
2691     oldDst = SelectObject(hdcDst, bmpDst);
2692
2693     expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2694     expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
2695     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2696                              0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2697
2698     expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2699     expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2700     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2701                              0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2702
2703     /* Tidy up */
2704     SelectObject(hdcSrc, oldSrc);
2705     DeleteObject(bmpSrc);
2706     DeleteDC(hdcSrc);
2707
2708     SelectObject(hdcDst, oldDst);
2709     DeleteObject(bmpDst);
2710     DeleteDC(hdcDst);
2711
2712     DeleteDC(hdcScreen);
2713 }
2714
2715 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
2716                                       DWORD dwRop, UINT32 expected, int line)
2717 {
2718     const UINT32 buffer[2] = { 0xFEDCBA98, 0 };
2719     BITMAPINFO bitmapInfo;
2720
2721     memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2722     bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2723     bitmapInfo.bmiHeader.biWidth = 2;
2724     bitmapInfo.bmiHeader.biHeight = 1;
2725     bitmapInfo.bmiHeader.biPlanes = 1;
2726     bitmapInfo.bmiHeader.biBitCount = 32;
2727     bitmapInfo.bmiHeader.biCompression = BI_RGB;
2728     bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer);
2729
2730     *dstBuffer = 0x89ABCDEF;
2731
2732     StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop);
2733     ok(expected == *dstBuffer,
2734         "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2735         dwRop, expected, *dstBuffer, line);
2736 }
2737
2738 static void check_StretchDIBits_stretch(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
2739                                         int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2740                                         int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2741                                         UINT32 expected[4], UINT32 legacy_expected[4], int line)
2742 {
2743     BITMAPINFO bitmapInfo;
2744
2745     memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2746     bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2747     bitmapInfo.bmiHeader.biWidth = 2;
2748     bitmapInfo.bmiHeader.biHeight = -2;
2749     bitmapInfo.bmiHeader.biPlanes = 1;
2750     bitmapInfo.bmiHeader.biBitCount = 32;
2751     bitmapInfo.bmiHeader.biCompression = BI_RGB;
2752
2753     memset(dstBuffer, 0, 16);
2754     StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2755                   nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2756                   srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
2757     ok(memcmp(dstBuffer, expected, 16) == 0,
2758         "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2759         "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2760         expected[0], expected[1], expected[2], expected[3],
2761         dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2762         nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2763         nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2764 }
2765
2766 static void test_StretchDIBits(void)
2767 {
2768     HBITMAP bmpDst;
2769     HBITMAP oldDst;
2770     HDC hdcScreen, hdcDst;
2771     UINT32 *dstBuffer, srcBuffer[4];
2772     HBRUSH hBrush, hOldBrush;
2773     BITMAPINFO biDst;
2774     UINT32 expected[4], legacy_expected[4];
2775
2776     memset(&biDst, 0, sizeof(BITMAPINFO));
2777     biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2778     biDst.bmiHeader.biWidth = 2;
2779     biDst.bmiHeader.biHeight = -2;
2780     biDst.bmiHeader.biPlanes = 1;
2781     biDst.bmiHeader.biBitCount = 32;
2782     biDst.bmiHeader.biCompression = BI_RGB;
2783
2784     hdcScreen = CreateCompatibleDC(0);
2785     hdcDst = CreateCompatibleDC(hdcScreen);
2786
2787     /* Pixel Tests */
2788     bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2789         NULL, 0);
2790     oldDst = SelectObject(hdcDst, bmpDst);
2791
2792     hBrush = CreateSolidBrush(0x012345678);
2793     hOldBrush = SelectObject(hdcDst, hBrush);
2794
2795     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2796     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2797     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2798     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2799     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2800     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2801     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2802     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2803     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2804     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2805     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2806     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2807     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2808     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2809     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2810
2811     SelectObject(hdcDst, hOldBrush);
2812     DeleteObject(hBrush);
2813
2814     /* Top-down destination tests */
2815     srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2816     srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
2817
2818     expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2819     expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2820     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2821                                 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2822
2823     expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2824     expected[2] = 0x00000000, expected[3] = 0x00000000;
2825     legacy_expected[0] = 0xFEDCBA98, legacy_expected[1] = 0x00000000;
2826     legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
2827     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2828                                 0, 0, 1, 1, 0, 0, 1, 1, expected, legacy_expected, __LINE__);
2829
2830     expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
2831     expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
2832     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2833                                 0, 0, 2, 2, 0, 0, 1, 1, expected, expected, __LINE__);
2834
2835     expected[0] = 0x42441000, expected[1] = 0x00000000;
2836     expected[2] = 0x00000000, expected[3] = 0x00000000;
2837     legacy_expected[0] = 0x00543210, legacy_expected[1] = 0x00000000;
2838     legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
2839     todo_wine check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2840                                 0, 0, 1, 1, 0, 0, 2, 2, expected, legacy_expected, __LINE__);
2841
2842     expected[0] = 0x00000000, expected[1] = 0x00000000;
2843     expected[2] = 0x00000000, expected[3] = 0x00000000;
2844     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2845                                 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2846
2847     expected[0] = 0x00000000, expected[1] = 0x00000000;
2848     expected[2] = 0x00000000, expected[3] = 0x00000000;
2849     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2850                                 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2851
2852     expected[0] = 0x00000000, expected[1] = 0x00000000;
2853     expected[2] = 0x00000000, expected[3] = 0x00000000;
2854     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2855                                 1, 1, -2, -2, 1, 1, -2, -2, expected, expected, __LINE__);
2856
2857     expected[0] = 0x00000000, expected[1] = 0x00000000;
2858     expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
2859     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2860                                 1, 1, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2861
2862     SelectObject(hdcDst, oldDst);
2863     DeleteObject(bmpDst);
2864
2865     /* Bottom up destination tests */
2866     biDst.bmiHeader.biHeight = 2;
2867     bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2868         NULL, 0);
2869     oldDst = SelectObject(hdcDst, bmpDst);
2870
2871     expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2872     expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
2873     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2874                                 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2875
2876     /* Tidy up */
2877     SelectObject(hdcDst, oldDst);
2878     DeleteObject(bmpDst);
2879     DeleteDC(hdcDst);
2880
2881     DeleteDC(hdcScreen);
2882 }
2883
2884 static void test_GdiAlphaBlend(void)
2885 {
2886     /* test out-of-bound parameters for GdiAlphaBlend */
2887     HDC hdcNull;
2888
2889     HDC hdcDst;
2890     HBITMAP bmpDst;
2891     HBITMAP oldDst;
2892
2893     BITMAPINFO bmi;
2894     HDC hdcSrc;
2895     HBITMAP bmpSrc;
2896     HBITMAP oldSrc;
2897     LPVOID bits;
2898
2899     BLENDFUNCTION blend;
2900
2901     if (!pGdiAlphaBlend)
2902     {
2903         win_skip("GdiAlphaBlend() is not implemented\n");
2904         return;
2905     }
2906
2907     hdcNull = GetDC(NULL);
2908     hdcDst = CreateCompatibleDC(hdcNull);
2909     bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
2910     hdcSrc = CreateCompatibleDC(hdcNull);
2911
2912     memset(&bmi, 0, sizeof(bmi));  /* as of Wine 0.9.44 we require the src to be a DIB section */
2913     bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
2914     bmi.bmiHeader.biHeight = 20;
2915     bmi.bmiHeader.biWidth = 20;
2916     bmi.bmiHeader.biBitCount = 32;
2917     bmi.bmiHeader.biPlanes = 1;
2918     bmi.bmiHeader.biCompression = BI_RGB;
2919     bmpSrc = CreateDIBSection(hdcDst, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
2920     ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
2921
2922     oldDst = SelectObject(hdcDst, bmpDst);
2923     oldSrc = SelectObject(hdcSrc, bmpSrc);
2924
2925     blend.BlendOp = AC_SRC_OVER;
2926     blend.BlendFlags = 0;
2927     blend.SourceConstantAlpha = 128;
2928     blend.AlphaFormat = 0;
2929
2930     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend), TRUE, BOOL, "%d");
2931     SetLastError(0xdeadbeef);
2932     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), FALSE, BOOL, "%d");
2933     expect_eq(GetLastError(), ERROR_INVALID_PARAMETER, int, "%d");
2934     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), FALSE, BOOL, "%d");
2935     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend), FALSE, BOOL, "%d");
2936     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
2937     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
2938
2939     SetWindowOrgEx(hdcSrc, -10, -10, NULL);
2940     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), TRUE, BOOL, "%d");
2941     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), TRUE, BOOL, "%d");
2942     SetMapMode(hdcSrc, MM_ANISOTROPIC);
2943     ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
2944     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend), TRUE, BOOL, "%d");
2945     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend), TRUE, BOOL, "%d");
2946
2947     SetLastError(0xdeadbeef);
2948     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend), FALSE, BOOL, "%d");
2949     expect_eq(GetLastError(), 0xdeadbeef, int, "%d");
2950
2951     SelectObject(hdcDst, oldDst);
2952     SelectObject(hdcSrc, oldSrc);
2953     DeleteObject(bmpSrc);
2954     DeleteObject(bmpDst);
2955     DeleteDC(hdcDst);
2956     DeleteDC(hdcSrc);
2957
2958     ReleaseDC(NULL, hdcNull);
2959
2960 }
2961
2962 static void test_clipping(void)
2963 {
2964     HBITMAP bmpDst;
2965     HBITMAP bmpSrc;
2966     HRGN hRgn;
2967     LPVOID bits;
2968     BOOL result;
2969
2970     HDC hdcDst = CreateCompatibleDC( NULL );
2971     HDC hdcSrc = CreateCompatibleDC( NULL );
2972
2973     BITMAPINFO bmpinfo={{0}};
2974     bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2975     bmpinfo.bmiHeader.biWidth = 100;
2976     bmpinfo.bmiHeader.biHeight = 100;
2977     bmpinfo.bmiHeader.biPlanes = 1;
2978     bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
2979     bmpinfo.bmiHeader.biCompression = BI_RGB;
2980
2981     bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
2982     ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
2983     SelectObject( hdcDst, bmpDst );
2984
2985     bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
2986     ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
2987     SelectObject( hdcSrc, bmpSrc );
2988
2989     result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
2990     ok(result, "BitBlt failed\n");
2991
2992     hRgn = CreateRectRgn( 0,0,0,0 );
2993     SelectClipRgn( hdcDst, hRgn );
2994
2995     result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
2996     ok(result, "BitBlt failed\n");
2997
2998     DeleteObject( bmpDst );
2999     DeleteObject( bmpSrc );
3000     DeleteObject( hRgn );
3001     DeleteDC( hdcDst );
3002     DeleteDC( hdcSrc );
3003 }
3004
3005 static void test_32bit_bitmap_blt(void)
3006 {
3007     BITMAPINFO biDst;
3008     HBITMAP bmpSrc, bmpDst;
3009     HBITMAP oldSrc, oldDst;
3010     HDC hdcSrc, hdcDst, hdcScreen;
3011     UINT32 *dstBuffer;
3012     DWORD colorSrc = 0x11223344;
3013
3014     memset(&biDst, 0, sizeof(BITMAPINFO));
3015     biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3016     biDst.bmiHeader.biWidth = 2;
3017     biDst.bmiHeader.biHeight = -2;
3018     biDst.bmiHeader.biPlanes = 1;
3019     biDst.bmiHeader.biBitCount = 32;
3020     biDst.bmiHeader.biCompression = BI_RGB;
3021
3022     hdcScreen = CreateCompatibleDC(0);
3023     if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3024     {
3025         DeleteDC(hdcScreen);
3026         trace("Skipping 32-bit DDB test\n");
3027         return;
3028     }
3029
3030     hdcSrc = CreateCompatibleDC(hdcScreen);
3031     bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3032     oldSrc = SelectObject(hdcSrc, bmpSrc);
3033
3034     hdcDst = CreateCompatibleDC(hdcScreen);
3035     bmpDst = CreateDIBSection(hdcDst, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3036     oldDst = SelectObject(hdcDst, bmpDst);
3037
3038     StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3039     ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3040
3041     /* Tidy up */
3042     SelectObject(hdcDst, oldDst);
3043     DeleteObject(bmpDst);
3044     DeleteDC(hdcDst);
3045
3046     SelectObject(hdcSrc, oldSrc);
3047     DeleteObject(bmpSrc);
3048     DeleteDC(hdcSrc);
3049
3050     DeleteDC(hdcScreen);
3051 }
3052
3053 /*
3054  * Used by test_GetDIBits_top_down to create the bitmap to test against.
3055  */
3056 static void setup_picture(char *picture, int bpp)
3057 {
3058     int i;
3059
3060     switch(bpp)
3061     {
3062         case 16:
3063         case 32:
3064             /*Set the first byte in each pixel to the index of that pixel.*/
3065             for (i = 0; i < 4; i++)
3066                 picture[i * (bpp / 8)] = i;
3067             break;
3068         case 24:
3069             picture[0] = 0;
3070             picture[3] = 1;
3071             /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
3072             picture[8] = 2;
3073             picture[11] = 3;
3074             break;
3075     }
3076 }
3077
3078 static void test_GetDIBits_top_down(int bpp)
3079 {
3080     BITMAPINFO bi;
3081     HBITMAP bmptb, bmpbt;
3082     HDC hdc;
3083     int pictureOut[4];
3084     int *picture;
3085     int statusCode;
3086
3087     bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
3088     bi.bmiHeader.biWidth=2;
3089     bi.bmiHeader.biHeight=2;
3090     bi.bmiHeader.biPlanes=1;
3091     bi.bmiHeader.biBitCount=bpp;
3092     bi.bmiHeader.biCompression=BI_RGB;
3093
3094     /*Get the device context for the screen.*/
3095     hdc = GetDC(NULL);
3096     ok(hdc != NULL, "Could not get a handle to a device context.\n");
3097
3098     /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
3099     bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3100     ok(bmpbt != NULL, "Could not create a DIB section.\n");
3101     /*Now that we have a pointer to the pixels, we write to them.*/
3102     setup_picture((char*)picture, bpp);
3103     /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
3104     bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
3105     bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3106     ok(bmptb != NULL, "Could not create a DIB section.\n");
3107     /*Write to this top to bottom bitmap.*/
3108     setup_picture((char*)picture, bpp);
3109
3110     bi.bmiHeader.biWidth = 1;
3111
3112     bi.bmiHeader.biHeight = 2;
3113     statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3114     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3115     /*Check the first byte of the pixel.*/
3116     ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3117     statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3118     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3119     ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3120     /*Check second scanline.*/
3121     statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3122     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3123     ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3124     statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3125     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3126     ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3127     /*Check both scanlines.*/
3128     statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3129     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3130     ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3131     ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3132     statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3133     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3134     ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3135     ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3136
3137     /*Make destination bitmap top-down.*/
3138     bi.bmiHeader.biHeight = -2;
3139     statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3140     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3141     ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3142     statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3143     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3144     ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3145     /*Check second scanline.*/
3146     statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3147     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3148     ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3149     statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3150     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3151     ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3152     /*Check both scanlines.*/
3153     statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3154     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3155     ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3156     ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3157     statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3158     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3159     ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3160     ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3161
3162     DeleteObject(bmpbt);
3163     DeleteObject(bmptb);
3164 }
3165
3166 static void test_GetSetDIBits_rtl(void)
3167 {
3168     HDC hdc, hdc_mem;
3169     HBITMAP bitmap, orig_bitmap;
3170     BITMAPINFO info;
3171     int ret;
3172     DWORD bits_1[8 * 8], bits_2[8 * 8];
3173
3174     if(!pSetLayout)
3175     {
3176         win_skip("Don't have SetLayout\n");
3177         return;
3178     }
3179
3180     hdc = GetDC( NULL );
3181     hdc_mem = CreateCompatibleDC( hdc );
3182     pSetLayout( hdc_mem, LAYOUT_LTR );
3183
3184     bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
3185     orig_bitmap = SelectObject( hdc_mem, bitmap );
3186     SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
3187     SelectObject( hdc_mem, orig_bitmap );
3188
3189     info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3190     info.bmiHeader.biWidth = 8;
3191     info.bmiHeader.biHeight = 8;
3192     info.bmiHeader.biPlanes = 1;
3193     info.bmiHeader.biBitCount = 32;
3194     info.bmiHeader.biCompression = BI_RGB;
3195
3196     /* First show that GetDIBits ignores the layout mode. */
3197
3198     ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3199     ok(ret == 8, "got %d\n", ret);
3200     ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
3201
3202     pSetLayout( hdc_mem, LAYOUT_RTL );
3203
3204     ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3205     ok(ret == 8, "got %d\n", ret);
3206
3207     ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3208
3209     /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
3210        followed by a GetDIBits and show that the bits remain unchanged. */
3211
3212     pSetLayout( hdc_mem, LAYOUT_LTR );
3213
3214     ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3215     ok(ret == 8, "got %d\n", ret);
3216     ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3217     ok(ret == 8, "got %d\n", ret);
3218     ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3219
3220     pSetLayout( hdc_mem, LAYOUT_RTL );
3221
3222     ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3223     ok(ret == 8, "got %d\n", ret);
3224     ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3225     ok(ret == 8, "got %d\n", ret);
3226     ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3227
3228     DeleteObject( bitmap );
3229     DeleteDC( hdc_mem );
3230     ReleaseDC( NULL, hdc );
3231 }
3232
3233 static void test_GetDIBits_scanlines(void)
3234 {
3235     char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3236     BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3237     DWORD *dib_bits;
3238     HDC hdc = GetDC( NULL );
3239     HBITMAP dib;
3240     DWORD data[128], inverted_bits[64];
3241     int i, ret;
3242
3243     memset( info, 0, sizeof(bmi_buf) );
3244
3245     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
3246     info->bmiHeader.biWidth       = 8;
3247     info->bmiHeader.biHeight      = 8;
3248     info->bmiHeader.biPlanes      = 1;
3249     info->bmiHeader.biBitCount    = 32;
3250     info->bmiHeader.biCompression = BI_RGB;
3251
3252     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3253
3254     for (i = 0; i < 64; i++)
3255     {
3256         dib_bits[i] = i;
3257         inverted_bits[56 - (i & ~7) + (i & 7)] = i;
3258     }
3259
3260     /* b-u -> b-u */
3261
3262     memset( data, 0xaa, sizeof(data) );
3263
3264     ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3265     ok( ret == 8, "got %d\n", ret );
3266     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3267     memset( data, 0xaa, sizeof(data) );
3268
3269     ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3270     ok( ret == 5, "got %d\n", ret );
3271     ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
3272     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3273     memset( data, 0xaa, sizeof(data) );
3274
3275     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3276     ok( ret == 7, "got %d\n", ret );
3277     ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
3278     for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3279     memset( data, 0xaa, sizeof(data) );
3280
3281     ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3282     ok( ret == 1, "got %d\n", ret );
3283     for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3284     memset( data, 0xaa, sizeof(data) );
3285
3286     info->bmiHeader.biHeight = 16;
3287     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3288     ok( ret == 5, "got %d\n", ret );
3289     for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3290     ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
3291     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3292     memset( data, 0xaa, sizeof(data) );
3293
3294     ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3295     ok( ret == 6, "got %d\n", ret );
3296     for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3297     ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
3298     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3299     memset( data, 0xaa, sizeof(data) );
3300
3301     ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3302     ok( ret == 0, "got %d\n", ret );
3303     for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3304     for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3305     memset( data, 0xaa, sizeof(data) );
3306
3307     info->bmiHeader.biHeight = 5;
3308     ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3309     ok( ret == 2, "got %d\n", ret );
3310     ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
3311     for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3312     memset( data, 0xaa, sizeof(data) );
3313
3314     /* b-u -> t-d */
3315
3316     info->bmiHeader.biHeight = -8;
3317     ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3318     ok( ret == 8, "got %d\n", ret );
3319     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3320     memset( data, 0xaa, sizeof(data) );
3321
3322     ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3323     ok( ret == 5, "got %d\n", ret );
3324     ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
3325     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3326     memset( data, 0xaa, sizeof(data) );
3327
3328     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3329     ok( ret == 7, "got %d\n", ret );
3330     ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3331     for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3332     memset( data, 0xaa, sizeof(data) );
3333
3334     ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3335     ok( ret == 4, "got %d\n", ret );
3336     ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
3337     for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3338     memset( data, 0xaa, sizeof(data) );
3339
3340     ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3341     ok( ret == 5, "got %d\n", ret );
3342     ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3343     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3344     memset( data, 0xaa, sizeof(data) );
3345
3346     ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3347     ok( ret == 5, "got %d\n", ret );
3348     ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3349     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3350     memset( data, 0xaa, sizeof(data) );
3351
3352     info->bmiHeader.biHeight = -16;
3353     ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3354     ok( ret == 8, "got %d\n", ret );
3355     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3356     for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3357     memset( data, 0xaa, sizeof(data) );
3358
3359     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3360     ok( ret == 5, "got %d\n", ret );
3361     ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
3362     for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3363     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3364     memset( data, 0xaa, sizeof(data) );
3365
3366     ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3367     ok( ret == 8, "got %d\n", ret );
3368     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3369     for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3370     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3371     memset( data, 0xaa, sizeof(data) );
3372
3373     ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3374     ok( ret == 8, "got %d\n", ret );
3375     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3376     for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3377     for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3378     memset( data, 0xaa, sizeof(data) );
3379
3380     ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3381     ok( ret == 7, "got %d\n", ret );
3382     ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3383     for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3384     memset( data, 0xaa, sizeof(data) );
3385
3386     ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
3387     ok( ret == 1, "got %d\n", ret );
3388     for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3389     memset( data, 0xaa, sizeof(data) );
3390
3391     info->bmiHeader.biHeight = -5;
3392     ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3393     ok( ret == 2, "got %d\n", ret );
3394     ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
3395     for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3396     memset( data, 0xaa, sizeof(data) );
3397
3398     DeleteObject( dib );
3399
3400     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
3401     info->bmiHeader.biWidth       = 8;
3402     info->bmiHeader.biHeight      = -8;
3403     info->bmiHeader.biPlanes      = 1;
3404     info->bmiHeader.biBitCount    = 32;
3405     info->bmiHeader.biCompression = BI_RGB;
3406
3407     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3408
3409     for (i = 0; i < 64; i++) dib_bits[i] = i;
3410
3411     /* t-d -> t-d */
3412
3413     info->bmiHeader.biHeight = -8;
3414     ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3415     ok( ret == 8, "got %d\n", ret );
3416     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3417     memset( data, 0xaa, sizeof(data) );
3418
3419     ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3420     ok( ret == 5, "got %d\n", ret );
3421     ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
3422     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3423     memset( data, 0xaa, sizeof(data) );
3424
3425     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3426     ok( ret == 7, "got %d\n", ret );
3427     ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3428     for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3429     memset( data, 0xaa, sizeof(data) );
3430
3431     ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3432     ok( ret == 4, "got %d\n", ret );
3433     ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
3434     for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3435     memset( data, 0xaa, sizeof(data) );
3436
3437     ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3438     ok( ret == 5, "got %d\n", ret );
3439     ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3440     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3441     memset( data, 0xaa, sizeof(data) );
3442
3443     ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3444     ok( ret == 5, "got %d\n", ret );
3445     ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3446     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3447     memset( data, 0xaa, sizeof(data) );
3448
3449     info->bmiHeader.biHeight = -16;
3450     ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3451     ok( ret == 8, "got %d\n", ret );
3452     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3453     for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3454     memset( data, 0xaa, sizeof(data) );
3455
3456     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3457     ok( ret == 5, "got %d\n", ret );
3458     ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
3459     for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3460     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3461     memset( data, 0xaa, sizeof(data) );
3462
3463     ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3464     ok( ret == 8, "got %d\n", ret );
3465     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3466     for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3467     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3468     memset( data, 0xaa, sizeof(data) );
3469
3470     ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3471     ok( ret == 8, "got %d\n", ret );
3472     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3473     for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3474     for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3475     memset( data, 0xaa, sizeof(data) );
3476
3477     ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3478     ok( ret == 7, "got %d\n", ret );
3479     ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3480     for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3481     memset( data, 0xaa, sizeof(data) );
3482
3483     info->bmiHeader.biHeight = -5;
3484     ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3485     ok( ret == 2, "got %d\n", ret );
3486     ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
3487     for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3488     memset( data, 0xaa, sizeof(data) );
3489
3490
3491     /* t-d -> b-u */
3492
3493     info->bmiHeader.biHeight = 8;
3494
3495     ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3496     ok( ret == 8, "got %d\n", ret );
3497     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3498     memset( data, 0xaa, sizeof(data) );
3499
3500     ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3501     ok( ret == 5, "got %d\n", ret );
3502     ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
3503     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3504     memset( data, 0xaa, sizeof(data) );
3505
3506     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3507     ok( ret == 7, "got %d\n", ret );
3508     ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
3509     for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3510     memset( data, 0xaa, sizeof(data) );
3511
3512     ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3513     ok( ret == 1, "got %d\n", ret );
3514     for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3515     memset( data, 0xaa, sizeof(data) );
3516
3517     info->bmiHeader.biHeight = 16;
3518     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3519     ok( ret == 5, "got %d\n", ret );
3520     for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3521     ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
3522     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3523     memset( data, 0xaa, sizeof(data) );
3524
3525     ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3526     ok( ret == 6, "got %d\n", ret );
3527     for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3528     ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
3529     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3530     memset( data, 0xaa, sizeof(data) );
3531
3532     ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3533     ok( ret == 0, "got %d\n", ret );
3534     for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3535     for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3536     memset( data, 0xaa, sizeof(data) );
3537
3538     info->bmiHeader.biHeight = 5;
3539     ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3540     ok( ret == 2, "got %d\n", ret );
3541     ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
3542     for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3543     memset( data, 0xaa, sizeof(data) );
3544
3545     DeleteObject( dib );
3546
3547     ReleaseDC( NULL, hdc );
3548 }
3549
3550
3551 static void test_SetDIBits(void)
3552 {
3553     char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3554     BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3555     DWORD *dib_bits;
3556     HDC hdc = GetDC( NULL );
3557     DWORD data[128], inverted_data[128];
3558     HBITMAP dib;
3559     int i, ret;
3560
3561     memset( info, 0, sizeof(bmi_buf) );
3562
3563     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
3564     info->bmiHeader.biWidth       = 8;
3565     info->bmiHeader.biHeight      = 8;
3566     info->bmiHeader.biPlanes      = 1;
3567     info->bmiHeader.biBitCount    = 32;
3568     info->bmiHeader.biCompression = BI_RGB;
3569
3570     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3571     memset( dib_bits, 0xaa, 64 * 4 );
3572
3573     for (i = 0; i < 128; i++)
3574     {
3575         data[i] = i;
3576         inverted_data[120 - (i & ~7) + (i & 7)] = i;
3577     }
3578
3579     /* b-u -> b-u */
3580
3581     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3582     ok( ret == 8, "got %d\n", ret );
3583     ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
3584     memset( dib_bits, 0xaa, 64 * 4 );
3585
3586     ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3587     ok( ret == 5, "got %d\n", ret );
3588     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3589     ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
3590     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3591     memset( dib_bits, 0xaa, 64 * 4 );
3592
3593     /* top of dst is aligned with startscans down for the top of the src.
3594        Then starting from the bottom of src, lines rows are copied across. */
3595
3596     info->bmiHeader.biHeight = 16;
3597     ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3598     ok( ret == 12, "got %d\n", ret );
3599     ok( !memcmp( dib_bits, data + 56,  40 * 4 ), "bits differ\n");
3600     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3601     memset( dib_bits, 0xaa, 64 * 4 );
3602
3603     info->bmiHeader.biHeight = 5;
3604     ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3605     ok( ret == 2, "got %d\n", ret );
3606     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3607     ok( !memcmp( dib_bits + 32, data,  16 * 4 ), "bits differ\n");
3608     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3609     memset( dib_bits, 0xaa, 64 * 4 );
3610
3611     /* t-d -> b-u */
3612     info->bmiHeader.biHeight = -8;
3613     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3614     ok( ret == 8, "got %d\n", ret );
3615     ok( !memcmp( dib_bits, inverted_data + 64,  64 * 4 ), "bits differ\n");
3616     memset( dib_bits, 0xaa, 64 * 4 );
3617
3618     /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
3619        we copy lines rows from the top of the src */
3620
3621     ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3622     ok( ret == 5, "got %d\n", ret );
3623     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3624     ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
3625     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3626     memset( dib_bits, 0xaa, 64 * 4 );
3627
3628     info->bmiHeader.biHeight = -16;
3629     ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3630     ok( ret == 12, "got %d\n", ret );
3631     ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
3632     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3633     memset( dib_bits, 0xaa, 64 * 4 );
3634
3635     ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3636     ok( ret == 12, "got %d\n", ret );
3637     ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3638     memset( dib_bits, 0xaa, 64 * 4 );
3639
3640     ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3641     ok( ret == 12, "got %d\n", ret );
3642     ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
3643     memset( dib_bits, 0xaa, 64 * 4 );
3644
3645     info->bmiHeader.biHeight = -5;
3646     ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3647     ok( ret == 2, "got %d\n", ret );
3648     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3649     ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
3650     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3651     memset( dib_bits, 0xaa, 64 * 4 );
3652
3653     DeleteObject( dib );
3654
3655     info->bmiHeader.biHeight = -8;
3656
3657     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3658     memset( dib_bits, 0xaa, 16 * 16 * 4 );
3659
3660     /* t-d -> t-d */
3661
3662     /* like the t-d -> b-u case. */
3663
3664     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3665     ok( ret == 8, "got %d\n", ret );
3666     ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
3667     memset( dib_bits, 0xaa, 64 * 4 );
3668
3669     ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3670     ok( ret == 5, "got %d\n", ret );
3671     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3672     ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
3673     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3674     memset( dib_bits, 0xaa, 64 * 4 );
3675
3676     info->bmiHeader.biHeight = -16;
3677     ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3678     ok( ret == 12, "got %d\n", ret );
3679     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3680     ok( !memcmp( dib_bits + 24, data,  40 * 4 ), "bits differ\n");
3681     memset( dib_bits, 0xaa, 64 * 4 );
3682
3683     info->bmiHeader.biHeight = -5;
3684     ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3685     ok( ret == 2, "got %d\n", ret );
3686     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3687     ok( !memcmp( dib_bits + 16, data,  16 * 4 ), "bits differ\n");
3688     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3689     memset( dib_bits, 0xaa, 64 * 4 );
3690
3691     /* b-u -> t-d */
3692     /* like the b-u -> b-u case */
3693
3694     info->bmiHeader.biHeight = 8;
3695     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3696     ok( ret == 8, "got %d\n", ret );
3697     ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3698     memset( dib_bits, 0xaa, 64 * 4 );
3699
3700     ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3701     ok( ret == 5, "got %d\n", ret );
3702     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3703     ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
3704     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3705     memset( dib_bits, 0xaa, 64 * 4 );
3706
3707     info->bmiHeader.biHeight = 16;
3708     ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3709     ok( ret == 12, "got %d\n", ret );
3710     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3711     ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
3712     memset( dib_bits, 0xaa, 64 * 4 );
3713
3714     info->bmiHeader.biHeight = 5;
3715     ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3716     ok( ret == 2, "got %d\n", ret );
3717     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3718     ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
3719     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3720     memset( dib_bits, 0xaa, 64 * 4 );
3721
3722     DeleteObject( dib );
3723     ReleaseDC( NULL, hdc );
3724 }
3725
3726 static void test_SetDIBits_RLE4(void)
3727 {
3728     char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3729     BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3730     DWORD *dib_bits;
3731     HDC hdc = GetDC( NULL );
3732     BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00,     /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
3733                            0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
3734                            0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00,     /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
3735                            0x00, 0x02, 0x01, 0x02, 0x05, 0x87,     /* dx=1, dy=2, 8, 7, 8, 7, 8 */
3736                            0x00, 0x01 };                           /* <eod> */
3737     HBITMAP dib;
3738     int i, ret;
3739     DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
3740                             0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
3741                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3742                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3743                             0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
3744                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3745                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3746                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
3747
3748     memset( info, 0, sizeof(bmi_buf) );
3749
3750     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
3751     info->bmiHeader.biWidth       = 8;
3752     info->bmiHeader.biHeight      = 8;
3753     info->bmiHeader.biPlanes      = 1;
3754     info->bmiHeader.biBitCount    = 32;
3755     info->bmiHeader.biCompression = BI_RGB;
3756
3757     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3758     memset( dib_bits, 0xaa, 64 * 4 );
3759
3760     info->bmiHeader.biBitCount    = 4;
3761     info->bmiHeader.biCompression = BI_RLE4;
3762     info->bmiHeader.biSizeImage   = sizeof(rle4_data);
3763
3764     for (i = 0; i < 16; i++)
3765     {
3766         info->bmiColors[i].rgbRed      = i;
3767         info->bmiColors[i].rgbGreen    = i;
3768         info->bmiColors[i].rgbBlue     = i;
3769         info->bmiColors[i].rgbReserved = 0;
3770     }
3771
3772     ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
3773     ok( ret == 8, "got %d\n", ret );
3774     ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
3775     memset( dib_bits, 0xaa, 64 * 4 );
3776
3777     DeleteObject( dib );
3778     ReleaseDC( NULL, hdc );
3779 }
3780
3781 static void test_SetDIBits_RLE8(void)
3782 {
3783     char bmi_buf[ FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ];
3784     BITMAPINFO *info = (BITMAPINFO *)bmi_buf;
3785     DWORD *dib_bits;
3786     HDC hdc = GetDC( NULL );
3787     BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00,     /* 2, 2, 2, f0, f0, f0, f0, <eol> */
3788                            0x00, 0x03, 0x04, 0x05, 0x06, 0x00,     /* 4, 5, 6, <pad> */
3789                            0x00, 0x02, 0x01, 0x02, 0x05, 0x80,     /* dx=1, dy=2, 80, 80, 80, 80, (80) */
3790                            0x00, 0x01 };                           /* <eod> */
3791     HBITMAP dib;
3792     int i, ret;
3793     DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
3794                             0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3795                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3796                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
3797                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3798                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3799                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3800                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
3801     DWORD top_down[64]  = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3802                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3803                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3804                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3805                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
3806                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3807                             0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
3808                             0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
3809
3810     memset( info, 0, sizeof(bmi_buf) );
3811
3812     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
3813     info->bmiHeader.biWidth       = 8;
3814     info->bmiHeader.biHeight      = 8;
3815     info->bmiHeader.biPlanes      = 1;
3816     info->bmiHeader.biBitCount    = 32;
3817     info->bmiHeader.biCompression = BI_RGB;
3818
3819     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3820     memset( dib_bits, 0xaa, 64 * 4 );
3821
3822     info->bmiHeader.biBitCount    = 8;
3823     info->bmiHeader.biCompression = BI_RLE8;
3824     info->bmiHeader.biSizeImage   = sizeof(rle8_data);
3825
3826     for (i = 0; i < 256; i++)
3827     {
3828         info->bmiColors[i].rgbRed      = i;
3829         info->bmiColors[i].rgbGreen    = i;
3830         info->bmiColors[i].rgbBlue     = i;
3831         info->bmiColors[i].rgbReserved = 0;
3832     }
3833
3834     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
3835     ok( ret == 8, "got %d\n", ret );
3836     ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
3837     memset( dib_bits, 0xaa, 64 * 4 );
3838
3839     /* startscan and lines are ignored, unless lines == 0 */
3840     ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
3841     ok( ret == 8, "got %d\n", ret );
3842     ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
3843     memset( dib_bits, 0xaa, 64 * 4 );
3844
3845     ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
3846     ok( ret == 8, "got %d\n", ret );
3847     ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
3848     memset( dib_bits, 0xaa, 64 * 4 );
3849
3850     ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
3851     ok( ret == 0, "got %d\n", ret );
3852     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3853     memset( dib_bits, 0xaa, 64 * 4 );
3854
3855     /* reduce width to 4, left-hand side of dst is touched. */
3856     info->bmiHeader.biWidth = 4;
3857     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
3858     ok( ret == 8, "got %d\n", ret );
3859     for (i = 0; i < 64; i++)
3860     {
3861         DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
3862         ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
3863     }
3864     memset( dib_bits, 0xaa, 64 * 4 );
3865
3866     /* Show that the top lines are aligned by adjusting the height of the src */
3867
3868     /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
3869     info->bmiHeader.biWidth  = 8;
3870     info->bmiHeader.biHeight = 4;
3871     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
3872     ok( ret == 4, "got %d\n", ret );
3873     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3874     ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
3875     memset( dib_bits, 0xaa, 64 * 4 );
3876
3877     /* increase the height to 9 -> everything moves down one row. */
3878     info->bmiHeader.biHeight = 9;
3879     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
3880     ok( ret == 9, "got %d\n", ret );
3881     ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
3882     for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
3883     memset( dib_bits, 0xaa, 64 * 4 );
3884
3885     /* top-down compressed dibs are invalid */
3886     info->bmiHeader.biHeight = -8;
3887     SetLastError( 0xdeadbeef );
3888     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
3889     ok( ret == 0, "got %d\n", ret );
3890     ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
3891     DeleteObject( dib );
3892
3893     /* top-down dst */
3894
3895     info->bmiHeader.biHeight      = -8;
3896     info->bmiHeader.biBitCount    = 32;
3897     info->bmiHeader.biCompression = BI_RGB;
3898     info->bmiHeader.biSizeImage   = 0;
3899
3900     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3901     memset( dib_bits, 0xaa, 16 * 16 * 4 );
3902
3903     info->bmiHeader.biHeight      = 8;
3904     info->bmiHeader.biBitCount    = 8;
3905     info->bmiHeader.biCompression = BI_RLE8;
3906     info->bmiHeader.biSizeImage   = sizeof(rle8_data);
3907
3908     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
3909     ok( ret == 8, "got %d\n", ret );
3910     ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
3911     memset( dib_bits, 0xaa, 64 * 4 );
3912
3913     info->bmiHeader.biHeight = 4;
3914     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
3915     ok( ret == 4, "got %d\n", ret );
3916     ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
3917     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3918     memset( dib_bits, 0xaa, 64 * 4 );
3919
3920     info->bmiHeader.biHeight = 9;
3921     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
3922     ok( ret == 9, "got %d\n", ret );
3923     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3924     ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
3925     memset( dib_bits, 0xaa, 64 * 4 );
3926
3927     DeleteObject( dib );
3928
3929     ReleaseDC( NULL, hdc );
3930 }
3931
3932 START_TEST(bitmap)
3933 {
3934     HMODULE hdll;
3935
3936     hdll = GetModuleHandle("gdi32.dll");
3937     pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
3938     pSetLayout     = (void*)GetProcAddress(hdll, "SetLayout");
3939
3940     test_createdibitmap();
3941     test_dibsections();
3942     test_mono_dibsection();
3943     test_bitmap();
3944     test_bmBits();
3945     test_GetDIBits_selected_DIB(1);
3946     test_GetDIBits_selected_DIB(4);
3947     test_GetDIBits_selected_DIB(8);
3948     test_GetDIBits_selected_DDB(TRUE);
3949     test_GetDIBits_selected_DDB(FALSE);
3950     test_GetDIBits();
3951     test_GetDIBits_BI_BITFIELDS();
3952     test_select_object();
3953     test_CreateBitmap();
3954     test_BitBlt();
3955     test_StretchBlt();
3956     test_StretchDIBits();
3957     test_GdiAlphaBlend();
3958     test_32bit_bitmap_blt();
3959     test_bitmapinfoheadersize();
3960     test_get16dibits();
3961     test_clipping();
3962     test_GetDIBits_top_down(16);
3963     test_GetDIBits_top_down(24);
3964     test_GetDIBits_top_down(32);
3965     test_GetSetDIBits_rtl();
3966     test_GetDIBits_scanlines();
3967     test_SetDIBits();
3968     test_SetDIBits_RLE4();
3969     test_SetDIBits_RLE8();
3970 }