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