gdi32/tests: Fix MSVC build in bitmap.c.
[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     BITMAPINFO *bi;
820     char data[256];
821     void *bits;
822     int planes, bpp, compr;
823     HBITMAP hdib, hbmp;
824     HDC hdc, memdc;
825     UINT ret;
826     BOOL expect_ok, todo;
827
828     bi = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
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     HeapFree( GetProcessHeap(), 0, bi );
1127 }
1128
1129 static void test_mono_dibsection(void)
1130 {
1131     HDC hdc, memdc;
1132     HBITMAP old_bm, mono_ds;
1133     char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
1134     BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
1135     BYTE bits[10 * 4];
1136     BYTE *ds_bits;
1137     int num;
1138
1139     hdc = GetDC(0);
1140
1141     memdc = CreateCompatibleDC(hdc);
1142
1143     memset(pbmi, 0, sizeof(bmibuf));
1144     pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
1145     pbmi->bmiHeader.biHeight = 10;
1146     pbmi->bmiHeader.biWidth = 10;
1147     pbmi->bmiHeader.biBitCount = 1;
1148     pbmi->bmiHeader.biPlanes = 1;
1149     pbmi->bmiHeader.biCompression = BI_RGB;
1150     pbmi->bmiColors[0].rgbRed = 0xff;
1151     pbmi->bmiColors[0].rgbGreen = 0xff;
1152     pbmi->bmiColors[0].rgbBlue = 0xff;
1153     pbmi->bmiColors[1].rgbRed = 0x0;
1154     pbmi->bmiColors[1].rgbGreen = 0x0;
1155     pbmi->bmiColors[1].rgbBlue = 0x0;
1156
1157     /*
1158      * First dib section is 'inverted' ie color[0] is white, color[1] is black
1159      */
1160
1161     mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1162     ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1163     old_bm = SelectObject(memdc, mono_ds);
1164
1165     /* black border, white interior */
1166     Rectangle(memdc, 0, 0, 10, 10);
1167     ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1168     ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1169
1170     /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1171
1172     memset(bits, 0, sizeof(bits));
1173     bits[0] = 0xaa;
1174
1175     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1176     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1177
1178     /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1179
1180     pbmi->bmiColors[0].rgbRed = 0x0;
1181     pbmi->bmiColors[0].rgbGreen = 0x0;
1182     pbmi->bmiColors[0].rgbBlue = 0x0;
1183     pbmi->bmiColors[1].rgbRed = 0xff;
1184     pbmi->bmiColors[1].rgbGreen = 0xff;
1185     pbmi->bmiColors[1].rgbBlue = 0xff;
1186
1187     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1188     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1189
1190     SelectObject(memdc, old_bm);
1191     DeleteObject(mono_ds);
1192
1193     /*
1194      * Next dib section is 'normal' ie color[0] is black, color[1] is white
1195      */
1196
1197     pbmi->bmiColors[0].rgbRed = 0x0;
1198     pbmi->bmiColors[0].rgbGreen = 0x0;
1199     pbmi->bmiColors[0].rgbBlue = 0x0;
1200     pbmi->bmiColors[1].rgbRed = 0xff;
1201     pbmi->bmiColors[1].rgbGreen = 0xff;
1202     pbmi->bmiColors[1].rgbBlue = 0xff;
1203
1204     mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1205     ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1206     old_bm = SelectObject(memdc, mono_ds);
1207
1208     /* black border, white interior */
1209     Rectangle(memdc, 0, 0, 10, 10);
1210     ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
1211     ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
1212
1213     /* SetDIBitsToDevice with a normal bmi -> normal dib section */
1214
1215     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1216     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1217
1218     /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
1219
1220     pbmi->bmiColors[0].rgbRed = 0xff;
1221     pbmi->bmiColors[0].rgbGreen = 0xff;
1222     pbmi->bmiColors[0].rgbBlue = 0xff;
1223     pbmi->bmiColors[1].rgbRed = 0x0;
1224     pbmi->bmiColors[1].rgbGreen = 0x0;
1225     pbmi->bmiColors[1].rgbBlue = 0x0;
1226
1227     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1228     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1229
1230     /*
1231      * Take that 'normal' dibsection and change its colour table to an 'inverted' one
1232      */
1233
1234     pbmi->bmiColors[0].rgbRed = 0xff;
1235     pbmi->bmiColors[0].rgbGreen = 0xff;
1236     pbmi->bmiColors[0].rgbBlue = 0xff;
1237     pbmi->bmiColors[1].rgbRed = 0x0;
1238     pbmi->bmiColors[1].rgbGreen = 0x0;
1239     pbmi->bmiColors[1].rgbBlue = 0x0;
1240     num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors);
1241     ok(num == 2, "num = %d\n", num);
1242
1243     /* black border, white interior */
1244     Rectangle(memdc, 0, 0, 10, 10);
1245     ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1246     ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1247
1248     /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1249
1250     memset(bits, 0, sizeof(bits));
1251     bits[0] = 0xaa;
1252
1253     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1254     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1255
1256     /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1257
1258     pbmi->bmiColors[0].rgbRed = 0x0;
1259     pbmi->bmiColors[0].rgbGreen = 0x0;
1260     pbmi->bmiColors[0].rgbBlue = 0x0;
1261     pbmi->bmiColors[1].rgbRed = 0xff;
1262     pbmi->bmiColors[1].rgbGreen = 0xff;
1263     pbmi->bmiColors[1].rgbBlue = 0xff;
1264
1265     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1266     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1267
1268     SelectObject(memdc, old_bm);
1269     DeleteObject(mono_ds);
1270
1271     /*
1272      * Now a dib section with a strange colour map just for fun.  This behaves just like an inverted one.
1273      */
1274  
1275     pbmi->bmiColors[0].rgbRed = 0xff;
1276     pbmi->bmiColors[0].rgbGreen = 0x0;
1277     pbmi->bmiColors[0].rgbBlue = 0x0;
1278     pbmi->bmiColors[1].rgbRed = 0xfe;
1279     pbmi->bmiColors[1].rgbGreen = 0x0;
1280     pbmi->bmiColors[1].rgbBlue = 0x0;
1281
1282     mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1283     ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1284     old_bm = SelectObject(memdc, mono_ds);
1285
1286     /* black border, white interior */
1287     Rectangle(memdc, 0, 0, 10, 10);
1288     ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1289     ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1290
1291     /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1292
1293     pbmi->bmiColors[0].rgbRed = 0x0;
1294     pbmi->bmiColors[0].rgbGreen = 0x0;
1295     pbmi->bmiColors[0].rgbBlue = 0x0;
1296     pbmi->bmiColors[1].rgbRed = 0xff;
1297     pbmi->bmiColors[1].rgbGreen = 0xff;
1298     pbmi->bmiColors[1].rgbBlue = 0xff;
1299
1300     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1301     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1302
1303     /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
1304
1305     pbmi->bmiColors[0].rgbRed = 0xff;
1306     pbmi->bmiColors[0].rgbGreen = 0xff;
1307     pbmi->bmiColors[0].rgbBlue = 0xff;
1308     pbmi->bmiColors[1].rgbRed = 0x0;
1309     pbmi->bmiColors[1].rgbGreen = 0x0;
1310     pbmi->bmiColors[1].rgbBlue = 0x0;
1311
1312     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1313     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1314
1315     SelectObject(memdc, old_bm);
1316     DeleteObject(mono_ds);
1317
1318     DeleteDC(memdc);
1319     ReleaseDC(0, hdc);
1320 }
1321
1322 static void test_bitmap(void)
1323 {
1324     char buf[256], buf_cmp[256];
1325     HBITMAP hbmp, hbmp_old;
1326     HDC hdc;
1327     BITMAP bm;
1328     BITMAP bma[2];
1329     INT ret;
1330
1331     hdc = CreateCompatibleDC(0);
1332     assert(hdc != 0);
1333
1334     SetLastError(0xdeadbeef);
1335     hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1336     if (!hbmp)
1337     {
1338         ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1339            GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1340            "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1341     }
1342     else
1343         DeleteObject(hbmp);
1344
1345     SetLastError(0xdeadbeef);
1346     hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1347     if (!hbmp)
1348     {
1349         ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1350            GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1351            "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1352     }
1353     else
1354         DeleteObject(hbmp);
1355
1356     SetLastError(0xdeadbeef);
1357     hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1358     ok(!hbmp, "CreateBitmap should fail\n");
1359     if (!hbmp)
1360         ok(GetLastError() == ERROR_INVALID_PARAMETER,
1361            "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1362     else
1363         DeleteObject(hbmp);
1364
1365     hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1366     assert(hbmp != NULL);
1367
1368     ret = GetObject(hbmp, sizeof(bm), &bm);
1369     ok(ret == sizeof(bm), "wrong size %d\n", ret);
1370
1371     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1372     ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1373     ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1374     ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1375     ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1376     ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1377     ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1378
1379     assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1380     assert(sizeof(buf) == sizeof(buf_cmp));
1381
1382     ret = GetBitmapBits(hbmp, 0, NULL);
1383     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1384
1385     memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1386     memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1387
1388     memset(buf, 0xAA, sizeof(buf));
1389     ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1390     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1391     ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1392
1393     hbmp_old = SelectObject(hdc, hbmp);
1394
1395     ret = GetObject(hbmp, sizeof(bm), &bm);
1396     ok(ret == sizeof(bm), "wrong size %d\n", ret);
1397
1398     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1399     ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1400     ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1401     ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1402     ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1403     ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1404     ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1405
1406     memset(buf, 0xAA, sizeof(buf));
1407     ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1408     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1409     ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1410
1411     hbmp_old = SelectObject(hdc, hbmp_old);
1412     ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1413
1414     /* test various buffer sizes for GetObject */
1415     ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
1416     ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1417
1418     ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1419     ok(ret == 0, "%d != 0\n", ret);
1420
1421     ret = GetObject(hbmp, 0, &bm);
1422     ok(ret == 0, "%d != 0\n", ret);
1423
1424     ret = GetObject(hbmp, 1, &bm);
1425     ok(ret == 0, "%d != 0\n", ret);
1426
1427     DeleteObject(hbmp);
1428     DeleteDC(hdc);
1429 }
1430
1431 static void test_bmBits(void)
1432 {
1433     BYTE bits[4];
1434     HBITMAP hbmp;
1435     BITMAP bmp;
1436
1437     memset(bits, 0, sizeof(bits));
1438     hbmp = CreateBitmap(2, 2, 1, 4, bits);
1439     ok(hbmp != NULL, "CreateBitmap failed\n");
1440
1441     memset(&bmp, 0xFF, sizeof(bmp));
1442     ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1443        "GetObject failed or returned a wrong structure size\n");
1444     ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1445
1446     DeleteObject(hbmp);
1447 }
1448
1449 static void test_GetDIBits_selected_DIB(UINT bpp)
1450 {
1451     HBITMAP dib;
1452     BITMAPINFO *info;
1453     BITMAPINFO *info2;
1454     void * bits;
1455     void * bits2;
1456     UINT dib_size, dib32_size;
1457     DWORD pixel;
1458     HDC dib_dc, dc;
1459     HBITMAP old_bmp;
1460     UINT i;
1461     int res;
1462
1463     info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1464     info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1465
1466     /* Create a DIB section with a color table */
1467
1468     info->bmiHeader.biSize          = sizeof(info->bmiHeader);
1469     info->bmiHeader.biWidth         = 32;
1470     info->bmiHeader.biHeight        = 32;
1471     info->bmiHeader.biPlanes        = 1;
1472     info->bmiHeader.biBitCount      = bpp;
1473     info->bmiHeader.biCompression   = BI_RGB;
1474     info->bmiHeader.biXPelsPerMeter = 0;
1475     info->bmiHeader.biYPelsPerMeter = 0;
1476     info->bmiHeader.biClrUsed       = 0;
1477     info->bmiHeader.biClrImportant  = 0;
1478
1479     for (i=0; i < (1u << bpp); i++)
1480     {
1481         BYTE c = i * (1 << (8 - bpp));
1482         info->bmiColors[i].rgbRed = c;
1483         info->bmiColors[i].rgbGreen = c;
1484         info->bmiColors[i].rgbBlue = c;
1485         info->bmiColors[i].rgbReserved = 0;
1486     }
1487
1488     dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1489     dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1490     dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1491
1492     /* Set the bits of the DIB section */
1493     for (i=0; i < dib_size; i++)
1494     {
1495         ((BYTE *)bits)[i] = i % 256;
1496     }
1497
1498     /* Select the DIB into a DC */
1499     dib_dc = CreateCompatibleDC(NULL);
1500     old_bmp = SelectObject(dib_dc, dib);
1501     dc = CreateCompatibleDC(NULL);
1502     bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
1503
1504     /* Copy the DIB attributes but not the color table */
1505     memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1506
1507     res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1508     ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1509
1510     /* Compare the color table and the bits */
1511     for (i=0; i < (1u << bpp); i++)
1512         ok( info->bmiColors[i].rgbRed      == info2->bmiColors[i].rgbRed   &&
1513             info->bmiColors[i].rgbGreen    == info2->bmiColors[i].rgbGreen &&
1514             info->bmiColors[i].rgbBlue     == info2->bmiColors[i].rgbBlue  &&
1515             info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1516             "color table entry %d differs (bpp %d)\n", i, bpp );
1517
1518     ok( !memcmp( bits, bits2, dib_size ), "bit mismatch (bpp %d)\n", bpp );
1519
1520     /* Test various combinations of lines = 0 and bits2 = NULL */
1521     memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1522     res = GetDIBits( dc, dib, 0, 0, bits2, info2, DIB_RGB_COLORS );
1523     ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1524     ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1525         "color table mismatch (bpp %d)\n", bpp );
1526
1527     memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1528     res = GetDIBits( dc, dib, 0, 0, NULL, info2, DIB_RGB_COLORS );
1529     ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1530     ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1531         "color table mismatch (bpp %d)\n", bpp );
1532
1533     memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1534     res = GetDIBits( dc, dib, 0, info->bmiHeader.biHeight, NULL, info2, DIB_RGB_COLORS );
1535     ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1536     ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1537         "color table mismatch (bpp %d)\n", bpp );
1538
1539     /* Map into a 32bit-DIB */
1540     info2->bmiHeader.biBitCount = 32;
1541     res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1542     ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1543
1544     /* Check if last pixel was set */
1545     pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
1546     ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
1547
1548     HeapFree(GetProcessHeap(), 0, bits2);
1549     DeleteDC(dc);
1550
1551     SelectObject(dib_dc, old_bmp);
1552     DeleteDC(dib_dc);
1553     DeleteObject(dib);
1554     HeapFree(GetProcessHeap(), 0, info2);
1555     HeapFree(GetProcessHeap(), 0, info);
1556 }
1557
1558 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1559 {
1560     HBITMAP ddb;
1561     BITMAPINFO *info;
1562     BITMAPINFO *info2;
1563     void * bits;
1564     void * bits2;
1565     HDC ddb_dc, dc;
1566     HBITMAP old_bmp;
1567     UINT width, height;
1568     UINT bpp;
1569     UINT i, j;
1570     int res;
1571
1572     info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1573     info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1574
1575     width = height = 16;
1576
1577     /* Create a DDB (device-dependent bitmap) */
1578     if (monochrome)
1579     {
1580         bpp = 1;
1581         ddb = CreateBitmap(width, height, 1, 1, NULL);
1582     }
1583     else
1584     {
1585         HDC screen_dc = GetDC(NULL);
1586         bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1587         ddb = CreateCompatibleBitmap(screen_dc, width, height);
1588         ReleaseDC(NULL, screen_dc);
1589     }
1590
1591     /* Set the pixels */
1592     ddb_dc = CreateCompatibleDC(NULL);
1593     old_bmp = SelectObject(ddb_dc, ddb);
1594     for (i = 0; i < width; i++)
1595     {
1596         for (j=0; j < height; j++)
1597         {
1598             BYTE c = (i * width + j) % 256;
1599             SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1600         }
1601     }
1602     SelectObject(ddb_dc, old_bmp);
1603
1604     info->bmiHeader.biSize = sizeof(info->bmiHeader);
1605     info->bmiHeader.biWidth = width;
1606     info->bmiHeader.biHeight = height;
1607     info->bmiHeader.biPlanes = 1;
1608     info->bmiHeader.biBitCount = bpp;
1609     info->bmiHeader.biCompression = BI_RGB;
1610
1611     dc = CreateCompatibleDC(NULL);
1612
1613     /* Fill in biSizeImage */
1614     GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1615     ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1616
1617     bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1618     bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1619
1620     /* Get the bits */
1621     res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1622     ok( res == height, "got %d (bpp %d)\n", res, bpp );
1623
1624     /* Copy the DIB attributes but not the color table */
1625     memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1626
1627     /* Select the DDB into another DC */
1628     old_bmp = SelectObject(ddb_dc, ddb);
1629
1630     /* Get the bits */
1631     res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1632     ok( res == height, "got %d (bpp %d)\n", res, bpp );
1633
1634     /* Compare the color table and the bits */
1635     if (bpp <= 8)
1636     {
1637         for (i=0; i < (1u << bpp); i++)
1638             ok( info->bmiColors[i].rgbRed      == info2->bmiColors[i].rgbRed   &&
1639                 info->bmiColors[i].rgbGreen    == info2->bmiColors[i].rgbGreen &&
1640                 info->bmiColors[i].rgbBlue     == info2->bmiColors[i].rgbBlue  &&
1641                 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1642                 "color table entry %d differs (bpp %d)\n", i, bpp );
1643     }
1644
1645     ok( !memcmp( bits, bits2, info->bmiHeader.biSizeImage ), "bit mismatch (bpp %d)\n", bpp );
1646
1647     /* Test the palette */
1648     if (info2->bmiHeader.biBitCount <= 8)
1649     {
1650         WORD *colors = (WORD*)info2->bmiColors;
1651
1652         /* Get the palette indices */
1653         res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1654         ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1655
1656         for (i = 0; i < (1 << info->bmiHeader.biBitCount); i++)
1657             ok( colors[i] == i, "%d: got %d (bpp %d)\n", i, colors[i], bpp );
1658     }
1659
1660     HeapFree(GetProcessHeap(), 0, bits2);
1661     HeapFree(GetProcessHeap(), 0, bits);
1662     DeleteDC(dc);
1663
1664     SelectObject(ddb_dc, old_bmp);
1665     DeleteDC(ddb_dc);
1666     DeleteObject(ddb);
1667     HeapFree(GetProcessHeap(), 0, info2);
1668     HeapFree(GetProcessHeap(), 0, info);
1669 }
1670
1671 static void test_GetDIBits(void)
1672 {
1673     /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1674     static const BYTE bmp_bits_1[16 * 2] =
1675     {
1676         0xff,0xff, 0,0, 0xff,0xff, 0,0,
1677         0xff,0xff, 0,0, 0xff,0xff, 0,0,
1678         0xff,0xff, 0,0, 0xff,0xff, 0,0,
1679         0xff,0xff, 0,0, 0xff,0xff, 0,0
1680     };
1681     /* 4-bytes aligned 1-bit DIB data: 16x16 */
1682     static const BYTE dib_bits_1[16 * 4] =
1683     {
1684         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1685         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1686         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1687         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1688     };
1689     /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1690     static const BYTE bmp_bits_24[16 * 16*3] =
1691     {
1692         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1717         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1718         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1719         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1720         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1721         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1724     };
1725     /* 4-bytes aligned 24-bit DIB data: 16x16 */
1726     static const BYTE dib_bits_24[16 * 16*3] =
1727     {
1728         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1753         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1754         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1755         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1756         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1757         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1758         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1759         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1760     };
1761     HBITMAP hbmp;
1762     BITMAP bm;
1763     HDC hdc;
1764     int i, bytes, lines;
1765     BYTE buf[1024];
1766     char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1767     BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1768     PALETTEENTRY pal_ents[20];
1769
1770     hdc = GetDC(0);
1771
1772     /* 1-bit source bitmap data */
1773     hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1774     ok(hbmp != 0, "CreateBitmap failed\n");
1775
1776     memset(&bm, 0xAA, sizeof(bm));
1777     bytes = GetObject(hbmp, sizeof(bm), &bm);
1778     ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1779     ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1780     ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1781     ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1782     ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1783     ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1784     ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1785     ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1786
1787     bytes = GetBitmapBits(hbmp, 0, NULL);
1788     ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1789     bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1790     ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1791     ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1792
1793     /* retrieve 1-bit DIB data */
1794     memset(bi, 0, sizeof(*bi));
1795     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1796     bi->bmiHeader.biWidth = bm.bmWidth;
1797     bi->bmiHeader.biHeight = bm.bmHeight;
1798     bi->bmiHeader.biPlanes = 1;
1799     bi->bmiHeader.biBitCount = 1;
1800     bi->bmiHeader.biCompression = BI_RGB;
1801     bi->bmiHeader.biSizeImage = 0;
1802     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1803     SetLastError(0xdeadbeef);
1804     lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1805     ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1806     ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1807        broken(GetLastError() == 0xdeadbeef), /* winnt */
1808        "wrong error %u\n", GetLastError());
1809     ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1810
1811     memset(buf, 0xAA, sizeof(buf));
1812     SetLastError(0xdeadbeef);
1813     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1814     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1815        lines, bm.bmHeight, GetLastError());
1816     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1817
1818     /* the color table consists of black and white */
1819     ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1820        bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1821        "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1822        bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1823        bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1824     ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1825        bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1826        "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1827        bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1828        bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1829     for (i = 2; i < 256; i++)
1830     {
1831         ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1832            bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1833            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1834            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1835            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1836     }
1837
1838     /* returned bits are DWORD aligned and upside down */
1839     ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1840
1841     /* Test the palette indices */
1842     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1843     SetLastError(0xdeadbeef);
1844     lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1845     ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1846     ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1847     for (i = 2; i < 256; i++)
1848         ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[1]);
1849
1850     /* retrieve 24-bit DIB data */
1851     memset(bi, 0, sizeof(*bi));
1852     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1853     bi->bmiHeader.biWidth = bm.bmWidth;
1854     bi->bmiHeader.biHeight = bm.bmHeight;
1855     bi->bmiHeader.biPlanes = 1;
1856     bi->bmiHeader.biBitCount = 24;
1857     bi->bmiHeader.biCompression = BI_RGB;
1858     bi->bmiHeader.biSizeImage = 0;
1859     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1860     memset(buf, 0xAA, sizeof(buf));
1861     SetLastError(0xdeadbeef);
1862     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1863     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1864        lines, bm.bmHeight, GetLastError());
1865     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1866
1867     /* the color table doesn't exist for 24-bit images */
1868     for (i = 0; i < 256; i++)
1869     {
1870         ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1871            bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1872            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1873            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1874            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1875     }
1876
1877     /* returned bits are DWORD aligned and upside down */
1878     ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1879     DeleteObject(hbmp);
1880
1881     /* 24-bit source bitmap data */
1882     hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1883     ok(hbmp != 0, "CreateBitmap failed\n");
1884     SetLastError(0xdeadbeef);
1885     bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1886     lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1887     ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1888        lines, bm.bmHeight, GetLastError());
1889
1890     memset(&bm, 0xAA, sizeof(bm));
1891     bytes = GetObject(hbmp, sizeof(bm), &bm);
1892     ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1893     ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1894     ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1895     ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1896     ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1897     ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1898     ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1899     ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1900
1901     bytes = GetBitmapBits(hbmp, 0, NULL);
1902     ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
1903     bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1904     ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1905        bm.bmWidthBytes * bm.bmHeight, bytes);
1906
1907     /* retrieve 1-bit DIB data */
1908     memset(bi, 0, sizeof(*bi));
1909     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1910     bi->bmiHeader.biWidth = bm.bmWidth;
1911     bi->bmiHeader.biHeight = bm.bmHeight;
1912     bi->bmiHeader.biPlanes = 1;
1913     bi->bmiHeader.biBitCount = 1;
1914     bi->bmiHeader.biCompression = BI_RGB;
1915     bi->bmiHeader.biSizeImage = 0;
1916     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1917     memset(buf, 0xAA, sizeof(buf));
1918     SetLastError(0xdeadbeef);
1919     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1920     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1921        lines, bm.bmHeight, GetLastError());
1922     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1923
1924     /* the color table consists of black and white */
1925     ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1926        bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1927        "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1928        bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1929        bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1930     ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1931        bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1932        "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1933        bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1934        bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1935     for (i = 2; i < 256; i++)
1936     {
1937         ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1938            bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1939            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1940            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1941            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1942     }
1943
1944     /* returned bits are DWORD aligned and upside down */
1945     ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1946
1947     /* Test the palette indices */
1948     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1949     SetLastError(0xdeadbeef);
1950     lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1951     ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1952     ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1953     for (i = 2; i < 256; i++)
1954         ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[i]);
1955
1956     /* retrieve 4-bit DIB data */
1957     memset(bi, 0, sizeof(*bi));
1958     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1959     bi->bmiHeader.biWidth = bm.bmWidth;
1960     bi->bmiHeader.biHeight = bm.bmHeight;
1961     bi->bmiHeader.biPlanes = 1;
1962     bi->bmiHeader.biBitCount = 4;
1963     bi->bmiHeader.biCompression = BI_RGB;
1964     bi->bmiHeader.biSizeImage = 0;
1965     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1966     memset(buf, 0xAA, sizeof(buf));
1967     SetLastError(0xdeadbeef);
1968     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1969     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1970        lines, bm.bmHeight, GetLastError());
1971
1972     GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
1973
1974     for (i = 0; i < 16; i++)
1975     {
1976         RGBQUAD expect;
1977         int entry = i < 8 ? i : i + 4;
1978
1979         if(entry == 7) entry = 12;
1980         else if(entry == 12) entry = 7;
1981
1982         expect.rgbRed   = pal_ents[entry].peRed;
1983         expect.rgbGreen = pal_ents[entry].peGreen;
1984         expect.rgbBlue  = pal_ents[entry].peBlue;
1985         expect.rgbReserved = 0;
1986
1987         ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
1988            "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
1989            expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
1990            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1991            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1992     }
1993
1994     /* retrieve 8-bit DIB data */
1995     memset(bi, 0, sizeof(*bi));
1996     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1997     bi->bmiHeader.biWidth = bm.bmWidth;
1998     bi->bmiHeader.biHeight = bm.bmHeight;
1999     bi->bmiHeader.biPlanes = 1;
2000     bi->bmiHeader.biBitCount = 8;
2001     bi->bmiHeader.biCompression = BI_RGB;
2002     bi->bmiHeader.biSizeImage = 0;
2003     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
2004     memset(buf, 0xAA, sizeof(buf));
2005     SetLastError(0xdeadbeef);
2006     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2007     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2008        lines, bm.bmHeight, GetLastError());
2009
2010     GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2011
2012     for (i = 0; i < 256; i++)
2013     {
2014         RGBQUAD expect;
2015
2016         if (i < 10 || i >= 246)
2017         {
2018             int entry = i < 10 ? i : i - 236;
2019             expect.rgbRed   = pal_ents[entry].peRed;
2020             expect.rgbGreen = pal_ents[entry].peGreen;
2021             expect.rgbBlue  = pal_ents[entry].peBlue;
2022         }
2023         else
2024         {
2025             expect.rgbRed   = (i & 0x07) << 5;
2026             expect.rgbGreen = (i & 0x38) << 2;
2027             expect.rgbBlue  =  i & 0xc0;
2028         }
2029         expect.rgbReserved = 0;
2030
2031         ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
2032            "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2033            expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2034            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
2035            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
2036     }
2037
2038     /* retrieve 24-bit DIB data */
2039     memset(bi, 0, sizeof(*bi));
2040     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2041     bi->bmiHeader.biWidth = bm.bmWidth;
2042     bi->bmiHeader.biHeight = bm.bmHeight;
2043     bi->bmiHeader.biPlanes = 1;
2044     bi->bmiHeader.biBitCount = 24;
2045     bi->bmiHeader.biCompression = BI_RGB;
2046     bi->bmiHeader.biSizeImage = 0;
2047     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
2048     memset(buf, 0xAA, sizeof(buf));
2049     SetLastError(0xdeadbeef);
2050     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2051     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2052        lines, bm.bmHeight, GetLastError());
2053     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2054
2055     /* the color table doesn't exist for 24-bit images */
2056     for (i = 0; i < 256; i++)
2057     {
2058         ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
2059            bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
2060            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2061            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
2062            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
2063     }
2064
2065     /* returned bits are DWORD aligned and upside down */
2066     ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2067     DeleteObject(hbmp);
2068
2069     ReleaseDC(0, hdc);
2070 }
2071
2072 static void test_GetDIBits_BI_BITFIELDS(void)
2073 {
2074     /* Try a screen resolution detection technique
2075      * from the September 1999 issue of Windows Developer's Journal
2076      * which seems to be in widespread use.
2077      * http://www.lesher.ws/highcolor.html
2078      * http://www.lesher.ws/vidfmt.c
2079      * It hinges on being able to retrieve the bitmaps
2080      * for the three primary colors in non-paletted 16 bit mode.
2081      */
2082     char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
2083     DWORD bits[32];
2084     LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
2085     DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
2086     HDC hdc;
2087     HBITMAP hbm;
2088     int ret;
2089     void *ptr;
2090
2091     memset(dibinfo, 0, sizeof(dibinfo_buf));
2092     dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2093
2094     hdc = GetDC(NULL);
2095     ok(hdc != NULL, "GetDC failed?\n");
2096     hbm = CreateCompatibleBitmap(hdc, 1, 1);
2097     ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
2098
2099     /* Call GetDIBits to fill in bmiHeader.  */
2100     ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2101     ok(ret == 1, "GetDIBits failed\n");
2102     if (dibinfo->bmiHeader.biBitCount > 8)
2103     {
2104         ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2105             broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2106             "compression is %u (%d bpp)\n", dibinfo->bmiHeader.biCompression, dibinfo->bmiHeader.biBitCount );
2107
2108         if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2109         {
2110             ok( !bitmasks[0], "red mask is set\n" );
2111             ok( !bitmasks[1], "green mask is set\n" );
2112             ok( !bitmasks[2], "blue mask is set\n" );
2113
2114             /* test with NULL bits pointer and correct bpp */
2115             dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2116             ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2117             ok(ret == 1, "GetDIBits failed\n");
2118
2119             ok( bitmasks[0] != 0, "red mask is not set\n" );
2120             ok( bitmasks[1] != 0, "green mask is not set\n" );
2121             ok( bitmasks[2] != 0, "blue mask is not set\n" );
2122             ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2123
2124             /* test with valid bits pointer */
2125             memset(dibinfo, 0, sizeof(dibinfo_buf));
2126             dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2127             ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2128             ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2129             dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2130             ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2131             ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2132
2133             ok( bitmasks[0] != 0, "red mask is not set\n" );
2134             ok( bitmasks[1] != 0, "green mask is not set\n" );
2135             ok( bitmasks[2] != 0, "blue mask is not set\n" );
2136             ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2137
2138             /* now with bits and 0 lines */
2139             memset(dibinfo, 0, sizeof(dibinfo_buf));
2140             dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2141             dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2142             SetLastError(0xdeadbeef);
2143             ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2144             ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2145
2146             ok( !bitmasks[0], "red mask is set\n" );
2147             ok( !bitmasks[1], "green mask is set\n" );
2148             ok( !bitmasks[2], "blue mask is set\n" );
2149             ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2150
2151             memset(bitmasks, 0, 3*sizeof(DWORD));
2152             dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2153             ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2154             ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2155
2156             ok( bitmasks[0] != 0, "red mask is not set\n" );
2157             ok( bitmasks[1] != 0, "green mask is not set\n" );
2158             ok( bitmasks[2] != 0, "blue mask is not set\n" );
2159             ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2160         }
2161     }
2162     else skip("bitmap in colortable mode, skipping BI_BITFIELDS tests\n");
2163
2164     DeleteObject(hbm);
2165
2166     /* same thing now with a 32-bpp DIB section */
2167
2168     dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2169     dibinfo->bmiHeader.biWidth = 1;
2170     dibinfo->bmiHeader.biHeight = 1;
2171     dibinfo->bmiHeader.biPlanes = 1;
2172     dibinfo->bmiHeader.biBitCount = 32;
2173     dibinfo->bmiHeader.biCompression = BI_RGB;
2174     dibinfo->bmiHeader.biSizeImage = 0;
2175     dibinfo->bmiHeader.biXPelsPerMeter = 0;
2176     dibinfo->bmiHeader.biYPelsPerMeter = 0;
2177     dibinfo->bmiHeader.biClrUsed = 0;
2178     dibinfo->bmiHeader.biClrImportant = 0;
2179     bitmasks[0] = 0x0000ff;
2180     bitmasks[1] = 0x00ff00;
2181     bitmasks[2] = 0xff0000;
2182     hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2183     ok( hbm != 0, "failed to create bitmap\n" );
2184
2185     memset(dibinfo, 0, sizeof(dibinfo_buf));
2186     dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2187     ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2188     ok(ret == 1, "GetDIBits failed\n");
2189     ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2190
2191     ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2192         broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2193         "compression is %u\n", dibinfo->bmiHeader.biCompression );
2194     ok( !bitmasks[0], "red mask is set\n" );
2195     ok( !bitmasks[1], "green mask is set\n" );
2196     ok( !bitmasks[2], "blue mask is set\n" );
2197
2198     dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2199     ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2200     ok(ret == 1, "GetDIBits failed\n");
2201     ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2202     ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2203         broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2204         "compression is %u\n", dibinfo->bmiHeader.biCompression );
2205     if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2206     {
2207         ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
2208         ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2209         ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
2210     }
2211     ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2212
2213     DeleteObject(hbm);
2214
2215     dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2216     dibinfo->bmiHeader.biWidth = 1;
2217     dibinfo->bmiHeader.biHeight = 1;
2218     dibinfo->bmiHeader.biPlanes = 1;
2219     dibinfo->bmiHeader.biBitCount = 32;
2220     dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2221     dibinfo->bmiHeader.biSizeImage = 0;
2222     dibinfo->bmiHeader.biXPelsPerMeter = 0;
2223     dibinfo->bmiHeader.biYPelsPerMeter = 0;
2224     dibinfo->bmiHeader.biClrUsed = 0;
2225     dibinfo->bmiHeader.biClrImportant = 0;
2226     bitmasks[0] = 0x0000ff;
2227     bitmasks[1] = 0x00ff00;
2228     bitmasks[2] = 0xff0000;
2229     hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2230     ok( hbm != 0, "failed to create bitmap\n" );
2231
2232     if (hbm)
2233     {
2234         memset(dibinfo, 0, sizeof(dibinfo_buf));
2235         dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2236         ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2237         ok(ret == 1, "GetDIBits failed\n");
2238
2239         ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
2240             "compression is %u\n", dibinfo->bmiHeader.biCompression );
2241         ok( !bitmasks[0], "red mask is set\n" );
2242         ok( !bitmasks[1], "green mask is set\n" );
2243         ok( !bitmasks[2], "blue mask is set\n" );
2244
2245         dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2246         ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2247         ok(ret == 1, "GetDIBits failed\n");
2248         ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
2249         ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2250         ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
2251         ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2252
2253         DeleteObject(hbm);
2254     }
2255
2256     /* 24-bpp DIB sections don't have bitfields */
2257
2258     dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2259     dibinfo->bmiHeader.biWidth = 1;
2260     dibinfo->bmiHeader.biHeight = 1;
2261     dibinfo->bmiHeader.biPlanes = 1;
2262     dibinfo->bmiHeader.biBitCount = 24;
2263     dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2264     dibinfo->bmiHeader.biSizeImage = 0;
2265     dibinfo->bmiHeader.biXPelsPerMeter = 0;
2266     dibinfo->bmiHeader.biYPelsPerMeter = 0;
2267     dibinfo->bmiHeader.biClrUsed = 0;
2268     dibinfo->bmiHeader.biClrImportant = 0;
2269     hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2270     ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
2271     dibinfo->bmiHeader.biCompression = BI_RGB;
2272     hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2273     ok( hbm != 0, "failed to create bitmap\n" );
2274
2275     memset(dibinfo, 0, sizeof(dibinfo_buf));
2276     dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2277     ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2278     ok(ret == 1, "GetDIBits failed\n");
2279     ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2280
2281     ok( dibinfo->bmiHeader.biCompression == BI_RGB,
2282         "compression is %u\n", dibinfo->bmiHeader.biCompression );
2283     ok( !bitmasks[0], "red mask is set\n" );
2284     ok( !bitmasks[1], "green mask is set\n" );
2285     ok( !bitmasks[2], "blue mask is set\n" );
2286
2287     dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2288     ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2289     ok(ret == 1, "GetDIBits failed\n");
2290     ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2291     ok( !bitmasks[0], "red mask is set\n" );
2292     ok( !bitmasks[1], "green mask is set\n" );
2293     ok( !bitmasks[2], "blue mask is set\n" );
2294     ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2295
2296     DeleteObject(hbm);
2297     ReleaseDC(NULL, hdc);
2298 }
2299
2300 static void test_select_object(void)
2301 {
2302     HDC hdc;
2303     HBITMAP hbm, hbm_old;
2304     INT planes, bpp, i;
2305     DWORD depths[] = {8, 15, 16, 24, 32};
2306     BITMAP bm;
2307     DWORD bytes;
2308
2309     hdc = GetDC(0);
2310     ok(hdc != 0, "GetDC(0) failed\n");
2311     hbm = CreateCompatibleBitmap(hdc, 10, 10);
2312     ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2313
2314     hbm_old = SelectObject(hdc, hbm);
2315     ok(hbm_old == 0, "SelectObject should fail\n");
2316
2317     DeleteObject(hbm);
2318     ReleaseDC(0, hdc);
2319
2320     hdc = CreateCompatibleDC(0);
2321     ok(hdc != 0, "GetDC(0) failed\n");
2322     hbm = CreateCompatibleBitmap(hdc, 10, 10);
2323     ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2324
2325     hbm_old = SelectObject(hdc, hbm);
2326     ok(hbm_old != 0, "SelectObject failed\n");
2327     hbm_old = SelectObject(hdc, hbm_old);
2328     ok(hbm_old == hbm, "SelectObject failed\n");
2329
2330     DeleteObject(hbm);
2331
2332     /* test an 1-bpp bitmap */
2333     planes = GetDeviceCaps(hdc, PLANES);
2334     bpp = 1;
2335
2336     hbm = CreateBitmap(10, 10, planes, bpp, NULL);
2337     ok(hbm != 0, "CreateBitmap failed\n");
2338
2339     hbm_old = SelectObject(hdc, hbm);
2340     ok(hbm_old != 0, "SelectObject failed\n");
2341     hbm_old = SelectObject(hdc, hbm_old);
2342     ok(hbm_old == hbm, "SelectObject failed\n");
2343
2344     DeleteObject(hbm);
2345
2346     for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
2347         /* test a color bitmap to dc bpp matching */
2348         planes = GetDeviceCaps(hdc, PLANES);
2349         bpp = GetDeviceCaps(hdc, BITSPIXEL);
2350
2351         hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
2352         ok(hbm != 0, "CreateBitmap failed\n");
2353
2354         hbm_old = SelectObject(hdc, hbm);
2355         if(depths[i] == bpp ||
2356           (bpp == 16 && depths[i] == 15)        /* 16 and 15 bpp are compatible */
2357           ) {
2358             ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
2359             SelectObject(hdc, hbm_old);
2360         } else {
2361             ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
2362         }
2363
2364         memset(&bm, 0xAA, sizeof(bm));
2365         bytes = GetObject(hbm, sizeof(bm), &bm);
2366         ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2367         ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2368         ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
2369         ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
2370         ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2371         ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
2372         if(depths[i] == 15) {
2373             ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
2374         } else {
2375             ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2376         }
2377         ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2378
2379         DeleteObject(hbm);
2380     }
2381
2382     DeleteDC(hdc);
2383 }
2384
2385 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
2386 {
2387     INT ret;
2388     BITMAP bm;
2389
2390     ret = GetObjectType(hbmp);
2391     ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
2392
2393     ret = GetObject(hbmp, 0, 0);
2394     ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
2395
2396     memset(&bm, 0xDA, sizeof(bm));
2397     SetLastError(0xdeadbeef);
2398     ret = GetObject(hbmp, sizeof(bm), &bm);
2399     if (!ret) /* XP, only for curObj2 */ return;
2400     ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
2401     ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2402     ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2403     ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2404     ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2405     ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2406     ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2407     ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2408 }
2409
2410 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2411
2412 static void test_CreateBitmap(void)
2413 {
2414     BITMAP bmp;
2415     HDC screenDC = GetDC(0);
2416     HDC hdc = CreateCompatibleDC(screenDC);
2417     UINT i, expect = 0;
2418
2419     /* all of these are the stock monochrome bitmap */
2420     HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2421     HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2422     HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2423     HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2424     HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2425     HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2426
2427     /* these 2 are not the stock monochrome bitmap */
2428     HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2429     HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2430
2431     HBITMAP old1 = SelectObject(hdc, bm2);
2432     HBITMAP old2 = SelectObject(screenDC, bm3);
2433     SelectObject(hdc, old1);
2434     SelectObject(screenDC, old2);
2435
2436     ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2437        "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2438        bm, bm1, bm4, bm5, curObj1, old1);
2439     ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2440 todo_wine
2441     ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
2442     ok(old2 == 0, "old2 %p\n", old2);
2443
2444     test_mono_1x1_bmp(bm);
2445     test_mono_1x1_bmp(bm1);
2446     test_mono_1x1_bmp(bm2);
2447     test_mono_1x1_bmp(bm3);
2448     test_mono_1x1_bmp(bm4);
2449     test_mono_1x1_bmp(bm5);
2450     test_mono_1x1_bmp(old1);
2451     test_mono_1x1_bmp(curObj1);
2452
2453     DeleteObject(bm);
2454     DeleteObject(bm1);
2455     DeleteObject(bm2);
2456     DeleteObject(bm3);
2457     DeleteObject(bm4);
2458     DeleteObject(bm5);
2459
2460     DeleteDC(hdc);
2461     ReleaseDC(0, screenDC);
2462
2463     /* show that Windows ignores the provided bm.bmWidthBytes */
2464     bmp.bmType = 0;
2465     bmp.bmWidth = 1;
2466     bmp.bmHeight = 1;
2467     bmp.bmWidthBytes = 28;
2468     bmp.bmPlanes = 1;
2469     bmp.bmBitsPixel = 1;
2470     bmp.bmBits = NULL;
2471     bm = CreateBitmapIndirect(&bmp);
2472     ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2473     test_mono_1x1_bmp(bm);
2474     DeleteObject(bm);
2475
2476     /* Test how the bmBitsPixel field is treated */
2477     for(i = 1; i <= 33; i++) {
2478         bmp.bmType = 0;
2479         bmp.bmWidth = 1;
2480         bmp.bmHeight = 1;
2481         bmp.bmWidthBytes = 28;
2482         bmp.bmPlanes = 1;
2483         bmp.bmBitsPixel = i;
2484         bmp.bmBits = NULL;
2485         SetLastError(0xdeadbeef);
2486         bm = CreateBitmapIndirect(&bmp);
2487         if(i > 32) {
2488             DWORD error = GetLastError();
2489             ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
2490             ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2491             DeleteObject(bm);
2492             continue;
2493         }
2494         ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2495         GetObject(bm, sizeof(bmp), &bmp);
2496         if(i == 1) {
2497             expect = 1;
2498         } else if(i <= 4) {
2499             expect = 4;
2500         } else if(i <= 8) {
2501             expect = 8;
2502         } else if(i <= 16) {
2503             expect = 16;
2504         } else if(i <= 24) {
2505             expect = 24;
2506         } else if(i <= 32) {
2507             expect = 32;
2508         }
2509         ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2510            i, bmp.bmBitsPixel, expect);
2511         DeleteObject(bm);
2512     }
2513 }
2514
2515 static void test_bitmapinfoheadersize(void)
2516 {
2517     HBITMAP hdib;
2518     BITMAPINFO bmi;
2519     BITMAPCOREINFO bci;
2520     HDC hdc = GetDC(0);
2521
2522     memset(&bmi, 0, sizeof(BITMAPINFO));
2523     bmi.bmiHeader.biHeight = 100;
2524     bmi.bmiHeader.biWidth = 512;
2525     bmi.bmiHeader.biBitCount = 24;
2526     bmi.bmiHeader.biPlanes = 1;
2527
2528     bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2529
2530     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2531     ok(hdib == NULL, "CreateDIBSection succeeded\n");
2532
2533     bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2534
2535     SetLastError(0xdeadbeef);
2536     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2537     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2538     DeleteObject(hdib);
2539
2540     bmi.bmiHeader.biSize++;
2541
2542     SetLastError(0xdeadbeef);
2543     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2544     ok(hdib != NULL ||
2545        broken(!hdib), /* Win98, WinMe */
2546        "CreateDIBSection error %d\n", GetLastError());
2547     DeleteObject(hdib);
2548
2549     bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2550
2551     SetLastError(0xdeadbeef);
2552     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2553     ok(hdib != NULL ||
2554        broken(!hdib), /* Win98, WinMe */
2555        "CreateDIBSection error %d\n", GetLastError());
2556     DeleteObject(hdib);
2557
2558     bmi.bmiHeader.biSize++;
2559
2560     SetLastError(0xdeadbeef);
2561     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2562     ok(hdib != NULL ||
2563        broken(!hdib), /* Win98, WinMe */
2564        "CreateDIBSection error %d\n", GetLastError());
2565     DeleteObject(hdib);
2566
2567     bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2568
2569     SetLastError(0xdeadbeef);
2570     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2571     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2572     DeleteObject(hdib);
2573
2574     bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2575
2576     SetLastError(0xdeadbeef);
2577     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2578     ok(hdib != NULL ||
2579        broken(!hdib), /* Win95 */
2580        "CreateDIBSection error %d\n", GetLastError());
2581     DeleteObject(hdib);
2582
2583     memset(&bci, 0, sizeof(BITMAPCOREINFO));
2584     bci.bmciHeader.bcHeight = 100;
2585     bci.bmciHeader.bcWidth = 512;
2586     bci.bmciHeader.bcBitCount = 24;
2587     bci.bmciHeader.bcPlanes = 1;
2588
2589     bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2590
2591     hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2592     ok(hdib == NULL, "CreateDIBSection succeeded\n");
2593
2594     bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2595
2596     SetLastError(0xdeadbeef);
2597     hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2598     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2599     DeleteObject(hdib);
2600
2601     bci.bmciHeader.bcSize++;
2602
2603     hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2604     ok(hdib == NULL, "CreateDIBSection succeeded\n");
2605
2606     bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2607
2608     hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2609     ok(hdib == NULL, "CreateDIBSection succeeded\n");
2610
2611     ReleaseDC(0, hdc);
2612 }
2613
2614 static void test_get16dibits(void)
2615 {
2616     BYTE bits[4 * (16 / sizeof(BYTE))];
2617     HBITMAP hbmp;
2618     HDC screen_dc = GetDC(NULL);
2619     int ret;
2620     BITMAPINFO * info;
2621     int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2622     BYTE *p;
2623     int overwritten_bytes = 0;
2624
2625     memset(bits, 0, sizeof(bits));
2626     hbmp = CreateBitmap(2, 2, 1, 16, bits);
2627     ok(hbmp != NULL, "CreateBitmap failed\n");
2628
2629     info  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2630     assert(info);
2631
2632     memset(info, '!', info_len);
2633     memset(info, 0, sizeof(info->bmiHeader));
2634
2635     info->bmiHeader.biSize = sizeof(info->bmiHeader);
2636     info->bmiHeader.biWidth = 2;
2637     info->bmiHeader.biHeight = 2;
2638     info->bmiHeader.biPlanes = 1;
2639     info->bmiHeader.biCompression = BI_RGB;
2640
2641     ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2642     ok(ret != 0, "GetDIBits failed got %d\n", ret);
2643
2644     for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2645         if (*p != '!')
2646             overwritten_bytes++;
2647     ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2648
2649     HeapFree(GetProcessHeap(), 0, info);
2650     DeleteObject(hbmp);
2651     ReleaseDC(NULL, screen_dc);
2652 }
2653
2654 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2655                                DWORD dwRop, UINT32 expected, int line)
2656 {
2657     *srcBuffer = 0xFEDCBA98;
2658     *dstBuffer = 0x89ABCDEF;
2659     Rectangle(hdcSrc, 0, 0, 1, 1);  /* A null operation to ensure dibs are coerced to X11 */
2660     BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
2661     ok(expected == *dstBuffer,
2662         "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2663         dwRop, expected, *dstBuffer, line);
2664 }
2665
2666 static void test_BitBlt(void)
2667 {
2668     HBITMAP bmpDst, bmpSrc;
2669     HBITMAP oldDst, oldSrc;
2670     HDC hdcScreen, hdcDst, hdcSrc;
2671     UINT32 *dstBuffer, *srcBuffer;
2672     HBRUSH hBrush, hOldBrush;
2673     BITMAPINFO bitmapInfo;
2674
2675     memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2676     bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2677     bitmapInfo.bmiHeader.biWidth = 1;
2678     bitmapInfo.bmiHeader.biHeight = 1;
2679     bitmapInfo.bmiHeader.biPlanes = 1;
2680     bitmapInfo.bmiHeader.biBitCount = 32;
2681     bitmapInfo.bmiHeader.biCompression = BI_RGB;
2682     bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2683
2684     hdcScreen = CreateCompatibleDC(0);
2685     hdcDst = CreateCompatibleDC(hdcScreen);
2686     hdcSrc = CreateCompatibleDC(hdcDst);
2687
2688     /* Setup the destination dib section */
2689     bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
2690         NULL, 0);
2691     oldDst = SelectObject(hdcDst, bmpDst);
2692
2693     hBrush = CreateSolidBrush(0x012345678);
2694     hOldBrush = SelectObject(hdcDst, hBrush);
2695
2696     /* Setup the source dib section */
2697     bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
2698         NULL, 0);
2699     oldSrc = SelectObject(hdcSrc, bmpSrc);
2700
2701     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2702     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2703     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2704     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2705     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2706     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2707     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2708     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2709     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2710     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2711     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2712     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2713     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2714     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2715     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2716
2717     /* Tidy up */
2718     SelectObject(hdcSrc, oldSrc);
2719     DeleteObject(bmpSrc);
2720     DeleteDC(hdcSrc);
2721
2722     SelectObject(hdcDst, hOldBrush);
2723     DeleteObject(hBrush);
2724     SelectObject(hdcDst, oldDst);
2725     DeleteObject(bmpDst);
2726     DeleteDC(hdcDst);
2727
2728
2729     DeleteDC(hdcScreen);
2730 }
2731
2732 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2733                                    DWORD dwRop, UINT32 expected, int line)
2734 {
2735     *srcBuffer = 0xFEDCBA98;
2736     *dstBuffer = 0x89ABCDEF;
2737     StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
2738     ok(expected == *dstBuffer,
2739         "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2740         dwRop, expected, *dstBuffer, line);
2741 }
2742
2743 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, BITMAPINFO *dst_info, UINT32 *dstBuffer, UINT32 *srcBuffer,
2744                                      int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2745                                      int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2746                                      UINT32 *expected, int line)
2747 {
2748     int dst_size = get_dib_image_size( dst_info );
2749
2750     memset(dstBuffer, 0, dst_size);
2751     StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2752                hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
2753     ok(memcmp(dstBuffer, expected, dst_size) == 0,
2754         "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2755         "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2756         expected[0], expected[1], expected[2], expected[3],
2757         dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2758         nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2759         nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2760 }
2761
2762 static void test_StretchBlt(void)
2763 {
2764     HBITMAP bmpDst, bmpSrc;
2765     HBITMAP oldDst, oldSrc;
2766     HDC hdcScreen, hdcDst, hdcSrc;
2767     UINT32 *dstBuffer, *srcBuffer;
2768     HBRUSH hBrush, hOldBrush;
2769     BITMAPINFO biDst, biSrc;
2770     UINT32 expected[256];
2771     RGBQUAD colors[2];
2772
2773     memset(&biDst, 0, sizeof(BITMAPINFO));
2774     biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2775     biDst.bmiHeader.biWidth = 16;
2776     biDst.bmiHeader.biHeight = -16;
2777     biDst.bmiHeader.biPlanes = 1;
2778     biDst.bmiHeader.biBitCount = 32;
2779     biDst.bmiHeader.biCompression = BI_RGB;
2780     memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
2781
2782     hdcScreen = CreateCompatibleDC(0);
2783     hdcDst = CreateCompatibleDC(hdcScreen);
2784     hdcSrc = CreateCompatibleDC(hdcDst);
2785
2786     /* Pixel Tests */
2787     bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2788         NULL, 0);
2789     oldDst = SelectObject(hdcDst, bmpDst);
2790
2791     bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2792         NULL, 0);
2793     oldSrc = SelectObject(hdcSrc, bmpSrc);
2794
2795     hBrush = CreateSolidBrush(0x012345678);
2796     hOldBrush = SelectObject(hdcDst, hBrush);
2797
2798     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2799     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2800     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2801     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2802     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2803     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2804     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2805     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2806     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2807     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2808     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2809     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2810     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2811     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2812     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2813
2814     SelectObject(hdcDst, hOldBrush);
2815     DeleteObject(hBrush);
2816
2817     /* Top-down to top-down tests */
2818     srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2819     srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2820
2821     memset( expected, 0, get_dib_image_size( &biDst ) );
2822     expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2823     expected[16] = 0xFEDCBA98, expected[17] = 0x76543210;
2824     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2825                              0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2826
2827     expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2828     expected[16] = 0x00000000, expected[17] = 0x00000000;
2829     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2830                              0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
2831
2832     expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
2833     expected[16] = 0xCAFED00D, expected[17] = 0xCAFED00D;
2834     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2835                              0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
2836
2837     /* This is an example of the dst width (height) == 1 exception, explored below */
2838     expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2839     expected[16] = 0x00000000, expected[17] = 0x00000000;
2840     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2841                              0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
2842
2843     expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2844     expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
2845     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2846                              0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2847
2848     expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2849     expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
2850     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2851                              1, 1, -2, -2, 0, 0, 2, 2, expected, __LINE__);
2852
2853     expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2854     expected[16] = 0x00000000, expected[17] = 0x00000000;
2855     todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2856                                        1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
2857
2858     expected[0] = 0x00000000, expected[1] = 0x00000000;
2859     expected[16] = 0x00000000, expected[17] = 0xCAFED00D, expected[18] = 0xFEEDFACE;
2860     expected[32] = 0x00000000, expected[33] = 0xFEDCBA98, expected[34] = 0x76543210;
2861
2862     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2863                              1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2864
2865     /* when dst width is 1 merge src width - 1 pixels */
2866     memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
2867     srcBuffer[0] = 0x0000ff00, srcBuffer[1] = 0x0000f0f0, srcBuffer[2] = 0x0000cccc, srcBuffer[3] = 0x0000aaaa;
2868     srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2869
2870     memset( expected, 0, get_dib_image_size( &biDst ) );
2871     expected[0] = srcBuffer[0];
2872     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2873                              0, 0, 1, 1, 0, 0, 2, 1, expected, __LINE__);
2874
2875     expected[0] = srcBuffer[0] & srcBuffer[1];
2876     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2877                              0, 0, 1, 1, 0, 0, 3, 1, expected, __LINE__);
2878
2879     expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
2880     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2881                              0, 0, 1, 1, 0, 0, 4, 1, expected, __LINE__);
2882
2883     /* this doesn't happen if the src width is -ve */
2884     expected[0] = srcBuffer[1] & srcBuffer[2];
2885     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2886                              0, 0, 1, 1, 2, 0, -2, 1, expected, __LINE__);
2887
2888     /* when dst width > 1 behaviour reverts to what one would expect */
2889     expected[0] = srcBuffer[0] & srcBuffer[1], expected[1] = srcBuffer[2] & srcBuffer[3];
2890     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2891                              0, 0, 2, 1, 0, 0, 4, 1, expected, __LINE__);
2892
2893     /* similarly in the vertical direction */
2894     memset( expected, 0, get_dib_image_size( &biDst ) );
2895     expected[0] = srcBuffer[0];
2896     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2897                              0, 0, 1, 1, 0, 0, 1, 2, expected, __LINE__);
2898
2899     /* check that it's the dst size in device units that needs to be 1 */
2900     SetMapMode( hdcDst, MM_ISOTROPIC );
2901     SetWindowExtEx( hdcDst, 200, 200, NULL );
2902     SetViewportExtEx( hdcDst, 100, 100, NULL );
2903
2904     expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
2905     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2906                              0, 0, 2, 2, 0, 0, 4, 1, expected, __LINE__);
2907     SetMapMode( hdcDst, MM_TEXT );
2908
2909     SelectObject(hdcDst, oldDst);
2910     DeleteObject(bmpDst);
2911
2912     /* Top-down to bottom-up tests */
2913     memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
2914     srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2915     srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2916
2917     biDst.bmiHeader.biHeight = 16;
2918     bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2919         NULL, 0);
2920     oldDst = SelectObject(hdcDst, bmpDst);
2921
2922     memset( expected, 0, get_dib_image_size( &biDst ) );
2923
2924     expected[224] = 0xFEDCBA98, expected[225] = 0x76543210;
2925     expected[240] = 0xCAFED00D, expected[241] = 0xFEEDFACE;
2926     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2927                              0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2928
2929     expected[224] = 0xFEEDFACE, expected[225] = 0xCAFED00D;
2930     expected[240] = 0x76543210, expected[241] = 0xFEDCBA98;
2931     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2932                              0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2933
2934     SelectObject(hdcSrc, oldSrc);
2935     DeleteObject(bmpSrc);
2936
2937     /* Bottom-up to bottom-up tests */
2938     biSrc.bmiHeader.biHeight = 16;
2939     bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2940         NULL, 0);
2941     srcBuffer[224] = 0xCAFED00D, srcBuffer[225] = 0xFEEDFACE;
2942     srcBuffer[240] = 0xFEDCBA98, srcBuffer[241] = 0x76543210;
2943     oldSrc = SelectObject(hdcSrc, bmpSrc);
2944
2945     memset( expected, 0, get_dib_image_size( &biDst ) );
2946
2947     expected[224] = 0xCAFED00D, expected[225] = 0xFEEDFACE;
2948     expected[240] = 0xFEDCBA98, expected[241] = 0x76543210;
2949     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2950                              0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2951
2952     expected[224] = 0x76543210, expected[225] = 0xFEDCBA98;
2953     expected[240] = 0xFEEDFACE, expected[241] = 0xCAFED00D;
2954     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2955                              0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2956
2957     SelectObject(hdcDst, oldDst);
2958     DeleteObject(bmpDst);
2959
2960     /* Bottom-up to top-down tests */
2961     biDst.bmiHeader.biHeight = -16;
2962     bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2963         NULL, 0);
2964     oldDst = SelectObject(hdcDst, bmpDst);
2965
2966     memset( expected, 0, get_dib_image_size( &biDst ) );
2967     expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2968     expected[16] = 0xCAFED00D, expected[17] = 0xFEEDFACE;
2969     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2970                              0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2971
2972     expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2973     expected[16] = 0x76543210, expected[17] = 0xFEDCBA98;
2974     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2975                              0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2976
2977     SelectObject(hdcSrc, oldSrc);
2978     DeleteObject(bmpSrc);
2979
2980     biSrc.bmiHeader.biHeight = -2;
2981     biSrc.bmiHeader.biBitCount = 24;
2982     bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
2983     oldSrc = SelectObject(hdcSrc, bmpSrc);
2984
2985     memset( expected, 0, get_dib_image_size( &biDst ) );
2986     expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2987     expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2988     memcpy(dstBuffer, expected, 4 * sizeof(*dstBuffer));
2989     StretchBlt(hdcSrc, 0, 0, 4, 1, hdcDst, 0, 0, 4, 1, SRCCOPY );
2990     memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
2991     StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
2992     expected[0] = 0x00EDFACE, expected[1] = 0x00FED00D;
2993     expected[2] = 0x00543210, expected[3] = 0x00DCBA98;
2994     ok(!memcmp(dstBuffer, expected, 16),
2995        "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
2996         expected[0], expected[1], expected[2], expected[3],
2997         dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
2998
2999     expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3000     expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
3001     memcpy(srcBuffer, expected, 4 * sizeof(*dstBuffer));
3002     memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
3003     StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3004     expected[0] = 0x00EDFACE, expected[1] = 0x00D00DFE;
3005     expected[2] = 0x0010CAFE, expected[3] = 0x00765432;
3006     ok(!memcmp(dstBuffer, expected, 16),
3007        "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3008         expected[0], expected[1], expected[2], expected[3],
3009         dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3010
3011     SelectObject(hdcSrc, oldSrc);
3012     DeleteObject(bmpSrc);
3013
3014     biSrc.bmiHeader.biBitCount = 1;
3015     bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
3016     oldSrc = SelectObject(hdcSrc, bmpSrc);
3017     *((DWORD *)colors + 0) = 0x123456;
3018     *((DWORD *)colors + 1) = 0x335577;
3019     SetDIBColorTable( hdcSrc, 0, 2, colors );
3020     srcBuffer[0] = 0x55555555;
3021     memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
3022     SetTextColor( hdcDst, 0 );
3023     SetBkColor( hdcDst, 0 );
3024     StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3025     expected[0] = expected[2] = 0x00123456;
3026     expected[1] = expected[3] = 0x00335577;
3027     ok(!memcmp(dstBuffer, expected, 16),
3028        "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3029         expected[0], expected[1], expected[2], expected[3],
3030         dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3031
3032     SelectObject(hdcSrc, oldSrc);
3033     DeleteObject(bmpSrc);
3034
3035     bmpSrc = CreateBitmap( 16, 16, 1, 1, 0 );
3036     oldSrc = SelectObject(hdcSrc, bmpSrc);
3037     SetPixel( hdcSrc, 0, 0, 0 );
3038     SetPixel( hdcSrc, 1, 0, 0xffffff );
3039     SetPixel( hdcSrc, 2, 0, 0xffffff );
3040     SetPixel( hdcSrc, 3, 0, 0 );
3041     memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
3042     SetTextColor( hdcDst, RGB(0x22,0x44,0x66) );
3043     SetBkColor( hdcDst, RGB(0x65,0x43,0x21) );
3044     StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3045     expected[0] = expected[3] = 0x00224466;
3046     expected[1] = expected[2] = 0x00654321;
3047     ok(!memcmp(dstBuffer, expected, 16),
3048        "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3049         expected[0], expected[1], expected[2], expected[3],
3050         dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3051
3052     SelectObject(hdcSrc, oldSrc);
3053     DeleteObject(bmpSrc);
3054
3055     DeleteDC(hdcSrc);
3056
3057     SelectObject(hdcDst, oldDst);
3058     DeleteObject(bmpDst);
3059     DeleteDC(hdcDst);
3060
3061     DeleteDC(hdcScreen);
3062 }
3063
3064 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3065                                       DWORD dwRop, UINT32 expected, int line)
3066 {
3067     const UINT32 buffer[2] = { 0xFEDCBA98, 0 };
3068     BITMAPINFO bitmapInfo;
3069
3070     memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3071     bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3072     bitmapInfo.bmiHeader.biWidth = 2;
3073     bitmapInfo.bmiHeader.biHeight = 1;
3074     bitmapInfo.bmiHeader.biPlanes = 1;
3075     bitmapInfo.bmiHeader.biBitCount = 32;
3076     bitmapInfo.bmiHeader.biCompression = BI_RGB;
3077     bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer);
3078
3079     *dstBuffer = 0x89ABCDEF;
3080
3081     StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop);
3082     ok(expected == *dstBuffer,
3083         "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
3084         dwRop, expected, *dstBuffer, line);
3085 }
3086
3087 static void check_StretchDIBits_stretch(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3088                                         int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
3089                                         int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
3090                                         UINT32 expected[4], UINT32 legacy_expected[4], int line)
3091 {
3092     BITMAPINFO bitmapInfo;
3093
3094     memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3095     bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3096     bitmapInfo.bmiHeader.biWidth = 2;
3097     bitmapInfo.bmiHeader.biHeight = -2;
3098     bitmapInfo.bmiHeader.biPlanes = 1;
3099     bitmapInfo.bmiHeader.biBitCount = 32;
3100     bitmapInfo.bmiHeader.biCompression = BI_RGB;
3101
3102     memset(dstBuffer, 0, 16);
3103     StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
3104                   nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3105                   srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
3106     ok(memcmp(dstBuffer, expected, 16) == 0,
3107         "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
3108         "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
3109         expected[0], expected[1], expected[2], expected[3],
3110         dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
3111         nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3112         nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
3113 }
3114
3115 static void test_StretchDIBits(void)
3116 {
3117     HBITMAP bmpDst;
3118     HBITMAP oldDst;
3119     HDC hdcScreen, hdcDst;
3120     UINT32 *dstBuffer, srcBuffer[4];
3121     HBRUSH hBrush, hOldBrush;
3122     BITMAPINFO biDst;
3123     UINT32 expected[4], legacy_expected[4];
3124
3125     memset(&biDst, 0, sizeof(BITMAPINFO));
3126     biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3127     biDst.bmiHeader.biWidth = 2;
3128     biDst.bmiHeader.biHeight = -2;
3129     biDst.bmiHeader.biPlanes = 1;
3130     biDst.bmiHeader.biBitCount = 32;
3131     biDst.bmiHeader.biCompression = BI_RGB;
3132
3133     hdcScreen = CreateCompatibleDC(0);
3134     hdcDst = CreateCompatibleDC(hdcScreen);
3135
3136     /* Pixel Tests */
3137     bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3138         NULL, 0);
3139     oldDst = SelectObject(hdcDst, bmpDst);
3140
3141     hBrush = CreateSolidBrush(0x012345678);
3142     hOldBrush = SelectObject(hdcDst, hBrush);
3143
3144     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3145     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3146     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3147     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3148     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3149     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3150     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3151     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3152     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3153     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3154     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3155     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3156     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3157     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3158     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3159
3160     SelectObject(hdcDst, hOldBrush);
3161     DeleteObject(hBrush);
3162
3163     /* Top-down destination tests */
3164     srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3165     srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
3166
3167     expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
3168     expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
3169     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3170                                 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
3171
3172     expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3173     expected[2] = 0x00000000, expected[3] = 0x00000000;
3174     legacy_expected[0] = 0xFEDCBA98, legacy_expected[1] = 0x00000000;
3175     legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
3176     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3177                                 0, 0, 1, 1, 0, 0, 1, 1, expected, legacy_expected, __LINE__);
3178
3179     expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
3180     expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
3181     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3182                                 0, 0, 2, 2, 0, 0, 1, 1, expected, expected, __LINE__);
3183
3184     expected[0] = 0x42441000, expected[1] = 0x00000000;
3185     expected[2] = 0x00000000, expected[3] = 0x00000000;
3186     legacy_expected[0] = 0x00543210, legacy_expected[1] = 0x00000000;
3187     legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
3188     todo_wine check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3189                                 0, 0, 1, 1, 0, 0, 2, 2, expected, legacy_expected, __LINE__);
3190
3191     expected[0] = 0x00000000, expected[1] = 0x00000000;
3192     expected[2] = 0x00000000, expected[3] = 0x00000000;
3193     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3194                                 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
3195
3196     expected[0] = 0x00000000, expected[1] = 0x00000000;
3197     expected[2] = 0x00000000, expected[3] = 0x00000000;
3198     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3199                                 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
3200
3201     expected[0] = 0x00000000, expected[1] = 0x00000000;
3202     expected[2] = 0x00000000, expected[3] = 0x00000000;
3203     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3204                                 1, 1, -2, -2, 1, 1, -2, -2, expected, expected, __LINE__);
3205
3206     expected[0] = 0x00000000, expected[1] = 0x00000000;
3207     expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
3208     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3209                                 1, 1, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
3210
3211     SelectObject(hdcDst, oldDst);
3212     DeleteObject(bmpDst);
3213
3214     /* Bottom up destination tests */
3215     biDst.bmiHeader.biHeight = 2;
3216     bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3217         NULL, 0);
3218     oldDst = SelectObject(hdcDst, bmpDst);
3219
3220     expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3221     expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
3222     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3223                                 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
3224
3225     /* Tidy up */
3226     SelectObject(hdcDst, oldDst);
3227     DeleteObject(bmpDst);
3228     DeleteDC(hdcDst);
3229
3230     DeleteDC(hdcScreen);
3231 }
3232
3233 static void test_GdiAlphaBlend(void)
3234 {
3235     /* test out-of-bound parameters for GdiAlphaBlend */
3236     HDC hdcNull;
3237
3238     HDC hdcDst;
3239     HBITMAP bmpDst;
3240     HBITMAP oldDst;
3241
3242     BITMAPINFO bmi;
3243     HDC hdcSrc;
3244     HBITMAP bmpSrc;
3245     HBITMAP oldSrc;
3246     LPVOID bits;
3247
3248     BLENDFUNCTION blend;
3249
3250     if (!pGdiAlphaBlend)
3251     {
3252         win_skip("GdiAlphaBlend() is not implemented\n");
3253         return;
3254     }
3255
3256     hdcNull = GetDC(NULL);
3257     hdcDst = CreateCompatibleDC(hdcNull);
3258     bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
3259     hdcSrc = CreateCompatibleDC(hdcNull);
3260
3261     memset(&bmi, 0, sizeof(bmi));  /* as of Wine 0.9.44 we require the src to be a DIB section */
3262     bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
3263     bmi.bmiHeader.biHeight = 20;
3264     bmi.bmiHeader.biWidth = 20;
3265     bmi.bmiHeader.biBitCount = 32;
3266     bmi.bmiHeader.biPlanes = 1;
3267     bmi.bmiHeader.biCompression = BI_RGB;
3268     bmpSrc = CreateDIBSection(hdcDst, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3269     ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3270
3271     oldDst = SelectObject(hdcDst, bmpDst);
3272     oldSrc = SelectObject(hdcSrc, bmpSrc);
3273
3274     blend.BlendOp = AC_SRC_OVER;
3275     blend.BlendFlags = 0;
3276     blend.SourceConstantAlpha = 128;
3277     blend.AlphaFormat = 0;
3278
3279     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend), TRUE, BOOL, "%d");
3280     SetLastError(0xdeadbeef);
3281     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), FALSE, BOOL, "%d");
3282     expect_eq(GetLastError(), ERROR_INVALID_PARAMETER, int, "%d");
3283     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), FALSE, BOOL, "%d");
3284     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend), FALSE, BOOL, "%d");
3285     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
3286     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
3287
3288     SetWindowOrgEx(hdcSrc, -10, -10, NULL);
3289     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), TRUE, BOOL, "%d");
3290     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), TRUE, BOOL, "%d");
3291     SetMapMode(hdcSrc, MM_ANISOTROPIC);
3292     ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
3293     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend), TRUE, BOOL, "%d");
3294     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend), TRUE, BOOL, "%d");
3295
3296     SetLastError(0xdeadbeef);
3297     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend), FALSE, BOOL, "%d");
3298     expect_eq(GetLastError(), 0xdeadbeef, int, "%d");
3299
3300     SelectObject(hdcDst, oldDst);
3301     SelectObject(hdcSrc, oldSrc);
3302     DeleteObject(bmpSrc);
3303     DeleteObject(bmpDst);
3304     DeleteDC(hdcDst);
3305     DeleteDC(hdcSrc);
3306
3307     ReleaseDC(NULL, hdcNull);
3308
3309 }
3310
3311 static void test_clipping(void)
3312 {
3313     HBITMAP bmpDst;
3314     HBITMAP bmpSrc;
3315     HRGN hRgn;
3316     LPVOID bits;
3317     BOOL result;
3318
3319     HDC hdcDst = CreateCompatibleDC( NULL );
3320     HDC hdcSrc = CreateCompatibleDC( NULL );
3321
3322     BITMAPINFO bmpinfo={{0}};
3323     bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3324     bmpinfo.bmiHeader.biWidth = 100;
3325     bmpinfo.bmiHeader.biHeight = 100;
3326     bmpinfo.bmiHeader.biPlanes = 1;
3327     bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3328     bmpinfo.bmiHeader.biCompression = BI_RGB;
3329
3330     bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3331     ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3332     SelectObject( hdcDst, bmpDst );
3333
3334     bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3335     ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3336     SelectObject( hdcSrc, bmpSrc );
3337
3338     result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3339     ok(result, "BitBlt failed\n");
3340
3341     hRgn = CreateRectRgn( 0,0,0,0 );
3342     SelectClipRgn( hdcDst, hRgn );
3343
3344     result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3345     ok(result, "BitBlt failed\n");
3346
3347     DeleteObject( bmpDst );
3348     DeleteObject( bmpSrc );
3349     DeleteObject( hRgn );
3350     DeleteDC( hdcDst );
3351     DeleteDC( hdcSrc );
3352 }
3353
3354 static void test_32bit_bitmap_blt(void)
3355 {
3356     BITMAPINFO biDst;
3357     HBITMAP bmpSrc, bmpDst;
3358     HBITMAP oldSrc, oldDst;
3359     HDC hdcSrc, hdcDst, hdcScreen;
3360     UINT32 *dstBuffer;
3361     DWORD colorSrc = 0x11223344;
3362
3363     memset(&biDst, 0, sizeof(BITMAPINFO));
3364     biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3365     biDst.bmiHeader.biWidth = 2;
3366     biDst.bmiHeader.biHeight = -2;
3367     biDst.bmiHeader.biPlanes = 1;
3368     biDst.bmiHeader.biBitCount = 32;
3369     biDst.bmiHeader.biCompression = BI_RGB;
3370
3371     hdcScreen = CreateCompatibleDC(0);
3372     if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3373     {
3374         DeleteDC(hdcScreen);
3375         trace("Skipping 32-bit DDB test\n");
3376         return;
3377     }
3378
3379     hdcSrc = CreateCompatibleDC(hdcScreen);
3380     bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3381     oldSrc = SelectObject(hdcSrc, bmpSrc);
3382
3383     hdcDst = CreateCompatibleDC(hdcScreen);
3384     bmpDst = CreateDIBSection(hdcDst, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3385     oldDst = SelectObject(hdcDst, bmpDst);
3386
3387     StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3388     ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3389
3390     /* Tidy up */
3391     SelectObject(hdcDst, oldDst);
3392     DeleteObject(bmpDst);
3393     DeleteDC(hdcDst);
3394
3395     SelectObject(hdcSrc, oldSrc);
3396     DeleteObject(bmpSrc);
3397     DeleteDC(hdcSrc);
3398
3399     DeleteDC(hdcScreen);
3400 }
3401
3402 /*
3403  * Used by test_GetDIBits_top_down to create the bitmap to test against.
3404  */
3405 static void setup_picture(char *picture, int bpp)
3406 {
3407     int i;
3408
3409     switch(bpp)
3410     {
3411         case 16:
3412         case 32:
3413             /*Set the first byte in each pixel to the index of that pixel.*/
3414             for (i = 0; i < 4; i++)
3415                 picture[i * (bpp / 8)] = i;
3416             break;
3417         case 24:
3418             picture[0] = 0;
3419             picture[3] = 1;
3420             /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
3421             picture[8] = 2;
3422             picture[11] = 3;
3423             break;
3424     }
3425 }
3426
3427 static void test_GetDIBits_top_down(int bpp)
3428 {
3429     BITMAPINFO bi;
3430     HBITMAP bmptb, bmpbt;
3431     HDC hdc;
3432     int pictureOut[4];
3433     int *picture;
3434     int statusCode;
3435
3436     memset( &bi, 0, sizeof(bi) );
3437     bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
3438     bi.bmiHeader.biWidth=2;
3439     bi.bmiHeader.biHeight=2;
3440     bi.bmiHeader.biPlanes=1;
3441     bi.bmiHeader.biBitCount=bpp;
3442     bi.bmiHeader.biCompression=BI_RGB;
3443
3444     /*Get the device context for the screen.*/
3445     hdc = GetDC(NULL);
3446     ok(hdc != NULL, "Could not get a handle to a device context.\n");
3447
3448     /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
3449     bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3450     ok(bmpbt != NULL, "Could not create a DIB section.\n");
3451     /*Now that we have a pointer to the pixels, we write to them.*/
3452     setup_picture((char*)picture, bpp);
3453     /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
3454     bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
3455     bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3456     ok(bmptb != NULL, "Could not create a DIB section.\n");
3457     /*Write to this top to bottom bitmap.*/
3458     setup_picture((char*)picture, bpp);
3459
3460     bi.bmiHeader.biWidth = 1;
3461
3462     bi.bmiHeader.biHeight = 2;
3463     statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3464     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3465     /*Check the first byte of the pixel.*/
3466     ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3467     statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3468     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3469     ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3470     /*Check second scanline.*/
3471     statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3472     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3473     ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3474     statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3475     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3476     ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3477     /*Check both scanlines.*/
3478     statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3479     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3480     ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3481     ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3482     statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3483     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3484     ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3485     ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3486
3487     /*Make destination bitmap top-down.*/
3488     bi.bmiHeader.biHeight = -2;
3489     statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3490     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3491     ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3492     statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3493     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3494     ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3495     /*Check second scanline.*/
3496     statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3497     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3498     ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3499     statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3500     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3501     ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3502     /*Check both scanlines.*/
3503     statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3504     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3505     ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3506     ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3507     statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3508     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3509     ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3510     ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3511
3512     DeleteObject(bmpbt);
3513     DeleteObject(bmptb);
3514 }
3515
3516 static void test_GetSetDIBits_rtl(void)
3517 {
3518     HDC hdc, hdc_mem;
3519     HBITMAP bitmap, orig_bitmap;
3520     BITMAPINFO info;
3521     int ret;
3522     DWORD bits_1[8 * 8], bits_2[8 * 8];
3523
3524     if(!pSetLayout)
3525     {
3526         win_skip("Don't have SetLayout\n");
3527         return;
3528     }
3529
3530     hdc = GetDC( NULL );
3531     hdc_mem = CreateCompatibleDC( hdc );
3532     pSetLayout( hdc_mem, LAYOUT_LTR );
3533
3534     bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
3535     orig_bitmap = SelectObject( hdc_mem, bitmap );
3536     SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
3537     SelectObject( hdc_mem, orig_bitmap );
3538
3539     info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3540     info.bmiHeader.biWidth = 8;
3541     info.bmiHeader.biHeight = 8;
3542     info.bmiHeader.biPlanes = 1;
3543     info.bmiHeader.biBitCount = 32;
3544     info.bmiHeader.biCompression = BI_RGB;
3545
3546     /* First show that GetDIBits ignores the layout mode. */
3547
3548     ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3549     ok(ret == 8, "got %d\n", ret);
3550     ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
3551
3552     pSetLayout( hdc_mem, LAYOUT_RTL );
3553
3554     ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3555     ok(ret == 8, "got %d\n", ret);
3556
3557     ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3558
3559     /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
3560        followed by a GetDIBits and show that the bits remain unchanged. */
3561
3562     pSetLayout( hdc_mem, LAYOUT_LTR );
3563
3564     ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3565     ok(ret == 8, "got %d\n", ret);
3566     ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3567     ok(ret == 8, "got %d\n", ret);
3568     ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3569
3570     pSetLayout( hdc_mem, LAYOUT_RTL );
3571
3572     ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3573     ok(ret == 8, "got %d\n", ret);
3574     ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3575     ok(ret == 8, "got %d\n", ret);
3576     ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3577
3578     DeleteObject( bitmap );
3579     DeleteDC( hdc_mem );
3580     ReleaseDC( NULL, hdc );
3581 }
3582
3583 static void test_GetDIBits_scanlines(void)
3584 {
3585     BITMAPINFO *info;
3586     DWORD *dib_bits;
3587     HDC hdc = GetDC( NULL );
3588     HBITMAP dib;
3589     DWORD data[128], inverted_bits[64];
3590     int i, ret;
3591
3592     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
3593
3594     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
3595     info->bmiHeader.biWidth       = 8;
3596     info->bmiHeader.biHeight      = 8;
3597     info->bmiHeader.biPlanes      = 1;
3598     info->bmiHeader.biBitCount    = 32;
3599     info->bmiHeader.biCompression = BI_RGB;
3600
3601     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3602
3603     for (i = 0; i < 64; i++)
3604     {
3605         dib_bits[i] = i;
3606         inverted_bits[56 - (i & ~7) + (i & 7)] = i;
3607     }
3608
3609     /* b-u -> b-u */
3610
3611     memset( data, 0xaa, sizeof(data) );
3612
3613     ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3614     ok( ret == 8, "got %d\n", ret );
3615     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3616     memset( data, 0xaa, sizeof(data) );
3617
3618     ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3619     ok( ret == 5, "got %d\n", ret );
3620     ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
3621     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3622     memset( data, 0xaa, sizeof(data) );
3623
3624     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3625     ok( ret == 7, "got %d\n", ret );
3626     ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
3627     for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3628     memset( data, 0xaa, sizeof(data) );
3629
3630     ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3631     ok( ret == 1, "got %d\n", ret );
3632     for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3633     memset( data, 0xaa, sizeof(data) );
3634
3635     info->bmiHeader.biHeight = 16;
3636     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3637     ok( ret == 5, "got %d\n", ret );
3638     for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3639     ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
3640     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3641     memset( data, 0xaa, sizeof(data) );
3642
3643     ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3644     ok( ret == 6, "got %d\n", ret );
3645     for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3646     ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
3647     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3648     memset( data, 0xaa, sizeof(data) );
3649
3650     ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3651     ok( ret == 0, "got %d\n", ret );
3652     for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3653     for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3654     memset( data, 0xaa, sizeof(data) );
3655
3656     info->bmiHeader.biHeight = 5;
3657     ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3658     ok( ret == 2, "got %d\n", ret );
3659     ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
3660     for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3661     memset( data, 0xaa, sizeof(data) );
3662
3663     /* b-u -> t-d */
3664
3665     info->bmiHeader.biHeight = -8;
3666     ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3667     ok( ret == 8, "got %d\n", ret );
3668     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3669     memset( data, 0xaa, sizeof(data) );
3670
3671     ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3672     ok( ret == 5, "got %d\n", ret );
3673     ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
3674     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3675     memset( data, 0xaa, sizeof(data) );
3676
3677     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3678     ok( ret == 7, "got %d\n", ret );
3679     ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3680     for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3681     memset( data, 0xaa, sizeof(data) );
3682
3683     ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3684     ok( ret == 4, "got %d\n", ret );
3685     ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
3686     for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3687     memset( data, 0xaa, sizeof(data) );
3688
3689     ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3690     ok( ret == 5, "got %d\n", ret );
3691     ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3692     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3693     memset( data, 0xaa, sizeof(data) );
3694
3695     ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3696     ok( ret == 5, "got %d\n", ret );
3697     ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3698     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3699     memset( data, 0xaa, sizeof(data) );
3700
3701     info->bmiHeader.biHeight = -16;
3702     ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3703     ok( ret == 8, "got %d\n", ret );
3704     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3705     for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3706     memset( data, 0xaa, sizeof(data) );
3707
3708     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3709     ok( ret == 5, "got %d\n", ret );
3710     ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
3711     for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3712     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3713     memset( data, 0xaa, sizeof(data) );
3714
3715     ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3716     ok( ret == 8, "got %d\n", ret );
3717     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3718     for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3719     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3720     memset( data, 0xaa, sizeof(data) );
3721
3722     ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3723     ok( ret == 8, "got %d\n", ret );
3724     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3725     for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3726     for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3727     memset( data, 0xaa, sizeof(data) );
3728
3729     ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3730     ok( ret == 7, "got %d\n", ret );
3731     ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3732     for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3733     memset( data, 0xaa, sizeof(data) );
3734
3735     ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
3736     ok( ret == 1, "got %d\n", ret );
3737     for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3738     memset( data, 0xaa, sizeof(data) );
3739
3740     info->bmiHeader.biHeight = -5;
3741     ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3742     ok( ret == 2, "got %d\n", ret );
3743     ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
3744     for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3745     memset( data, 0xaa, sizeof(data) );
3746
3747     DeleteObject( dib );
3748
3749     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
3750     info->bmiHeader.biWidth       = 8;
3751     info->bmiHeader.biHeight      = -8;
3752     info->bmiHeader.biPlanes      = 1;
3753     info->bmiHeader.biBitCount    = 32;
3754     info->bmiHeader.biCompression = BI_RGB;
3755
3756     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3757
3758     for (i = 0; i < 64; i++) dib_bits[i] = i;
3759
3760     /* t-d -> t-d */
3761
3762     info->bmiHeader.biHeight = -8;
3763     ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3764     ok( ret == 8, "got %d\n", ret );
3765     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3766     memset( data, 0xaa, sizeof(data) );
3767
3768     ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3769     ok( ret == 5, "got %d\n", ret );
3770     ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
3771     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3772     memset( data, 0xaa, sizeof(data) );
3773
3774     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3775     ok( ret == 7, "got %d\n", ret );
3776     ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3777     for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3778     memset( data, 0xaa, sizeof(data) );
3779
3780     ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3781     ok( ret == 4, "got %d\n", ret );
3782     ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
3783     for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3784     memset( data, 0xaa, sizeof(data) );
3785
3786     ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3787     ok( ret == 5, "got %d\n", ret );
3788     ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3789     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3790     memset( data, 0xaa, sizeof(data) );
3791
3792     ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3793     ok( ret == 5, "got %d\n", ret );
3794     ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3795     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3796     memset( data, 0xaa, sizeof(data) );
3797
3798     info->bmiHeader.biHeight = -16;
3799     ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3800     ok( ret == 8, "got %d\n", ret );
3801     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3802     for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3803     memset( data, 0xaa, sizeof(data) );
3804
3805     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3806     ok( ret == 5, "got %d\n", ret );
3807     ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
3808     for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3809     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3810     memset( data, 0xaa, sizeof(data) );
3811
3812     ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3813     ok( ret == 8, "got %d\n", ret );
3814     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3815     for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3816     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3817     memset( data, 0xaa, sizeof(data) );
3818
3819     ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3820     ok( ret == 8, "got %d\n", ret );
3821     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3822     for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3823     for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3824     memset( data, 0xaa, sizeof(data) );
3825
3826     ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3827     ok( ret == 7, "got %d\n", ret );
3828     ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3829     for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3830     memset( data, 0xaa, sizeof(data) );
3831
3832     info->bmiHeader.biHeight = -5;
3833     ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3834     ok( ret == 2, "got %d\n", ret );
3835     ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
3836     for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3837     memset( data, 0xaa, sizeof(data) );
3838
3839
3840     /* t-d -> b-u */
3841
3842     info->bmiHeader.biHeight = 8;
3843
3844     ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3845     ok( ret == 8, "got %d\n", ret );
3846     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3847     memset( data, 0xaa, sizeof(data) );
3848
3849     ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3850     ok( ret == 5, "got %d\n", ret );
3851     ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
3852     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3853     memset( data, 0xaa, sizeof(data) );
3854
3855     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3856     ok( ret == 7, "got %d\n", ret );
3857     ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
3858     for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3859     memset( data, 0xaa, sizeof(data) );
3860
3861     ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3862     ok( ret == 1, "got %d\n", ret );
3863     for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3864     memset( data, 0xaa, sizeof(data) );
3865
3866     info->bmiHeader.biHeight = 16;
3867     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3868     ok( ret == 5, "got %d\n", ret );
3869     for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3870     ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
3871     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3872     memset( data, 0xaa, sizeof(data) );
3873
3874     ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3875     ok( ret == 6, "got %d\n", ret );
3876     for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3877     ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
3878     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3879     memset( data, 0xaa, sizeof(data) );
3880
3881     ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3882     ok( ret == 0, "got %d\n", ret );
3883     for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3884     for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3885     memset( data, 0xaa, sizeof(data) );
3886
3887     info->bmiHeader.biHeight = 5;
3888     ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3889     ok( ret == 2, "got %d\n", ret );
3890     ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
3891     for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3892     memset( data, 0xaa, sizeof(data) );
3893
3894     DeleteObject( dib );
3895
3896     ReleaseDC( NULL, hdc );
3897     HeapFree( GetProcessHeap(), 0, info );
3898 }
3899
3900
3901 static void test_SetDIBits(void)
3902 {
3903     BITMAPINFO *info;
3904     DWORD *dib_bits;
3905     HDC hdc = GetDC( NULL );
3906     DWORD data[128], inverted_data[128];
3907     HBITMAP dib;
3908     int i, ret;
3909
3910     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
3911
3912     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
3913     info->bmiHeader.biWidth       = 8;
3914     info->bmiHeader.biHeight      = 8;
3915     info->bmiHeader.biPlanes      = 1;
3916     info->bmiHeader.biBitCount    = 32;
3917     info->bmiHeader.biCompression = BI_RGB;
3918
3919     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3920     memset( dib_bits, 0xaa, 64 * 4 );
3921
3922     for (i = 0; i < 128; i++)
3923     {
3924         data[i] = i;
3925         inverted_data[120 - (i & ~7) + (i & 7)] = i;
3926     }
3927
3928     /* b-u -> b-u */
3929
3930     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3931     ok( ret == 8, "got %d\n", ret );
3932     ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
3933     memset( dib_bits, 0xaa, 64 * 4 );
3934
3935     ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3936     ok( ret == 5, "got %d\n", ret );
3937     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3938     ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
3939     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3940     memset( dib_bits, 0xaa, 64 * 4 );
3941
3942     /* top of dst is aligned with startscans down for the top of the src.
3943        Then starting from the bottom of src, lines rows are copied across. */
3944
3945     info->bmiHeader.biHeight = 16;
3946     ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3947     ok( ret == 12, "got %d\n", ret );
3948     ok( !memcmp( dib_bits, data + 56,  40 * 4 ), "bits differ\n");
3949     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3950     memset( dib_bits, 0xaa, 64 * 4 );
3951
3952     info->bmiHeader.biHeight = 5;
3953     ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3954     ok( ret == 2, "got %d\n", ret );
3955     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3956     ok( !memcmp( dib_bits + 32, data,  16 * 4 ), "bits differ\n");
3957     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3958     memset( dib_bits, 0xaa, 64 * 4 );
3959
3960     /* t-d -> b-u */
3961     info->bmiHeader.biHeight = -8;
3962     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3963     ok( ret == 8, "got %d\n", ret );
3964     ok( !memcmp( dib_bits, inverted_data + 64,  64 * 4 ), "bits differ\n");
3965     memset( dib_bits, 0xaa, 64 * 4 );
3966
3967     /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
3968        we copy lines rows from the top of the src */
3969
3970     ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3971     ok( ret == 5, "got %d\n", ret );
3972     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3973     ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
3974     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3975     memset( dib_bits, 0xaa, 64 * 4 );
3976
3977     info->bmiHeader.biHeight = -16;
3978     ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3979     ok( ret == 12, "got %d\n", ret );
3980     ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
3981     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3982     memset( dib_bits, 0xaa, 64 * 4 );
3983
3984     ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3985     ok( ret == 12, "got %d\n", ret );
3986     ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
3987     memset( dib_bits, 0xaa, 64 * 4 );
3988
3989     ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3990     ok( ret == 12, "got %d\n", ret );
3991     ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
3992     memset( dib_bits, 0xaa, 64 * 4 );
3993
3994     info->bmiHeader.biHeight = -5;
3995     ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3996     ok( ret == 2, "got %d\n", ret );
3997     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
3998     ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
3999     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4000     memset( dib_bits, 0xaa, 64 * 4 );
4001
4002     DeleteObject( dib );
4003
4004     info->bmiHeader.biHeight = -8;
4005
4006     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4007     memset( dib_bits, 0xaa, 16 * 16 * 4 );
4008
4009     /* t-d -> t-d */
4010
4011     /* like the t-d -> b-u case. */
4012
4013     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4014     ok( ret == 8, "got %d\n", ret );
4015     ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4016     memset( dib_bits, 0xaa, 64 * 4 );
4017
4018     ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4019     ok( ret == 5, "got %d\n", ret );
4020     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4021     ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
4022     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4023     memset( dib_bits, 0xaa, 64 * 4 );
4024
4025     info->bmiHeader.biHeight = -16;
4026     ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4027     ok( ret == 12, "got %d\n", ret );
4028     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4029     ok( !memcmp( dib_bits + 24, data,  40 * 4 ), "bits differ\n");
4030     memset( dib_bits, 0xaa, 64 * 4 );
4031
4032     info->bmiHeader.biHeight = -5;
4033     ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4034     ok( ret == 2, "got %d\n", ret );
4035     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4036     ok( !memcmp( dib_bits + 16, data,  16 * 4 ), "bits differ\n");
4037     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4038     memset( dib_bits, 0xaa, 64 * 4 );
4039
4040     /* b-u -> t-d */
4041     /* like the b-u -> b-u case */
4042
4043     info->bmiHeader.biHeight = 8;
4044     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4045     ok( ret == 8, "got %d\n", ret );
4046     ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4047     memset( dib_bits, 0xaa, 64 * 4 );
4048
4049     ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4050     ok( ret == 5, "got %d\n", ret );
4051     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4052     ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
4053     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4054     memset( dib_bits, 0xaa, 64 * 4 );
4055
4056     info->bmiHeader.biHeight = 16;
4057     ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4058     ok( ret == 12, "got %d\n", ret );
4059     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4060     ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
4061     memset( dib_bits, 0xaa, 64 * 4 );
4062
4063     info->bmiHeader.biHeight = 5;
4064     ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4065     ok( ret == 2, "got %d\n", ret );
4066     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4067     ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
4068     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4069     memset( dib_bits, 0xaa, 64 * 4 );
4070
4071     DeleteObject( dib );
4072     ReleaseDC( NULL, hdc );
4073     HeapFree( GetProcessHeap(), 0, info );
4074 }
4075
4076 static void test_SetDIBits_RLE4(void)
4077 {
4078     BITMAPINFO *info;
4079     DWORD *dib_bits;
4080     HDC hdc = GetDC( NULL );
4081     BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00,     /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
4082                            0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
4083                            0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00,     /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
4084                            0x00, 0x02, 0x01, 0x02, 0x05, 0x87,     /* dx=1, dy=2, 8, 7, 8, 7, 8 */
4085                            0x00, 0x01 };                           /* <eod> */
4086     HBITMAP dib;
4087     int i, ret;
4088     DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
4089                             0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
4090                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4091                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4092                             0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
4093                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4094                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4095                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4096
4097     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4098
4099     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4100     info->bmiHeader.biWidth       = 8;
4101     info->bmiHeader.biHeight      = 8;
4102     info->bmiHeader.biPlanes      = 1;
4103     info->bmiHeader.biBitCount    = 32;
4104     info->bmiHeader.biCompression = BI_RGB;
4105
4106     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4107     memset( dib_bits, 0xaa, 64 * 4 );
4108
4109     info->bmiHeader.biBitCount    = 4;
4110     info->bmiHeader.biCompression = BI_RLE4;
4111     info->bmiHeader.biSizeImage   = sizeof(rle4_data);
4112
4113     for (i = 0; i < 16; i++)
4114     {
4115         info->bmiColors[i].rgbRed      = i;
4116         info->bmiColors[i].rgbGreen    = i;
4117         info->bmiColors[i].rgbBlue     = i;
4118         info->bmiColors[i].rgbReserved = 0;
4119     }
4120
4121     ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
4122     ok( ret == 8, "got %d\n", ret );
4123     ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
4124     memset( dib_bits, 0xaa, 64 * 4 );
4125
4126     DeleteObject( dib );
4127     ReleaseDC( NULL, hdc );
4128     HeapFree( GetProcessHeap(), 0, info );
4129 }
4130
4131 static void test_SetDIBits_RLE8(void)
4132 {
4133     BITMAPINFO *info;
4134     DWORD *dib_bits;
4135     HDC hdc = GetDC( NULL );
4136     BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00,     /* 2, 2, 2, f0, f0, f0, f0, <eol> */
4137                            0x00, 0x03, 0x04, 0x05, 0x06, 0x00,     /* 4, 5, 6, <pad> */
4138                            0x00, 0x02, 0x01, 0x02, 0x05, 0x80,     /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4139                            0x00, 0x01 };                           /* <eod> */
4140     HBITMAP dib;
4141     int i, ret;
4142     DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4143                             0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4144                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4145                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
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                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4150     DWORD top_down[64]  = { 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, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4154                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4155                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4156                             0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4157                             0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4158
4159     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4160
4161     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4162     info->bmiHeader.biWidth       = 8;
4163     info->bmiHeader.biHeight      = 8;
4164     info->bmiHeader.biPlanes      = 1;
4165     info->bmiHeader.biBitCount    = 32;
4166     info->bmiHeader.biCompression = BI_RGB;
4167
4168     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4169     memset( dib_bits, 0xaa, 64 * 4 );
4170
4171     info->bmiHeader.biBitCount    = 8;
4172     info->bmiHeader.biCompression = BI_RLE8;
4173     info->bmiHeader.biSizeImage   = sizeof(rle8_data);
4174
4175     for (i = 0; i < 256; i++)
4176     {
4177         info->bmiColors[i].rgbRed      = i;
4178         info->bmiColors[i].rgbGreen    = i;
4179         info->bmiColors[i].rgbBlue     = i;
4180         info->bmiColors[i].rgbReserved = 0;
4181     }
4182
4183     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4184     ok( ret == 8, "got %d\n", ret );
4185     ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4186     memset( dib_bits, 0xaa, 64 * 4 );
4187
4188     /* startscan and lines are ignored, unless lines == 0 */
4189     ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4190     ok( ret == 8, "got %d\n", ret );
4191     ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4192     memset( dib_bits, 0xaa, 64 * 4 );
4193
4194     ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4195     ok( ret == 8, "got %d\n", ret );
4196     ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4197     memset( dib_bits, 0xaa, 64 * 4 );
4198
4199     ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4200     ok( ret == 0, "got %d\n", ret );
4201     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4202     memset( dib_bits, 0xaa, 64 * 4 );
4203
4204     /* reduce width to 4, left-hand side of dst is touched. */
4205     info->bmiHeader.biWidth = 4;
4206     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4207     ok( ret == 8, "got %d\n", ret );
4208     for (i = 0; i < 64; i++)
4209     {
4210         DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4211         ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4212     }
4213     memset( dib_bits, 0xaa, 64 * 4 );
4214
4215     /* Show that the top lines are aligned by adjusting the height of the src */
4216
4217     /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4218     info->bmiHeader.biWidth  = 8;
4219     info->bmiHeader.biHeight = 4;
4220     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4221     ok( ret == 4, "got %d\n", ret );
4222     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4223     ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4224     memset( dib_bits, 0xaa, 64 * 4 );
4225
4226     /* increase the height to 9 -> everything moves down one row. */
4227     info->bmiHeader.biHeight = 9;
4228     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4229     ok( ret == 9, "got %d\n", ret );
4230     ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4231     for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4232     memset( dib_bits, 0xaa, 64 * 4 );
4233
4234     /* top-down compressed dibs are invalid */
4235     info->bmiHeader.biHeight = -8;
4236     SetLastError( 0xdeadbeef );
4237     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4238     ok( ret == 0, "got %d\n", ret );
4239     ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4240     DeleteObject( dib );
4241
4242     /* top-down dst */
4243
4244     info->bmiHeader.biHeight      = -8;
4245     info->bmiHeader.biBitCount    = 32;
4246     info->bmiHeader.biCompression = BI_RGB;
4247     info->bmiHeader.biSizeImage   = 0;
4248
4249     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4250     memset( dib_bits, 0xaa, 16 * 16 * 4 );
4251
4252     info->bmiHeader.biHeight      = 8;
4253     info->bmiHeader.biBitCount    = 8;
4254     info->bmiHeader.biCompression = BI_RLE8;
4255     info->bmiHeader.biSizeImage   = sizeof(rle8_data);
4256
4257     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4258     ok( ret == 8, "got %d\n", ret );
4259     ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4260     memset( dib_bits, 0xaa, 64 * 4 );
4261
4262     info->bmiHeader.biHeight = 4;
4263     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4264     ok( ret == 4, "got %d\n", ret );
4265     ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4266     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4267     memset( dib_bits, 0xaa, 64 * 4 );
4268
4269     info->bmiHeader.biHeight = 9;
4270     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4271     ok( ret == 9, "got %d\n", ret );
4272     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4273     ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4274     memset( dib_bits, 0xaa, 64 * 4 );
4275
4276     DeleteObject( dib );
4277     ReleaseDC( NULL, hdc );
4278     HeapFree( GetProcessHeap(), 0, info );
4279 }
4280
4281 static void test_SetDIBitsToDevice(void)
4282 {
4283     BITMAPINFO *info;
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     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
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     HeapFree( GetProcessHeap(), 0, info );
4644 }
4645
4646 static void test_SetDIBitsToDevice_RLE8(void)
4647 {
4648     BITMAPINFO *info;
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     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
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     HeapFree( GetProcessHeap(), 0, info );
4865 }
4866
4867 START_TEST(bitmap)
4868 {
4869     HMODULE hdll;
4870
4871     hdll = GetModuleHandle("gdi32.dll");
4872     pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
4873     pSetLayout     = (void*)GetProcAddress(hdll, "SetLayout");
4874
4875     test_createdibitmap();
4876     test_dibsections();
4877     test_dib_formats();
4878     test_mono_dibsection();
4879     test_bitmap();
4880     test_bmBits();
4881     test_GetDIBits_selected_DIB(1);
4882     test_GetDIBits_selected_DIB(4);
4883     test_GetDIBits_selected_DIB(8);
4884     test_GetDIBits_selected_DDB(TRUE);
4885     test_GetDIBits_selected_DDB(FALSE);
4886     test_GetDIBits();
4887     test_GetDIBits_BI_BITFIELDS();
4888     test_select_object();
4889     test_CreateBitmap();
4890     test_BitBlt();
4891     test_StretchBlt();
4892     test_StretchDIBits();
4893     test_GdiAlphaBlend();
4894     test_32bit_bitmap_blt();
4895     test_bitmapinfoheadersize();
4896     test_get16dibits();
4897     test_clipping();
4898     test_GetDIBits_top_down(16);
4899     test_GetDIBits_top_down(24);
4900     test_GetDIBits_top_down(32);
4901     test_GetSetDIBits_rtl();
4902     test_GetDIBits_scanlines();
4903     test_SetDIBits();
4904     test_SetDIBits_RLE4();
4905     test_SetDIBits_RLE8();
4906     test_SetDIBitsToDevice();
4907     test_SetDIBitsToDevice_RLE8();
4908 }