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