gdi32/tests: Fix some test failures on old Windows versions.
[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     DeleteDC( memdc );
1159     DeleteObject( hbmp );
1160     ReleaseDC( 0, hdc );
1161     HeapFree( GetProcessHeap(), 0, bi );
1162 }
1163
1164 static void test_mono_dibsection(void)
1165 {
1166     HDC hdc, memdc;
1167     HBITMAP old_bm, mono_ds;
1168     char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
1169     BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
1170     RGBQUAD *colors = pbmi->bmiColors;
1171     BYTE bits[10 * 4];
1172     BYTE *ds_bits;
1173     int num;
1174
1175     hdc = GetDC(0);
1176
1177     memdc = CreateCompatibleDC(hdc);
1178
1179     memset(pbmi, 0, sizeof(bmibuf));
1180     pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
1181     pbmi->bmiHeader.biHeight = 10;
1182     pbmi->bmiHeader.biWidth = 10;
1183     pbmi->bmiHeader.biBitCount = 1;
1184     pbmi->bmiHeader.biPlanes = 1;
1185     pbmi->bmiHeader.biCompression = BI_RGB;
1186     colors[0].rgbRed = 0xff;
1187     colors[0].rgbGreen = 0xff;
1188     colors[0].rgbBlue = 0xff;
1189     colors[1].rgbRed = 0x0;
1190     colors[1].rgbGreen = 0x0;
1191     colors[1].rgbBlue = 0x0;
1192
1193     /*
1194      * First dib section is 'inverted' ie color[0] is white, color[1] is black
1195      */
1196
1197     mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1198     ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1199     old_bm = SelectObject(memdc, mono_ds);
1200
1201     /* black border, white interior */
1202     Rectangle(memdc, 0, 0, 10, 10);
1203     ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1204     ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1205
1206     /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1207
1208     memset(bits, 0, sizeof(bits));
1209     bits[0] = 0xaa;
1210
1211     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1212     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1213
1214     /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1215
1216     colors[0].rgbRed = 0x0;
1217     colors[0].rgbGreen = 0x0;
1218     colors[0].rgbBlue = 0x0;
1219     colors[1].rgbRed = 0xff;
1220     colors[1].rgbGreen = 0xff;
1221     colors[1].rgbBlue = 0xff;
1222
1223     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1224     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1225
1226     SelectObject(memdc, old_bm);
1227     DeleteObject(mono_ds);
1228
1229     /*
1230      * Next dib section is 'normal' ie color[0] is black, color[1] is white
1231      */
1232
1233     colors[0].rgbRed = 0x0;
1234     colors[0].rgbGreen = 0x0;
1235     colors[0].rgbBlue = 0x0;
1236     colors[1].rgbRed = 0xff;
1237     colors[1].rgbGreen = 0xff;
1238     colors[1].rgbBlue = 0xff;
1239
1240     mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1241     ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1242     old_bm = SelectObject(memdc, mono_ds);
1243
1244     /* black border, white interior */
1245     Rectangle(memdc, 0, 0, 10, 10);
1246     ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
1247     ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
1248
1249     /* SetDIBitsToDevice with a normal bmi -> normal dib section */
1250
1251     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1252     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1253
1254     /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
1255
1256     colors[0].rgbRed = 0xff;
1257     colors[0].rgbGreen = 0xff;
1258     colors[0].rgbBlue = 0xff;
1259     colors[1].rgbRed = 0x0;
1260     colors[1].rgbGreen = 0x0;
1261     colors[1].rgbBlue = 0x0;
1262
1263     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1264     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1265
1266     /*
1267      * Take that 'normal' dibsection and change its colour table to an 'inverted' one
1268      */
1269
1270     colors[0].rgbRed = 0xff;
1271     colors[0].rgbGreen = 0xff;
1272     colors[0].rgbBlue = 0xff;
1273     colors[1].rgbRed = 0x0;
1274     colors[1].rgbGreen = 0x0;
1275     colors[1].rgbBlue = 0x0;
1276     num = SetDIBColorTable(memdc, 0, 2, colors);
1277     ok(num == 2, "num = %d\n", num);
1278
1279     /* black border, white interior */
1280     Rectangle(memdc, 0, 0, 10, 10);
1281     ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1282     ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1283
1284     /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1285
1286     memset(bits, 0, sizeof(bits));
1287     bits[0] = 0xaa;
1288
1289     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1290     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1291
1292     /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1293
1294     colors[0].rgbRed = 0x0;
1295     colors[0].rgbGreen = 0x0;
1296     colors[0].rgbBlue = 0x0;
1297     colors[1].rgbRed = 0xff;
1298     colors[1].rgbGreen = 0xff;
1299     colors[1].rgbBlue = 0xff;
1300
1301     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1302     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1303
1304     SelectObject(memdc, old_bm);
1305     DeleteObject(mono_ds);
1306
1307     /*
1308      * Now a dib section with a strange colour map just for fun.  This behaves just like an inverted one.
1309      */
1310  
1311     colors[0].rgbRed = 0xff;
1312     colors[0].rgbGreen = 0x0;
1313     colors[0].rgbBlue = 0x0;
1314     colors[1].rgbRed = 0xfe;
1315     colors[1].rgbGreen = 0x0;
1316     colors[1].rgbBlue = 0x0;
1317
1318     mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1319     ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1320     old_bm = SelectObject(memdc, mono_ds);
1321
1322     /* black border, white interior */
1323     Rectangle(memdc, 0, 0, 10, 10);
1324     ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1325     ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1326
1327     /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1328
1329     colors[0].rgbRed = 0x0;
1330     colors[0].rgbGreen = 0x0;
1331     colors[0].rgbBlue = 0x0;
1332     colors[1].rgbRed = 0xff;
1333     colors[1].rgbGreen = 0xff;
1334     colors[1].rgbBlue = 0xff;
1335
1336     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1337     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1338
1339     /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
1340
1341     colors[0].rgbRed = 0xff;
1342     colors[0].rgbGreen = 0xff;
1343     colors[0].rgbBlue = 0xff;
1344     colors[1].rgbRed = 0x0;
1345     colors[1].rgbGreen = 0x0;
1346     colors[1].rgbBlue = 0x0;
1347
1348     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1349     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1350
1351     SelectObject(memdc, old_bm);
1352     DeleteObject(mono_ds);
1353
1354     DeleteDC(memdc);
1355     ReleaseDC(0, hdc);
1356 }
1357
1358 static void test_bitmap(void)
1359 {
1360     char buf[256], buf_cmp[256];
1361     HBITMAP hbmp, hbmp_old;
1362     HDC hdc;
1363     BITMAP bm;
1364     BITMAP bma[2];
1365     INT ret;
1366
1367     hdc = CreateCompatibleDC(0);
1368     assert(hdc != 0);
1369
1370     SetLastError(0xdeadbeef);
1371     hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1372     if (!hbmp)
1373     {
1374         ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1375            GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1376            "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1377     }
1378     else
1379         DeleteObject(hbmp);
1380
1381     SetLastError(0xdeadbeef);
1382     hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1383     if (!hbmp)
1384     {
1385         ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1386            GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1387            "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1388     }
1389     else
1390         DeleteObject(hbmp);
1391
1392     SetLastError(0xdeadbeef);
1393     hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1394     ok(!hbmp, "CreateBitmap should fail\n");
1395     if (!hbmp)
1396         ok(GetLastError() == ERROR_INVALID_PARAMETER,
1397            "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1398     else
1399         DeleteObject(hbmp);
1400
1401     hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1402     assert(hbmp != NULL);
1403
1404     ret = GetObject(hbmp, sizeof(bm), &bm);
1405     ok(ret == sizeof(bm), "wrong size %d\n", ret);
1406
1407     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1408     ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1409     ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1410     ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1411     ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1412     ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1413     ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1414
1415     assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1416     assert(sizeof(buf) == sizeof(buf_cmp));
1417
1418     ret = GetBitmapBits(hbmp, 0, NULL);
1419     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1420
1421     memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1422     memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1423
1424     memset(buf, 0xAA, sizeof(buf));
1425     ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1426     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1427     ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1428
1429     hbmp_old = SelectObject(hdc, hbmp);
1430
1431     ret = GetObject(hbmp, sizeof(bm), &bm);
1432     ok(ret == sizeof(bm), "wrong size %d\n", ret);
1433
1434     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1435     ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1436     ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1437     ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1438     ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1439     ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1440     ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1441
1442     memset(buf, 0xAA, sizeof(buf));
1443     ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1444     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1445     ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1446
1447     hbmp_old = SelectObject(hdc, hbmp_old);
1448     ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1449
1450     /* test various buffer sizes for GetObject */
1451     ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
1452     ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1453
1454     ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1455     ok(ret == 0, "%d != 0\n", ret);
1456
1457     ret = GetObject(hbmp, 0, &bm);
1458     ok(ret == 0, "%d != 0\n", ret);
1459
1460     ret = GetObject(hbmp, 1, &bm);
1461     ok(ret == 0, "%d != 0\n", ret);
1462
1463     DeleteObject(hbmp);
1464     DeleteDC(hdc);
1465 }
1466
1467 static void test_bmBits(void)
1468 {
1469     BYTE bits[4];
1470     HBITMAP hbmp;
1471     BITMAP bmp;
1472
1473     memset(bits, 0, sizeof(bits));
1474     hbmp = CreateBitmap(2, 2, 1, 4, bits);
1475     ok(hbmp != NULL, "CreateBitmap failed\n");
1476
1477     memset(&bmp, 0xFF, sizeof(bmp));
1478     ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1479        "GetObject failed or returned a wrong structure size\n");
1480     ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1481
1482     DeleteObject(hbmp);
1483 }
1484
1485 static void test_GetDIBits_selected_DIB(UINT bpp)
1486 {
1487     HBITMAP dib;
1488     BITMAPINFO *info;
1489     BITMAPINFO *info2;
1490     void * bits;
1491     void * bits2;
1492     UINT dib_size, dib32_size;
1493     DWORD pixel;
1494     HDC dib_dc, dc;
1495     HBITMAP old_bmp;
1496     UINT i;
1497     int res;
1498
1499     info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1500     info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1501
1502     /* Create a DIB section with a color table */
1503
1504     info->bmiHeader.biSize          = sizeof(info->bmiHeader);
1505     info->bmiHeader.biWidth         = 32;
1506     info->bmiHeader.biHeight        = 32;
1507     info->bmiHeader.biPlanes        = 1;
1508     info->bmiHeader.biBitCount      = bpp;
1509     info->bmiHeader.biCompression   = BI_RGB;
1510     info->bmiHeader.biXPelsPerMeter = 0;
1511     info->bmiHeader.biYPelsPerMeter = 0;
1512     info->bmiHeader.biClrUsed       = 0;
1513     info->bmiHeader.biClrImportant  = 0;
1514
1515     for (i=0; i < (1u << bpp); i++)
1516     {
1517         BYTE c = i * (1 << (8 - bpp));
1518         info->bmiColors[i].rgbRed = c;
1519         info->bmiColors[i].rgbGreen = c;
1520         info->bmiColors[i].rgbBlue = c;
1521         info->bmiColors[i].rgbReserved = 0;
1522     }
1523
1524     dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1525     dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1526     dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1527
1528     /* Set the bits of the DIB section */
1529     for (i=0; i < dib_size; i++)
1530     {
1531         ((BYTE *)bits)[i] = i % 256;
1532     }
1533
1534     /* Select the DIB into a DC */
1535     dib_dc = CreateCompatibleDC(NULL);
1536     old_bmp = SelectObject(dib_dc, dib);
1537     dc = CreateCompatibleDC(NULL);
1538     bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
1539
1540     /* Copy the DIB attributes but not the color table */
1541     memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1542
1543     res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1544     ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1545
1546     /* Compare the color table and the bits */
1547     for (i=0; i < (1u << bpp); i++)
1548         ok( info->bmiColors[i].rgbRed      == info2->bmiColors[i].rgbRed   &&
1549             info->bmiColors[i].rgbGreen    == info2->bmiColors[i].rgbGreen &&
1550             info->bmiColors[i].rgbBlue     == info2->bmiColors[i].rgbBlue  &&
1551             info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1552             "color table entry %d differs (bpp %d)\n", i, bpp );
1553
1554     ok( !memcmp( bits, bits2, dib_size ), "bit mismatch (bpp %d)\n", bpp );
1555
1556     /* Test various combinations of lines = 0 and bits2 = NULL */
1557     memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1558     res = GetDIBits( dc, dib, 0, 0, bits2, info2, DIB_RGB_COLORS );
1559     ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1560     ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1561         "color table mismatch (bpp %d)\n", bpp );
1562
1563     memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1564     res = GetDIBits( dc, dib, 0, 0, NULL, info2, DIB_RGB_COLORS );
1565     ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1566     ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1567         "color table mismatch (bpp %d)\n", bpp );
1568
1569     memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1570     res = GetDIBits( dc, dib, 0, info->bmiHeader.biHeight, NULL, info2, DIB_RGB_COLORS );
1571     ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1572     ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1573         "color table mismatch (bpp %d)\n", bpp );
1574
1575     /* Map into a 32bit-DIB */
1576     info2->bmiHeader.biBitCount = 32;
1577     res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1578     ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1579
1580     /* Check if last pixel was set */
1581     pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
1582     ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
1583
1584     HeapFree(GetProcessHeap(), 0, bits2);
1585     DeleteDC(dc);
1586
1587     SelectObject(dib_dc, old_bmp);
1588     DeleteDC(dib_dc);
1589     DeleteObject(dib);
1590     HeapFree(GetProcessHeap(), 0, info2);
1591     HeapFree(GetProcessHeap(), 0, info);
1592 }
1593
1594 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1595 {
1596     HBITMAP ddb;
1597     BITMAPINFO *info;
1598     BITMAPINFO *info2;
1599     void * bits;
1600     void * bits2;
1601     HDC ddb_dc, dc;
1602     HBITMAP old_bmp;
1603     UINT width, height;
1604     UINT bpp;
1605     UINT i, j;
1606     int res;
1607
1608     info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1609     info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1610
1611     width = height = 16;
1612
1613     /* Create a DDB (device-dependent bitmap) */
1614     if (monochrome)
1615     {
1616         bpp = 1;
1617         ddb = CreateBitmap(width, height, 1, 1, NULL);
1618     }
1619     else
1620     {
1621         HDC screen_dc = GetDC(NULL);
1622         bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1623         ddb = CreateCompatibleBitmap(screen_dc, width, height);
1624         ReleaseDC(NULL, screen_dc);
1625     }
1626
1627     /* Set the pixels */
1628     ddb_dc = CreateCompatibleDC(NULL);
1629     old_bmp = SelectObject(ddb_dc, ddb);
1630     for (i = 0; i < width; i++)
1631     {
1632         for (j=0; j < height; j++)
1633         {
1634             BYTE c = (i * width + j) % 256;
1635             SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1636         }
1637     }
1638     SelectObject(ddb_dc, old_bmp);
1639
1640     info->bmiHeader.biSize = sizeof(info->bmiHeader);
1641     info->bmiHeader.biWidth = width;
1642     info->bmiHeader.biHeight = height;
1643     info->bmiHeader.biPlanes = 1;
1644     info->bmiHeader.biBitCount = bpp;
1645     info->bmiHeader.biCompression = BI_RGB;
1646
1647     dc = CreateCompatibleDC(NULL);
1648
1649     /* Fill in biSizeImage */
1650     GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1651     ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1652
1653     bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1654     bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1655
1656     /* Get the bits */
1657     res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1658     ok( res == height, "got %d (bpp %d)\n", res, bpp );
1659
1660     /* Copy the DIB attributes but not the color table */
1661     memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1662
1663     /* Select the DDB into another DC */
1664     old_bmp = SelectObject(ddb_dc, ddb);
1665
1666     /* Get the bits */
1667     res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1668     ok( res == height, "got %d (bpp %d)\n", res, bpp );
1669
1670     /* Compare the color table and the bits */
1671     if (bpp <= 8)
1672     {
1673         for (i=0; i < (1u << bpp); i++)
1674             ok( info->bmiColors[i].rgbRed      == info2->bmiColors[i].rgbRed   &&
1675                 info->bmiColors[i].rgbGreen    == info2->bmiColors[i].rgbGreen &&
1676                 info->bmiColors[i].rgbBlue     == info2->bmiColors[i].rgbBlue  &&
1677                 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1678                 "color table entry %d differs (bpp %d)\n", i, bpp );
1679     }
1680
1681     ok( !memcmp( bits, bits2, info->bmiHeader.biSizeImage ), "bit mismatch (bpp %d)\n", bpp );
1682
1683     /* Test the palette */
1684     if (info2->bmiHeader.biBitCount <= 8)
1685     {
1686         WORD *colors = (WORD*)info2->bmiColors;
1687
1688         /* Get the palette indices */
1689         res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1690         ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1691
1692         for (i = 0; i < (1 << info->bmiHeader.biBitCount); i++)
1693             ok( colors[i] == i, "%d: got %d (bpp %d)\n", i, colors[i], bpp );
1694     }
1695
1696     HeapFree(GetProcessHeap(), 0, bits2);
1697     HeapFree(GetProcessHeap(), 0, bits);
1698     DeleteDC(dc);
1699
1700     SelectObject(ddb_dc, old_bmp);
1701     DeleteDC(ddb_dc);
1702     DeleteObject(ddb);
1703     HeapFree(GetProcessHeap(), 0, info2);
1704     HeapFree(GetProcessHeap(), 0, info);
1705 }
1706
1707 static void test_GetDIBits(void)
1708 {
1709     /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1710     static const BYTE bmp_bits_1[16 * 2] =
1711     {
1712         0xff,0xff, 0,0, 0xff,0xff, 0,0,
1713         0xff,0xff, 0,0, 0xff,0xff, 0,0,
1714         0xff,0xff, 0,0, 0xff,0xff, 0,0,
1715         0xff,0xff, 0,0, 0xff,0xff, 0,0
1716     };
1717     /* 4-bytes aligned 1-bit DIB data: 16x16 */
1718     static const BYTE dib_bits_1[16 * 4] =
1719     {
1720         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1721         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1722         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1723         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1724     };
1725     /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1726     static const BYTE bmp_bits_24[16 * 16*3] =
1727     {
1728         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1729         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1730         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1731         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1732         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1733         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1734         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1735         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1736         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1737         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1738         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1739         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1740         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1741         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1742         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1743         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1744         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1745         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1746         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1747         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1748         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1749         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1750         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1751         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1752         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1753         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1754         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1755         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1756         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1757         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1758         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1759         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1760     };
1761     /* 4-bytes aligned 24-bit DIB data: 16x16 */
1762     static const BYTE dib_bits_24[16 * 16*3] =
1763     {
1764         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1765         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1766         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1767         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1768         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1769         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1770         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1771         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1772         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1773         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1774         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1775         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1776         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1777         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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     };
1797     HBITMAP hbmp;
1798     BITMAP bm;
1799     HDC hdc;
1800     int i, bytes, lines;
1801     BYTE buf[1024];
1802     char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1803     BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1804     RGBQUAD *colors = bi->bmiColors;
1805     PALETTEENTRY pal_ents[20];
1806
1807     hdc = GetDC(0);
1808
1809     /* 1-bit source bitmap data */
1810     hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1811     ok(hbmp != 0, "CreateBitmap failed\n");
1812
1813     memset(&bm, 0xAA, sizeof(bm));
1814     bytes = GetObject(hbmp, sizeof(bm), &bm);
1815     ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1816     ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1817     ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1818     ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1819     ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1820     ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1821     ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1822     ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1823
1824     bytes = GetBitmapBits(hbmp, 0, NULL);
1825     ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1826     bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1827     ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1828     ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1829
1830     /* retrieve 1-bit DIB data */
1831     memset(bi, 0, sizeof(*bi));
1832     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1833     bi->bmiHeader.biWidth = bm.bmWidth;
1834     bi->bmiHeader.biHeight = bm.bmHeight;
1835     bi->bmiHeader.biPlanes = 1;
1836     bi->bmiHeader.biBitCount = 1;
1837     bi->bmiHeader.biCompression = BI_RGB;
1838     bi->bmiHeader.biClrUsed = 37;
1839     bi->bmiHeader.biSizeImage = 0;
1840     memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1841     SetLastError(0xdeadbeef);
1842     lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1843     ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1844     ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1845        broken(GetLastError() == 0xdeadbeef), /* winnt */
1846        "wrong error %u\n", GetLastError());
1847     ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1848     ok(bi->bmiHeader.biClrUsed == 37 || broken(bi->bmiHeader.biClrUsed == 0),
1849        "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
1850
1851     memset(buf, 0xAA, sizeof(buf));
1852     SetLastError(0xdeadbeef);
1853     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1854     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1855        lines, bm.bmHeight, GetLastError());
1856     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1857     ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
1858
1859     /* the color table consists of black and white */
1860     ok(colors[0].rgbRed == 0 && colors[0].rgbGreen == 0 &&
1861        colors[0].rgbBlue == 0 && colors[0].rgbReserved == 0,
1862        "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1863        colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue, colors[0].rgbReserved);
1864     ok(colors[1].rgbRed == 0xff && colors[1].rgbGreen == 0xff &&
1865        colors[1].rgbBlue == 0xff && colors[1].rgbReserved == 0,
1866        "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1867        colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue, colors[1].rgbReserved);
1868     for (i = 2; i < 256; i++)
1869     {
1870         ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
1871            colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
1872            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1873            colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
1874     }
1875
1876     /* returned bits are DWORD aligned and upside down */
1877     ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1878
1879     /* Test the palette indices */
1880     memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1881     SetLastError(0xdeadbeef);
1882     lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1883     ok(((WORD*)colors)[0] == 0, "Color 0 is %d\n", ((WORD*)colors)[0]);
1884     ok(((WORD*)colors)[1] == 1, "Color 1 is %d\n", ((WORD*)colors)[1]);
1885     for (i = 2; i < 256; i++)
1886         ok(((WORD*)colors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)colors)[1]);
1887
1888     /* retrieve 24-bit DIB data */
1889     memset(bi, 0, sizeof(*bi));
1890     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1891     bi->bmiHeader.biWidth = bm.bmWidth;
1892     bi->bmiHeader.biHeight = bm.bmHeight;
1893     bi->bmiHeader.biPlanes = 1;
1894     bi->bmiHeader.biBitCount = 24;
1895     bi->bmiHeader.biCompression = BI_RGB;
1896     bi->bmiHeader.biClrUsed = 37;
1897     bi->bmiHeader.biSizeImage = 0;
1898     memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1899     memset(buf, 0xAA, sizeof(buf));
1900     SetLastError(0xdeadbeef);
1901     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1902     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1903        lines, bm.bmHeight, GetLastError());
1904     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1905     ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
1906
1907     /* the color table doesn't exist for 24-bit images */
1908     for (i = 0; i < 256; i++)
1909     {
1910         ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
1911            colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
1912            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1913            colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
1914     }
1915
1916     /* returned bits are DWORD aligned and upside down */
1917     ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1918     DeleteObject(hbmp);
1919
1920     /* 24-bit source bitmap data */
1921     hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1922     ok(hbmp != 0, "CreateBitmap failed\n");
1923     SetLastError(0xdeadbeef);
1924     bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1925     lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1926     ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1927        lines, bm.bmHeight, GetLastError());
1928
1929     memset(&bm, 0xAA, sizeof(bm));
1930     bytes = GetObject(hbmp, sizeof(bm), &bm);
1931     ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1932     ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1933     ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1934     ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1935     ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1936     ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1937     ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1938     ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1939
1940     bytes = GetBitmapBits(hbmp, 0, NULL);
1941     ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
1942     bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1943     ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1944        bm.bmWidthBytes * bm.bmHeight, bytes);
1945
1946     /* retrieve 1-bit DIB data */
1947     memset(bi, 0, sizeof(*bi));
1948     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1949     bi->bmiHeader.biWidth = bm.bmWidth;
1950     bi->bmiHeader.biHeight = bm.bmHeight;
1951     bi->bmiHeader.biPlanes = 1;
1952     bi->bmiHeader.biBitCount = 1;
1953     bi->bmiHeader.biCompression = BI_RGB;
1954     bi->bmiHeader.biClrUsed = 37;
1955     bi->bmiHeader.biSizeImage = 0;
1956     memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1957     memset(buf, 0xAA, sizeof(buf));
1958     SetLastError(0xdeadbeef);
1959     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1960     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1961        lines, bm.bmHeight, GetLastError());
1962     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1963     ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
1964
1965     /* the color table consists of black and white */
1966     ok(colors[0].rgbRed == 0 && colors[0].rgbGreen == 0 &&
1967        colors[0].rgbBlue == 0 && colors[0].rgbReserved == 0,
1968        "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1969        colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue, colors[0].rgbReserved);
1970     ok(colors[1].rgbRed == 0xff && colors[1].rgbGreen == 0xff &&
1971        colors[1].rgbBlue == 0xff && colors[1].rgbReserved == 0,
1972        "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1973        colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue, colors[1].rgbReserved);
1974     for (i = 2; i < 256; i++)
1975     {
1976         ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
1977            colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
1978            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1979            colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
1980     }
1981
1982     /* returned bits are DWORD aligned and upside down */
1983     ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1984
1985     /* Test the palette indices */
1986     memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
1987     SetLastError(0xdeadbeef);
1988     lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1989     ok(((WORD*)colors)[0] == 0, "Color 0 is %d\n", ((WORD*)colors)[0]);
1990     ok(((WORD*)colors)[1] == 1, "Color 1 is %d\n", ((WORD*)colors)[1]);
1991     for (i = 2; i < 256; i++)
1992         ok(((WORD*)colors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)colors)[i]);
1993
1994     /* retrieve 4-bit DIB data */
1995     memset(bi, 0, sizeof(*bi));
1996     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1997     bi->bmiHeader.biWidth = bm.bmWidth;
1998     bi->bmiHeader.biHeight = bm.bmHeight;
1999     bi->bmiHeader.biPlanes = 1;
2000     bi->bmiHeader.biBitCount = 4;
2001     bi->bmiHeader.biCompression = BI_RGB;
2002     bi->bmiHeader.biClrUsed = 37;
2003     bi->bmiHeader.biSizeImage = 0;
2004     memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2005     memset(buf, 0xAA, sizeof(buf));
2006     SetLastError(0xdeadbeef);
2007     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2008     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2009        lines, bm.bmHeight, GetLastError());
2010     ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2011
2012     GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2013
2014     for (i = 0; i < 16; i++)
2015     {
2016         RGBQUAD expect;
2017         int entry = i < 8 ? i : i + 4;
2018
2019         if(entry == 7) entry = 12;
2020         else if(entry == 12) entry = 7;
2021
2022         expect.rgbRed   = pal_ents[entry].peRed;
2023         expect.rgbGreen = pal_ents[entry].peGreen;
2024         expect.rgbBlue  = pal_ents[entry].peBlue;
2025         expect.rgbReserved = 0;
2026
2027         ok(!memcmp(colors + i, &expect, sizeof(expect)),
2028            "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2029            expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2030            colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2031     }
2032
2033     /* retrieve 8-bit DIB data */
2034     memset(bi, 0, sizeof(*bi));
2035     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2036     bi->bmiHeader.biWidth = bm.bmWidth;
2037     bi->bmiHeader.biHeight = bm.bmHeight;
2038     bi->bmiHeader.biPlanes = 1;
2039     bi->bmiHeader.biBitCount = 8;
2040     bi->bmiHeader.biCompression = BI_RGB;
2041     bi->bmiHeader.biClrUsed = 37;
2042     bi->bmiHeader.biSizeImage = 0;
2043     memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2044     memset(buf, 0xAA, sizeof(buf));
2045     SetLastError(0xdeadbeef);
2046     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2047     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2048        lines, bm.bmHeight, GetLastError());
2049     ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2050
2051     GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2052
2053     for (i = 0; i < 256; i++)
2054     {
2055         RGBQUAD expect;
2056
2057         if (i < 10 || i >= 246)
2058         {
2059             int entry = i < 10 ? i : i - 236;
2060             expect.rgbRed   = pal_ents[entry].peRed;
2061             expect.rgbGreen = pal_ents[entry].peGreen;
2062             expect.rgbBlue  = pal_ents[entry].peBlue;
2063         }
2064         else
2065         {
2066             expect.rgbRed   = (i & 0x07) << 5;
2067             expect.rgbGreen = (i & 0x38) << 2;
2068             expect.rgbBlue  =  i & 0xc0;
2069         }
2070         expect.rgbReserved = 0;
2071
2072         ok(!memcmp(colors + i, &expect, sizeof(expect)),
2073            "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2074            expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2075            colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2076     }
2077
2078     /* retrieve 24-bit DIB data */
2079     memset(bi, 0, sizeof(*bi));
2080     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2081     bi->bmiHeader.biWidth = bm.bmWidth;
2082     bi->bmiHeader.biHeight = bm.bmHeight;
2083     bi->bmiHeader.biPlanes = 1;
2084     bi->bmiHeader.biBitCount = 24;
2085     bi->bmiHeader.biCompression = BI_RGB;
2086     bi->bmiHeader.biClrUsed = 37;
2087     bi->bmiHeader.biSizeImage = 0;
2088     memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2089     memset(buf, 0xAA, sizeof(buf));
2090     SetLastError(0xdeadbeef);
2091     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2092     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2093        lines, bm.bmHeight, GetLastError());
2094     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2095     ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2096
2097     /* the color table doesn't exist for 24-bit images */
2098     for (i = 0; i < 256; i++)
2099     {
2100         ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2101            colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2102            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2103            colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2104     }
2105
2106     /* returned bits are DWORD aligned and upside down */
2107     ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2108     DeleteObject(hbmp);
2109
2110     ReleaseDC(0, hdc);
2111 }
2112
2113 static void test_GetDIBits_BI_BITFIELDS(void)
2114 {
2115     /* Try a screen resolution detection technique
2116      * from the September 1999 issue of Windows Developer's Journal
2117      * which seems to be in widespread use.
2118      * http://www.lesher.ws/highcolor.html
2119      * http://www.lesher.ws/vidfmt.c
2120      * It hinges on being able to retrieve the bitmaps
2121      * for the three primary colors in non-paletted 16 bit mode.
2122      */
2123     char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
2124     DWORD bits[32];
2125     LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
2126     DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
2127     HDC hdc;
2128     HBITMAP hbm;
2129     int ret;
2130     void *ptr;
2131
2132     memset(dibinfo, 0, sizeof(dibinfo_buf));
2133     dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2134
2135     hdc = GetDC(NULL);
2136     ok(hdc != NULL, "GetDC failed?\n");
2137     hbm = CreateCompatibleBitmap(hdc, 1, 1);
2138     ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
2139
2140     /* Call GetDIBits to fill in bmiHeader.  */
2141     ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2142     ok(ret == 1, "GetDIBits failed\n");
2143     if (dibinfo->bmiHeader.biBitCount > 8)
2144     {
2145         ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2146             broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2147             "compression is %u (%d bpp)\n", dibinfo->bmiHeader.biCompression, dibinfo->bmiHeader.biBitCount );
2148
2149         if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2150         {
2151             ok( !bitmasks[0], "red mask is set\n" );
2152             ok( !bitmasks[1], "green mask is set\n" );
2153             ok( !bitmasks[2], "blue mask is set\n" );
2154
2155             /* test with NULL bits pointer and correct bpp */
2156             dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2157             ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2158             ok(ret == 1, "GetDIBits failed\n");
2159
2160             ok( bitmasks[0] != 0, "red mask is not set\n" );
2161             ok( bitmasks[1] != 0, "green mask is not set\n" );
2162             ok( bitmasks[2] != 0, "blue mask is not set\n" );
2163             ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2164
2165             /* test with valid bits pointer */
2166             memset(dibinfo, 0, sizeof(dibinfo_buf));
2167             dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2168             ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2169             ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2170             dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2171             ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2172             ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2173
2174             ok( bitmasks[0] != 0, "red mask is not set\n" );
2175             ok( bitmasks[1] != 0, "green mask is not set\n" );
2176             ok( bitmasks[2] != 0, "blue mask is not set\n" );
2177             ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2178
2179             /* now with bits and 0 lines */
2180             memset(dibinfo, 0, sizeof(dibinfo_buf));
2181             dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2182             dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2183             SetLastError(0xdeadbeef);
2184             ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2185             ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2186
2187             ok( !bitmasks[0], "red mask is set\n" );
2188             ok( !bitmasks[1], "green mask is set\n" );
2189             ok( !bitmasks[2], "blue mask is set\n" );
2190             ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2191
2192             memset(bitmasks, 0, 3*sizeof(DWORD));
2193             dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2194             ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2195             ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2196
2197             ok( bitmasks[0] != 0, "red mask is not set\n" );
2198             ok( bitmasks[1] != 0, "green mask is not set\n" );
2199             ok( bitmasks[2] != 0, "blue mask is not set\n" );
2200             ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2201         }
2202     }
2203     else skip("bitmap in colortable mode, skipping BI_BITFIELDS tests\n");
2204
2205     DeleteObject(hbm);
2206
2207     /* same thing now with a 32-bpp DIB section */
2208
2209     dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2210     dibinfo->bmiHeader.biWidth = 1;
2211     dibinfo->bmiHeader.biHeight = 1;
2212     dibinfo->bmiHeader.biPlanes = 1;
2213     dibinfo->bmiHeader.biBitCount = 32;
2214     dibinfo->bmiHeader.biCompression = BI_RGB;
2215     dibinfo->bmiHeader.biSizeImage = 0;
2216     dibinfo->bmiHeader.biXPelsPerMeter = 0;
2217     dibinfo->bmiHeader.biYPelsPerMeter = 0;
2218     dibinfo->bmiHeader.biClrUsed = 0;
2219     dibinfo->bmiHeader.biClrImportant = 0;
2220     bitmasks[0] = 0x0000ff;
2221     bitmasks[1] = 0x00ff00;
2222     bitmasks[2] = 0xff0000;
2223     hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2224     ok( hbm != 0, "failed to create bitmap\n" );
2225
2226     memset(dibinfo, 0, sizeof(dibinfo_buf));
2227     dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2228     ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2229     ok(ret == 1, "GetDIBits failed\n");
2230     ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2231
2232     ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2233         broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2234         "compression is %u\n", dibinfo->bmiHeader.biCompression );
2235     ok( !bitmasks[0], "red mask is set\n" );
2236     ok( !bitmasks[1], "green mask is set\n" );
2237     ok( !bitmasks[2], "blue mask is set\n" );
2238
2239     dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2240     ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2241     ok(ret == 1, "GetDIBits failed\n");
2242     ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2243     ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2244         broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2245         "compression is %u\n", dibinfo->bmiHeader.biCompression );
2246     if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2247     {
2248         ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
2249         ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2250         ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
2251     }
2252     ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2253
2254     DeleteObject(hbm);
2255
2256     dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2257     dibinfo->bmiHeader.biWidth = 1;
2258     dibinfo->bmiHeader.biHeight = 1;
2259     dibinfo->bmiHeader.biPlanes = 1;
2260     dibinfo->bmiHeader.biBitCount = 32;
2261     dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2262     dibinfo->bmiHeader.biSizeImage = 0;
2263     dibinfo->bmiHeader.biXPelsPerMeter = 0;
2264     dibinfo->bmiHeader.biYPelsPerMeter = 0;
2265     dibinfo->bmiHeader.biClrUsed = 0;
2266     dibinfo->bmiHeader.biClrImportant = 0;
2267     bitmasks[0] = 0x0000ff;
2268     bitmasks[1] = 0x00ff00;
2269     bitmasks[2] = 0xff0000;
2270     hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2271     ok( hbm != 0, "failed to create bitmap\n" );
2272
2273     if (hbm)
2274     {
2275         memset(dibinfo, 0, sizeof(dibinfo_buf));
2276         dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2277         ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2278         ok(ret == 1, "GetDIBits failed\n");
2279
2280         ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
2281             "compression is %u\n", dibinfo->bmiHeader.biCompression );
2282         ok( !bitmasks[0], "red mask is set\n" );
2283         ok( !bitmasks[1], "green mask is set\n" );
2284         ok( !bitmasks[2], "blue mask is set\n" );
2285
2286         dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2287         ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2288         ok(ret == 1, "GetDIBits failed\n");
2289         ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
2290         ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2291         ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
2292         ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2293
2294         DeleteObject(hbm);
2295     }
2296
2297     /* 24-bpp DIB sections don't have bitfields */
2298
2299     dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2300     dibinfo->bmiHeader.biWidth = 1;
2301     dibinfo->bmiHeader.biHeight = 1;
2302     dibinfo->bmiHeader.biPlanes = 1;
2303     dibinfo->bmiHeader.biBitCount = 24;
2304     dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2305     dibinfo->bmiHeader.biSizeImage = 0;
2306     dibinfo->bmiHeader.biXPelsPerMeter = 0;
2307     dibinfo->bmiHeader.biYPelsPerMeter = 0;
2308     dibinfo->bmiHeader.biClrUsed = 0;
2309     dibinfo->bmiHeader.biClrImportant = 0;
2310     hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2311     ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
2312     dibinfo->bmiHeader.biCompression = BI_RGB;
2313     hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2314     ok( hbm != 0, "failed to create bitmap\n" );
2315
2316     memset(dibinfo, 0, sizeof(dibinfo_buf));
2317     dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2318     ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2319     ok(ret == 1, "GetDIBits failed\n");
2320     ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2321
2322     ok( dibinfo->bmiHeader.biCompression == BI_RGB,
2323         "compression is %u\n", dibinfo->bmiHeader.biCompression );
2324     ok( !bitmasks[0], "red mask is set\n" );
2325     ok( !bitmasks[1], "green mask is set\n" );
2326     ok( !bitmasks[2], "blue mask is set\n" );
2327
2328     dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2329     ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2330     ok(ret == 1, "GetDIBits failed\n");
2331     ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
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     ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2336
2337     DeleteObject(hbm);
2338     ReleaseDC(NULL, hdc);
2339 }
2340
2341 static void test_select_object(void)
2342 {
2343     HDC hdc;
2344     HBITMAP hbm, hbm_old;
2345     INT planes, bpp, i;
2346     DWORD depths[] = {8, 15, 16, 24, 32};
2347     BITMAP bm;
2348     DWORD bytes;
2349
2350     hdc = GetDC(0);
2351     ok(hdc != 0, "GetDC(0) failed\n");
2352     hbm = CreateCompatibleBitmap(hdc, 10, 10);
2353     ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2354
2355     hbm_old = SelectObject(hdc, hbm);
2356     ok(hbm_old == 0, "SelectObject should fail\n");
2357
2358     DeleteObject(hbm);
2359     ReleaseDC(0, hdc);
2360
2361     hdc = CreateCompatibleDC(0);
2362     ok(hdc != 0, "GetDC(0) failed\n");
2363     hbm = CreateCompatibleBitmap(hdc, 10, 10);
2364     ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2365
2366     hbm_old = SelectObject(hdc, hbm);
2367     ok(hbm_old != 0, "SelectObject failed\n");
2368     hbm_old = SelectObject(hdc, hbm_old);
2369     ok(hbm_old == hbm, "SelectObject failed\n");
2370
2371     DeleteObject(hbm);
2372
2373     /* test an 1-bpp bitmap */
2374     planes = GetDeviceCaps(hdc, PLANES);
2375     bpp = 1;
2376
2377     hbm = CreateBitmap(10, 10, planes, bpp, NULL);
2378     ok(hbm != 0, "CreateBitmap failed\n");
2379
2380     hbm_old = SelectObject(hdc, hbm);
2381     ok(hbm_old != 0, "SelectObject failed\n");
2382     hbm_old = SelectObject(hdc, hbm_old);
2383     ok(hbm_old == hbm, "SelectObject failed\n");
2384
2385     DeleteObject(hbm);
2386
2387     for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
2388         /* test a color bitmap to dc bpp matching */
2389         planes = GetDeviceCaps(hdc, PLANES);
2390         bpp = GetDeviceCaps(hdc, BITSPIXEL);
2391
2392         hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
2393         ok(hbm != 0, "CreateBitmap failed\n");
2394
2395         hbm_old = SelectObject(hdc, hbm);
2396         if(depths[i] == bpp ||
2397           (bpp == 16 && depths[i] == 15)        /* 16 and 15 bpp are compatible */
2398           ) {
2399             ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
2400             SelectObject(hdc, hbm_old);
2401         } else {
2402             ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
2403         }
2404
2405         memset(&bm, 0xAA, sizeof(bm));
2406         bytes = GetObject(hbm, sizeof(bm), &bm);
2407         ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2408         ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2409         ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
2410         ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
2411         ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2412         ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
2413         if(depths[i] == 15) {
2414             ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
2415         } else {
2416             ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2417         }
2418         ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2419
2420         DeleteObject(hbm);
2421     }
2422
2423     DeleteDC(hdc);
2424 }
2425
2426 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
2427 {
2428     INT ret;
2429     BITMAP bm;
2430
2431     ret = GetObjectType(hbmp);
2432     ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
2433
2434     ret = GetObject(hbmp, 0, 0);
2435     ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
2436
2437     memset(&bm, 0xDA, sizeof(bm));
2438     SetLastError(0xdeadbeef);
2439     ret = GetObject(hbmp, sizeof(bm), &bm);
2440     if (!ret) /* XP, only for curObj2 */ return;
2441     ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
2442     ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2443     ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2444     ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2445     ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2446     ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2447     ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2448     ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2449 }
2450
2451 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2452
2453 static void test_CreateBitmap(void)
2454 {
2455     BITMAP bmp;
2456     HDC screenDC = GetDC(0);
2457     HDC hdc = CreateCompatibleDC(screenDC);
2458     UINT i, expect = 0;
2459
2460     /* all of these are the stock monochrome bitmap */
2461     HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2462     HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2463     HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2464     HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2465     HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2466     HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2467
2468     /* these 2 are not the stock monochrome bitmap */
2469     HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2470     HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2471
2472     HBITMAP old1 = SelectObject(hdc, bm2);
2473     HBITMAP old2 = SelectObject(screenDC, bm3);
2474     SelectObject(hdc, old1);
2475     SelectObject(screenDC, old2);
2476
2477     ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2478        "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2479        bm, bm1, bm4, bm5, curObj1, old1);
2480     ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2481 todo_wine
2482     ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
2483     ok(old2 == 0, "old2 %p\n", old2);
2484
2485     test_mono_1x1_bmp(bm);
2486     test_mono_1x1_bmp(bm1);
2487     test_mono_1x1_bmp(bm2);
2488     test_mono_1x1_bmp(bm3);
2489     test_mono_1x1_bmp(bm4);
2490     test_mono_1x1_bmp(bm5);
2491     test_mono_1x1_bmp(old1);
2492     test_mono_1x1_bmp(curObj1);
2493
2494     DeleteObject(bm);
2495     DeleteObject(bm1);
2496     DeleteObject(bm2);
2497     DeleteObject(bm3);
2498     DeleteObject(bm4);
2499     DeleteObject(bm5);
2500
2501     DeleteDC(hdc);
2502     ReleaseDC(0, screenDC);
2503
2504     /* show that Windows ignores the provided bm.bmWidthBytes */
2505     bmp.bmType = 0;
2506     bmp.bmWidth = 1;
2507     bmp.bmHeight = 1;
2508     bmp.bmWidthBytes = 28;
2509     bmp.bmPlanes = 1;
2510     bmp.bmBitsPixel = 1;
2511     bmp.bmBits = NULL;
2512     bm = CreateBitmapIndirect(&bmp);
2513     ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2514     test_mono_1x1_bmp(bm);
2515     DeleteObject(bm);
2516
2517     /* Test how the bmBitsPixel field is treated */
2518     for(i = 1; i <= 33; i++) {
2519         bmp.bmType = 0;
2520         bmp.bmWidth = 1;
2521         bmp.bmHeight = 1;
2522         bmp.bmWidthBytes = 28;
2523         bmp.bmPlanes = 1;
2524         bmp.bmBitsPixel = i;
2525         bmp.bmBits = NULL;
2526         SetLastError(0xdeadbeef);
2527         bm = CreateBitmapIndirect(&bmp);
2528         if(i > 32) {
2529             DWORD error = GetLastError();
2530             ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
2531             ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2532             DeleteObject(bm);
2533             continue;
2534         }
2535         ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2536         GetObject(bm, sizeof(bmp), &bmp);
2537         if(i == 1) {
2538             expect = 1;
2539         } else if(i <= 4) {
2540             expect = 4;
2541         } else if(i <= 8) {
2542             expect = 8;
2543         } else if(i <= 16) {
2544             expect = 16;
2545         } else if(i <= 24) {
2546             expect = 24;
2547         } else if(i <= 32) {
2548             expect = 32;
2549         }
2550         ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2551            i, bmp.bmBitsPixel, expect);
2552         DeleteObject(bm);
2553     }
2554 }
2555
2556 static void test_bitmapinfoheadersize(void)
2557 {
2558     HBITMAP hdib;
2559     BITMAPINFO bmi;
2560     BITMAPCOREINFO bci;
2561     HDC hdc = GetDC(0);
2562
2563     memset(&bmi, 0, sizeof(BITMAPINFO));
2564     bmi.bmiHeader.biHeight = 100;
2565     bmi.bmiHeader.biWidth = 512;
2566     bmi.bmiHeader.biBitCount = 24;
2567     bmi.bmiHeader.biPlanes = 1;
2568
2569     bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2570
2571     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2572     ok(hdib == NULL, "CreateDIBSection succeeded\n");
2573
2574     bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2575
2576     SetLastError(0xdeadbeef);
2577     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2578     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2579     DeleteObject(hdib);
2580
2581     bmi.bmiHeader.biSize++;
2582
2583     SetLastError(0xdeadbeef);
2584     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2585     ok(hdib != NULL ||
2586        broken(!hdib), /* Win98, WinMe */
2587        "CreateDIBSection error %d\n", GetLastError());
2588     DeleteObject(hdib);
2589
2590     bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2591
2592     SetLastError(0xdeadbeef);
2593     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2594     ok(hdib != NULL ||
2595        broken(!hdib), /* Win98, WinMe */
2596        "CreateDIBSection error %d\n", GetLastError());
2597     DeleteObject(hdib);
2598
2599     bmi.bmiHeader.biSize++;
2600
2601     SetLastError(0xdeadbeef);
2602     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2603     ok(hdib != NULL ||
2604        broken(!hdib), /* Win98, WinMe */
2605        "CreateDIBSection error %d\n", GetLastError());
2606     DeleteObject(hdib);
2607
2608     bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2609
2610     SetLastError(0xdeadbeef);
2611     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2612     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2613     DeleteObject(hdib);
2614
2615     bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2616
2617     SetLastError(0xdeadbeef);
2618     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2619     ok(hdib != NULL ||
2620        broken(!hdib), /* Win95 */
2621        "CreateDIBSection error %d\n", GetLastError());
2622     DeleteObject(hdib);
2623
2624     memset(&bci, 0, sizeof(BITMAPCOREINFO));
2625     bci.bmciHeader.bcHeight = 100;
2626     bci.bmciHeader.bcWidth = 512;
2627     bci.bmciHeader.bcBitCount = 24;
2628     bci.bmciHeader.bcPlanes = 1;
2629
2630     bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2631
2632     hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2633     ok(hdib == NULL, "CreateDIBSection succeeded\n");
2634
2635     bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2636
2637     SetLastError(0xdeadbeef);
2638     hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2639     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2640     DeleteObject(hdib);
2641
2642     bci.bmciHeader.bcSize++;
2643
2644     hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2645     ok(hdib == NULL, "CreateDIBSection succeeded\n");
2646
2647     bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2648
2649     hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2650     ok(hdib == NULL, "CreateDIBSection succeeded\n");
2651
2652     ReleaseDC(0, hdc);
2653 }
2654
2655 static void test_get16dibits(void)
2656 {
2657     BYTE bits[4 * (16 / sizeof(BYTE))];
2658     HBITMAP hbmp;
2659     HDC screen_dc = GetDC(NULL);
2660     int ret;
2661     BITMAPINFO * info;
2662     int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2663     BYTE *p;
2664     int overwritten_bytes = 0;
2665
2666     memset(bits, 0, sizeof(bits));
2667     hbmp = CreateBitmap(2, 2, 1, 16, bits);
2668     ok(hbmp != NULL, "CreateBitmap failed\n");
2669
2670     info  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2671     assert(info);
2672
2673     memset(info, '!', info_len);
2674     memset(info, 0, sizeof(info->bmiHeader));
2675
2676     info->bmiHeader.biSize = sizeof(info->bmiHeader);
2677     info->bmiHeader.biWidth = 2;
2678     info->bmiHeader.biHeight = 2;
2679     info->bmiHeader.biPlanes = 1;
2680     info->bmiHeader.biCompression = BI_RGB;
2681
2682     ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2683     ok(ret != 0, "GetDIBits failed got %d\n", ret);
2684
2685     for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2686         if (*p != '!')
2687             overwritten_bytes++;
2688     ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2689
2690     HeapFree(GetProcessHeap(), 0, info);
2691     DeleteObject(hbmp);
2692     ReleaseDC(NULL, screen_dc);
2693 }
2694
2695 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2696                                DWORD dwRop, UINT32 expected, int line)
2697 {
2698     *srcBuffer = 0xFEDCBA98;
2699     *dstBuffer = 0x89ABCDEF;
2700     Rectangle(hdcSrc, 0, 0, 1, 1);  /* A null operation to ensure dibs are coerced to X11 */
2701     BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
2702     ok(expected == *dstBuffer,
2703         "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2704         dwRop, expected, *dstBuffer, line);
2705 }
2706
2707 static void test_BitBlt(void)
2708 {
2709     HBITMAP bmpDst, bmpSrc;
2710     HBITMAP oldDst, oldSrc;
2711     HDC hdcScreen, hdcDst, hdcSrc;
2712     UINT32 *dstBuffer, *srcBuffer;
2713     HBRUSH hBrush, hOldBrush;
2714     BITMAPINFO bitmapInfo;
2715
2716     memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2717     bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2718     bitmapInfo.bmiHeader.biWidth = 1;
2719     bitmapInfo.bmiHeader.biHeight = 1;
2720     bitmapInfo.bmiHeader.biPlanes = 1;
2721     bitmapInfo.bmiHeader.biBitCount = 32;
2722     bitmapInfo.bmiHeader.biCompression = BI_RGB;
2723     bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2724
2725     hdcScreen = CreateCompatibleDC(0);
2726     hdcDst = CreateCompatibleDC(hdcScreen);
2727     hdcSrc = CreateCompatibleDC(hdcDst);
2728
2729     /* Setup the destination dib section */
2730     bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
2731         NULL, 0);
2732     oldDst = SelectObject(hdcDst, bmpDst);
2733
2734     hBrush = CreateSolidBrush(0x012345678);
2735     hOldBrush = SelectObject(hdcDst, hBrush);
2736
2737     /* Setup the source dib section */
2738     bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
2739         NULL, 0);
2740     oldSrc = SelectObject(hdcSrc, bmpSrc);
2741
2742     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2743     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2744     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2745     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2746     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2747     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2748     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2749     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2750     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2751     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2752     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2753     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2754     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2755     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2756     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2757
2758     /* Tidy up */
2759     SelectObject(hdcSrc, oldSrc);
2760     DeleteObject(bmpSrc);
2761     DeleteDC(hdcSrc);
2762
2763     SelectObject(hdcDst, hOldBrush);
2764     DeleteObject(hBrush);
2765     SelectObject(hdcDst, oldDst);
2766     DeleteObject(bmpDst);
2767     DeleteDC(hdcDst);
2768
2769
2770     DeleteDC(hdcScreen);
2771 }
2772
2773 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2774                                    DWORD dwRop, UINT32 expected, int line)
2775 {
2776     *srcBuffer = 0xFEDCBA98;
2777     *dstBuffer = 0x89ABCDEF;
2778     StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
2779     ok(expected == *dstBuffer,
2780         "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2781         dwRop, expected, *dstBuffer, line);
2782 }
2783
2784 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, BITMAPINFO *dst_info, UINT32 *dstBuffer, UINT32 *srcBuffer,
2785                                      int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2786                                      int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2787                                      UINT32 *expected, int line)
2788 {
2789     int dst_size = get_dib_image_size( dst_info );
2790
2791     memset(dstBuffer, 0, dst_size);
2792     StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2793                hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
2794     ok(memcmp(dstBuffer, expected, dst_size) == 0,
2795         "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2796         "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2797         expected[0], expected[1], expected[2], expected[3],
2798         dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2799         nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2800         nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2801 }
2802
2803 static void test_StretchBlt(void)
2804 {
2805     HBITMAP bmpDst, bmpSrc;
2806     HBITMAP oldDst, oldSrc;
2807     HDC hdcScreen, hdcDst, hdcSrc;
2808     UINT32 *dstBuffer, *srcBuffer;
2809     HBRUSH hBrush, hOldBrush;
2810     BITMAPINFO biDst, biSrc;
2811     UINT32 expected[256];
2812     RGBQUAD colors[2];
2813
2814     memset(&biDst, 0, sizeof(BITMAPINFO));
2815     biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2816     biDst.bmiHeader.biWidth = 16;
2817     biDst.bmiHeader.biHeight = -16;
2818     biDst.bmiHeader.biPlanes = 1;
2819     biDst.bmiHeader.biBitCount = 32;
2820     biDst.bmiHeader.biCompression = BI_RGB;
2821     memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
2822
2823     hdcScreen = CreateCompatibleDC(0);
2824     hdcDst = CreateCompatibleDC(hdcScreen);
2825     hdcSrc = CreateCompatibleDC(hdcDst);
2826
2827     /* Pixel Tests */
2828     bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2829         NULL, 0);
2830     oldDst = SelectObject(hdcDst, bmpDst);
2831
2832     bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2833         NULL, 0);
2834     oldSrc = SelectObject(hdcSrc, bmpSrc);
2835
2836     hBrush = CreateSolidBrush(0x012345678);
2837     hOldBrush = SelectObject(hdcDst, hBrush);
2838
2839     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2840     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2841     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2842     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2843     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2844     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2845     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2846     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2847     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2848     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2849     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2850     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2851     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2852     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2853     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2854
2855     SelectObject(hdcDst, hOldBrush);
2856     DeleteObject(hBrush);
2857
2858     /* Top-down to top-down tests */
2859     srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2860     srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2861
2862     memset( expected, 0, get_dib_image_size( &biDst ) );
2863     expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2864     expected[16] = 0xFEDCBA98, expected[17] = 0x76543210;
2865     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2866                              0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2867
2868     expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2869     expected[16] = 0x00000000, expected[17] = 0x00000000;
2870     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2871                              0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
2872
2873     expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
2874     expected[16] = 0xCAFED00D, expected[17] = 0xCAFED00D;
2875     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2876                              0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
2877
2878     /* This is an example of the dst width (height) == 1 exception, explored below */
2879     expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2880     expected[16] = 0x00000000, expected[17] = 0x00000000;
2881     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2882                              0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
2883
2884     expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2885     expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
2886     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2887                              0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2888
2889     expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2890     expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
2891     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2892                              1, 1, -2, -2, 0, 0, 2, 2, expected, __LINE__);
2893
2894     expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2895     expected[16] = 0x00000000, expected[17] = 0x00000000;
2896     todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2897                                        1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
2898
2899     expected[0] = 0x00000000, expected[1] = 0x00000000;
2900     expected[16] = 0x00000000, expected[17] = 0xCAFED00D, expected[18] = 0xFEEDFACE;
2901     expected[32] = 0x00000000, expected[33] = 0xFEDCBA98, expected[34] = 0x76543210;
2902
2903     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2904                              1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2905
2906     /* when dst width is 1 merge src width - 1 pixels */
2907     memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
2908     srcBuffer[0] = 0x0000ff00, srcBuffer[1] = 0x0000f0f0, srcBuffer[2] = 0x0000cccc, srcBuffer[3] = 0x0000aaaa;
2909     srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2910
2911     memset( expected, 0, get_dib_image_size( &biDst ) );
2912     expected[0] = srcBuffer[0];
2913     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2914                              0, 0, 1, 1, 0, 0, 2, 1, expected, __LINE__);
2915
2916     expected[0] = srcBuffer[0] & srcBuffer[1];
2917     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2918                              0, 0, 1, 1, 0, 0, 3, 1, expected, __LINE__);
2919
2920     expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
2921     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2922                              0, 0, 1, 1, 0, 0, 4, 1, expected, __LINE__);
2923
2924     /* this doesn't happen if the src width is -ve */
2925     expected[0] = srcBuffer[1] & srcBuffer[2];
2926     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2927                              0, 0, 1, 1, 2, 0, -2, 1, expected, __LINE__);
2928
2929     /* when dst width > 1 behaviour reverts to what one would expect */
2930     expected[0] = srcBuffer[0] & srcBuffer[1], expected[1] = srcBuffer[2] & srcBuffer[3];
2931     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2932                              0, 0, 2, 1, 0, 0, 4, 1, expected, __LINE__);
2933
2934     /* similarly in the vertical direction */
2935     memset( expected, 0, get_dib_image_size( &biDst ) );
2936     expected[0] = srcBuffer[0];
2937     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2938                              0, 0, 1, 1, 0, 0, 1, 2, expected, __LINE__);
2939
2940     /* check that it's the dst size in device units that needs to be 1 */
2941     SetMapMode( hdcDst, MM_ISOTROPIC );
2942     SetWindowExtEx( hdcDst, 200, 200, NULL );
2943     SetViewportExtEx( hdcDst, 100, 100, NULL );
2944
2945     expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
2946     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2947                              0, 0, 2, 2, 0, 0, 4, 1, expected, __LINE__);
2948     SetMapMode( hdcDst, MM_TEXT );
2949
2950     SelectObject(hdcDst, oldDst);
2951     DeleteObject(bmpDst);
2952
2953     /* Top-down to bottom-up tests */
2954     memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
2955     srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2956     srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
2957
2958     biDst.bmiHeader.biHeight = 16;
2959     bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2960         NULL, 0);
2961     oldDst = SelectObject(hdcDst, bmpDst);
2962
2963     memset( expected, 0, get_dib_image_size( &biDst ) );
2964
2965     expected[224] = 0xFEDCBA98, expected[225] = 0x76543210;
2966     expected[240] = 0xCAFED00D, expected[241] = 0xFEEDFACE;
2967     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2968                              0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2969
2970     expected[224] = 0xFEEDFACE, expected[225] = 0xCAFED00D;
2971     expected[240] = 0x76543210, expected[241] = 0xFEDCBA98;
2972     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2973                              0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2974
2975     SelectObject(hdcSrc, oldSrc);
2976     DeleteObject(bmpSrc);
2977
2978     /* Bottom-up to bottom-up tests */
2979     biSrc.bmiHeader.biHeight = 16;
2980     bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2981         NULL, 0);
2982     srcBuffer[224] = 0xCAFED00D, srcBuffer[225] = 0xFEEDFACE;
2983     srcBuffer[240] = 0xFEDCBA98, srcBuffer[241] = 0x76543210;
2984     oldSrc = SelectObject(hdcSrc, bmpSrc);
2985
2986     memset( expected, 0, get_dib_image_size( &biDst ) );
2987
2988     expected[224] = 0xCAFED00D, expected[225] = 0xFEEDFACE;
2989     expected[240] = 0xFEDCBA98, expected[241] = 0x76543210;
2990     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2991                              0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
2992
2993     expected[224] = 0x76543210, expected[225] = 0xFEDCBA98;
2994     expected[240] = 0xFEEDFACE, expected[241] = 0xCAFED00D;
2995     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
2996                              0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
2997
2998     SelectObject(hdcDst, oldDst);
2999     DeleteObject(bmpDst);
3000
3001     /* Bottom-up to top-down tests */
3002     biDst.bmiHeader.biHeight = -16;
3003     bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3004         NULL, 0);
3005     oldDst = SelectObject(hdcDst, bmpDst);
3006
3007     memset( expected, 0, get_dib_image_size( &biDst ) );
3008     expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3009     expected[16] = 0xCAFED00D, expected[17] = 0xFEEDFACE;
3010     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3011                              0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3012
3013     expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3014     expected[16] = 0x76543210, expected[17] = 0xFEDCBA98;
3015     check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3016                              0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3017
3018     SelectObject(hdcSrc, oldSrc);
3019     DeleteObject(bmpSrc);
3020
3021     biSrc.bmiHeader.biHeight = -2;
3022     biSrc.bmiHeader.biBitCount = 24;
3023     bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
3024     oldSrc = SelectObject(hdcSrc, bmpSrc);
3025
3026     memset( expected, 0, get_dib_image_size( &biDst ) );
3027     expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3028     expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
3029     memcpy(dstBuffer, expected, 4 * sizeof(*dstBuffer));
3030     StretchBlt(hdcSrc, 0, 0, 4, 1, hdcDst, 0, 0, 4, 1, SRCCOPY );
3031     memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
3032     StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3033     expected[0] = 0x00EDFACE, expected[1] = 0x00FED00D;
3034     expected[2] = 0x00543210, expected[3] = 0x00DCBA98;
3035     ok(!memcmp(dstBuffer, expected, 16),
3036        "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3037         expected[0], expected[1], expected[2], expected[3],
3038         dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3039
3040     expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3041     expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
3042     memcpy(srcBuffer, expected, 4 * sizeof(*dstBuffer));
3043     memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
3044     StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3045     expected[0] = 0x00EDFACE, expected[1] = 0x00D00DFE;
3046     expected[2] = 0x0010CAFE, expected[3] = 0x00765432;
3047     ok(!memcmp(dstBuffer, expected, 16),
3048        "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3049         expected[0], expected[1], expected[2], expected[3],
3050         dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3051
3052     SelectObject(hdcSrc, oldSrc);
3053     DeleteObject(bmpSrc);
3054
3055     biSrc.bmiHeader.biBitCount = 1;
3056     bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
3057     oldSrc = SelectObject(hdcSrc, bmpSrc);
3058     *((DWORD *)colors + 0) = 0x123456;
3059     *((DWORD *)colors + 1) = 0x335577;
3060     SetDIBColorTable( hdcSrc, 0, 2, colors );
3061     srcBuffer[0] = 0x55555555;
3062     memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
3063     SetTextColor( hdcDst, 0 );
3064     SetBkColor( hdcDst, 0 );
3065     StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3066     expected[0] = expected[2] = 0x00123456;
3067     expected[1] = expected[3] = 0x00335577;
3068     ok(!memcmp(dstBuffer, expected, 16),
3069        "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3070         expected[0], expected[1], expected[2], expected[3],
3071         dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3072
3073     SelectObject(hdcSrc, oldSrc);
3074     DeleteObject(bmpSrc);
3075
3076     bmpSrc = CreateBitmap( 16, 16, 1, 1, 0 );
3077     oldSrc = SelectObject(hdcSrc, bmpSrc);
3078     SetPixel( hdcSrc, 0, 0, 0 );
3079     SetPixel( hdcSrc, 1, 0, 0xffffff );
3080     SetPixel( hdcSrc, 2, 0, 0xffffff );
3081     SetPixel( hdcSrc, 3, 0, 0 );
3082     memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
3083     SetTextColor( hdcDst, RGB(0x22,0x44,0x66) );
3084     SetBkColor( hdcDst, RGB(0x65,0x43,0x21) );
3085     StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3086     expected[0] = expected[3] = 0x00224466;
3087     expected[1] = expected[2] = 0x00654321;
3088     ok(!memcmp(dstBuffer, expected, 16),
3089        "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3090         expected[0], expected[1], expected[2], expected[3],
3091         dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3092
3093     SelectObject(hdcSrc, oldSrc);
3094     DeleteObject(bmpSrc);
3095
3096     DeleteDC(hdcSrc);
3097
3098     SelectObject(hdcDst, oldDst);
3099     DeleteObject(bmpDst);
3100     DeleteDC(hdcDst);
3101
3102     DeleteDC(hdcScreen);
3103 }
3104
3105 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3106                                       DWORD dwRop, UINT32 expected, int line)
3107 {
3108     const UINT32 buffer[2] = { 0xFEDCBA98, 0 };
3109     BITMAPINFO bitmapInfo;
3110
3111     memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3112     bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3113     bitmapInfo.bmiHeader.biWidth = 2;
3114     bitmapInfo.bmiHeader.biHeight = 1;
3115     bitmapInfo.bmiHeader.biPlanes = 1;
3116     bitmapInfo.bmiHeader.biBitCount = 32;
3117     bitmapInfo.bmiHeader.biCompression = BI_RGB;
3118     bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer);
3119
3120     *dstBuffer = 0x89ABCDEF;
3121
3122     StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop);
3123     ok(expected == *dstBuffer,
3124         "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
3125         dwRop, expected, *dstBuffer, line);
3126 }
3127
3128 static void check_StretchDIBits_stretch(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3129                                         int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
3130                                         int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
3131                                         UINT32 expected[4], int line)
3132 {
3133     BITMAPINFO bitmapInfo;
3134
3135     memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3136     bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3137     bitmapInfo.bmiHeader.biWidth = 2;
3138     bitmapInfo.bmiHeader.biHeight = -2;
3139     bitmapInfo.bmiHeader.biPlanes = 1;
3140     bitmapInfo.bmiHeader.biBitCount = 32;
3141     bitmapInfo.bmiHeader.biCompression = BI_RGB;
3142
3143     memset(dstBuffer, 0, 16);
3144     StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
3145                   nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3146                   srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
3147     ok(memcmp(dstBuffer, expected, 16) == 0,
3148         "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
3149         "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
3150         expected[0], expected[1], expected[2], expected[3],
3151         dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
3152         nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3153         nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
3154 }
3155
3156 static void test_StretchDIBits(void)
3157 {
3158     HBITMAP bmpDst;
3159     HBITMAP oldDst;
3160     HDC hdcScreen, hdcDst;
3161     UINT32 *dstBuffer, srcBuffer[4];
3162     HBRUSH hBrush, hOldBrush;
3163     BITMAPINFO biDst;
3164     UINT32 expected[4];
3165
3166     memset(&biDst, 0, sizeof(BITMAPINFO));
3167     biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3168     biDst.bmiHeader.biWidth = 2;
3169     biDst.bmiHeader.biHeight = -2;
3170     biDst.bmiHeader.biPlanes = 1;
3171     biDst.bmiHeader.biBitCount = 32;
3172     biDst.bmiHeader.biCompression = BI_RGB;
3173
3174     hdcScreen = CreateCompatibleDC(0);
3175     hdcDst = CreateCompatibleDC(hdcScreen);
3176
3177     /* Pixel Tests */
3178     bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3179         NULL, 0);
3180     oldDst = SelectObject(hdcDst, bmpDst);
3181
3182     hBrush = CreateSolidBrush(0x012345678);
3183     hOldBrush = SelectObject(hdcDst, hBrush);
3184
3185     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3186     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3187     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3188     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3189     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3190     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3191     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3192     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3193     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3194     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3195     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3196     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3197     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3198     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3199     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3200
3201     SelectObject(hdcDst, hOldBrush);
3202     DeleteObject(hBrush);
3203
3204     /* Top-down destination tests */
3205     srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3206     srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
3207
3208     expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
3209     expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
3210     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3211                                 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3212
3213     expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3214     expected[2] = 0x00000000, expected[3] = 0x00000000;
3215     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3216                                 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
3217
3218     expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
3219     expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
3220     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3221                                 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
3222
3223     expected[0] = 0x42441000, expected[1] = 0x00000000;
3224     expected[2] = 0x00000000, expected[3] = 0x00000000;
3225     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3226                                 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
3227
3228     expected[0] = 0x00000000, expected[1] = 0x00000000;
3229     expected[2] = 0x00000000, expected[3] = 0x00000000;
3230     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3231                                 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3232
3233     expected[0] = 0x00000000, expected[1] = 0x00000000;
3234     expected[2] = 0x00000000, expected[3] = 0x00000000;
3235     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3236                                 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3237
3238     expected[0] = 0x00000000, expected[1] = 0x00000000;
3239     expected[2] = 0x00000000, expected[3] = 0x00000000;
3240     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3241                                 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
3242
3243     expected[0] = 0x00000000, expected[1] = 0x00000000;
3244     expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
3245     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3246                                 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3247
3248     SelectObject(hdcDst, oldDst);
3249     DeleteObject(bmpDst);
3250
3251     /* Bottom up destination tests */
3252     biDst.bmiHeader.biHeight = 2;
3253     bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3254         NULL, 0);
3255     oldDst = SelectObject(hdcDst, bmpDst);
3256
3257     expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3258     expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
3259     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3260                                 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3261
3262     /* Tidy up */
3263     SelectObject(hdcDst, oldDst);
3264     DeleteObject(bmpDst);
3265     DeleteDC(hdcDst);
3266
3267     DeleteDC(hdcScreen);
3268 }
3269
3270 static void test_GdiAlphaBlend(void)
3271 {
3272     HDC hdcNull;
3273     HDC hdcDst;
3274     HBITMAP bmpDst;
3275     HBITMAP oldDst;
3276     BITMAPINFO *bmi;
3277     HDC hdcSrc;
3278     HBITMAP bmpSrc;
3279     HBITMAP oldSrc;
3280     LPVOID bits;
3281     BOOL ret;
3282     BLENDFUNCTION blend;
3283
3284     if (!pGdiAlphaBlend)
3285     {
3286         win_skip("GdiAlphaBlend() is not implemented\n");
3287         return;
3288     }
3289
3290     hdcNull = GetDC(NULL);
3291     hdcDst = CreateCompatibleDC(hdcNull);
3292     bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
3293     hdcSrc = CreateCompatibleDC(hdcNull);
3294
3295     bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3296     bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3297     bmi->bmiHeader.biHeight = 20;
3298     bmi->bmiHeader.biWidth = 20;
3299     bmi->bmiHeader.biBitCount = 32;
3300     bmi->bmiHeader.biPlanes = 1;
3301     bmi->bmiHeader.biCompression = BI_RGB;
3302     bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3303     ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3304
3305     oldDst = SelectObject(hdcDst, bmpDst);
3306     oldSrc = SelectObject(hdcSrc, bmpSrc);
3307
3308     blend.BlendOp = AC_SRC_OVER;
3309     blend.BlendFlags = 0;
3310     blend.SourceConstantAlpha = 128;
3311     blend.AlphaFormat = 0;
3312
3313     SetLastError(0xdeadbeef);
3314     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3315     ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3316
3317     SetLastError(0xdeadbeef);
3318     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3319     ok( !ret, "GdiAlphaBlend succeeded\n" );
3320     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3321
3322     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3323     ok( !ret, "GdiAlphaBlend succeeded\n" );
3324     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend);
3325     ok( !ret, "GdiAlphaBlend succeeded\n" );
3326     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3327     ok( !ret, "GdiAlphaBlend succeeded\n" );
3328     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3329     ok( !ret, "GdiAlphaBlend succeeded\n" );
3330
3331     SetWindowOrgEx(hdcSrc, -10, -10, NULL);
3332     SetLastError(0xdeadbeef);
3333     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3334     ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3335     SetLastError(0xdeadbeef);
3336     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3337     ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3338     SetMapMode(hdcSrc, MM_ANISOTROPIC);
3339     ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
3340     SetLastError(0xdeadbeef);
3341     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend);
3342     ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3343     SetLastError(0xdeadbeef);
3344     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend);
3345     ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3346
3347     SetLastError(0xdeadbeef);
3348     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend);
3349     ok( !ret, "GdiAlphaBlend succeeded\n" );
3350     ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3351
3352     /* overlapping source and dest not allowed */
3353
3354     SetLastError(0xdeadbeef);
3355     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 19, 19, 20, 20, blend);
3356     ok( !ret, "GdiAlphaBlend succeeded\n" );
3357     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3358
3359     SetLastError(0xdeadbeef);
3360     ret = pGdiAlphaBlend(hdcDst, 20, 20, 20, 20, hdcDst, 1, 1, 20, 20, blend);
3361     ok( !ret, "GdiAlphaBlend succeeded\n" );
3362     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3363
3364     SetLastError(0xdeadbeef);
3365     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 20, 10, 20, 20, blend);
3366     ok( ret, "GdiAlphaBlend succeeded\n" );
3367     SetLastError(0xdeadbeef);
3368     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 10, 20, 20, 20, blend);
3369     ok( ret, "GdiAlphaBlend succeeded\n" );
3370
3371     /* AC_SRC_ALPHA requires 32-bpp BI_RGB format */
3372
3373     blend.AlphaFormat = AC_SRC_ALPHA;
3374     SetLastError(0xdeadbeef);
3375     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3376     ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3377
3378     bmi->bmiHeader.biCompression = BI_BITFIELDS;
3379     ((DWORD *)bmi->bmiColors)[0] = 0xff0000;
3380     ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3381     ((DWORD *)bmi->bmiColors)[2] = 0x0000ff;
3382     bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3383     ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3384     oldSrc = SelectObject(hdcSrc, bmpSrc);
3385     DeleteObject( oldSrc );
3386
3387     SetLastError(0xdeadbeef);
3388     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3389     ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3390
3391     bmi->bmiHeader.biCompression = BI_BITFIELDS;
3392     ((DWORD *)bmi->bmiColors)[0] = 0x0000ff;
3393     ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3394     ((DWORD *)bmi->bmiColors)[2] = 0xff0000;
3395     bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3396     ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3397     oldSrc = SelectObject(hdcSrc, bmpSrc);
3398     DeleteObject( oldSrc );
3399
3400     SetLastError(0xdeadbeef);
3401     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3402     ok( !ret, "GdiAlphaBlend succeeded\n" );
3403     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3404
3405     bmi->bmiHeader.biBitCount = 24;
3406     bmi->bmiHeader.biCompression = BI_RGB;
3407     bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3408     ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3409     oldSrc = SelectObject(hdcSrc, bmpSrc);
3410     DeleteObject( oldSrc );
3411
3412     SetLastError(0xdeadbeef);
3413     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3414     ok( !ret, "GdiAlphaBlend succeeded\n" );
3415     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3416
3417     bmi->bmiHeader.biBitCount = 1;
3418     bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3419     ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3420     oldSrc = SelectObject(hdcSrc, bmpSrc);
3421     DeleteObject( oldSrc );
3422
3423     SetLastError(0xdeadbeef);
3424     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3425     ok( !ret, "GdiAlphaBlend succeeded\n" );
3426     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3427
3428     bmpSrc = CreateBitmap( 100, 100, 1, 1, NULL );
3429     ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3430     oldSrc = SelectObject(hdcSrc, bmpSrc);
3431     DeleteObject( oldSrc );
3432
3433     SetLastError(0xdeadbeef);
3434     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3435     ok( !ret, "GdiAlphaBlend succeeded\n" );
3436     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3437
3438     SelectObject(hdcDst, oldDst);
3439     SelectObject(hdcSrc, oldSrc);
3440     DeleteObject(bmpSrc);
3441     DeleteObject(bmpDst);
3442     DeleteDC(hdcDst);
3443     DeleteDC(hdcSrc);
3444
3445     ReleaseDC(NULL, hdcNull);
3446
3447 }
3448
3449 static void test_GdiGradientFill(void)
3450 {
3451     HDC hdc;
3452     BOOL ret;
3453     HBITMAP bmp;
3454     BITMAPINFO *bmi;
3455     void *bits;
3456     GRADIENT_RECT rect[] = { { 0, 0 }, { 0, 1 }, { 2, 3 } };
3457     GRADIENT_TRIANGLE tri[] = { { 0, 0, 0 }, { 0, 1, 2 }, { 0, 2, 1 }, { 0, 1, 3 } };
3458     TRIVERTEX vt[3] = { { 2,  2,  0xff00, 0x0000, 0x0000, 0x8000 },
3459                         { 10, 10, 0x0000, 0xff00, 0x0000, 0x8000 },
3460                         { 20, 10, 0x0000, 0x0000, 0xff00, 0xff00 } };
3461
3462     if (!pGdiGradientFill)
3463     {
3464         win_skip( "GdiGradientFill is not implemented\n" );
3465         return;
3466     }
3467
3468     hdc = CreateCompatibleDC( NULL );
3469     bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3470     bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3471     bmi->bmiHeader.biHeight = 20;
3472     bmi->bmiHeader.biWidth = 20;
3473     bmi->bmiHeader.biBitCount = 32;
3474     bmi->bmiHeader.biPlanes = 1;
3475     bmi->bmiHeader.biCompression = BI_RGB;
3476     bmp = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3477     ok( bmp != NULL, "couldn't create bitmap\n" );
3478     SelectObject( hdc, bmp );
3479
3480     SetLastError( 0xdeadbeef );
3481     ret = pGdiGradientFill( hdc, vt, 3, rect, 1, GRADIENT_FILL_RECT_H );
3482     ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3483     SetLastError( 0xdeadbeef );
3484     ret = pGdiGradientFill( hdc, vt, 3, rect, 1, 3 );
3485     ok( !ret, "GdiGradientFill succeeded\n" );
3486     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3487     SetLastError( 0xdeadbeef );
3488     ret = pGdiGradientFill( (HDC)0xdead, vt, 3, rect, 1, GRADIENT_FILL_RECT_H );
3489     ok( !ret, "GdiGradientFill succeeded\n" );
3490     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3491     SetLastError( 0xdeadbeef );
3492     ret = pGdiGradientFill( NULL, NULL, 0, rect, 1, GRADIENT_FILL_RECT_H );
3493     ok( !ret, "GdiGradientFill succeeded\n" );
3494     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3495     ret = pGdiGradientFill( hdc, NULL, 0, rect, 1, GRADIENT_FILL_RECT_H );
3496     ok( !ret, "GdiGradientFill succeeded\n" );
3497     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3498     SetLastError( 0xdeadbeef );
3499     ret = pGdiGradientFill( hdc, NULL, 3, rect, 1, GRADIENT_FILL_RECT_H );
3500     ok( !ret, "GdiGradientFill succeeded\n" );
3501     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3502     SetLastError( 0xdeadbeef );
3503     ret = pGdiGradientFill( hdc, vt, 3, NULL, 0, GRADIENT_FILL_RECT_H );
3504     ok( !ret, "GdiGradientFill succeeded\n" );
3505     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3506     SetLastError( 0xdeadbeef );
3507     ret = pGdiGradientFill( hdc, vt, 3, NULL, 1, GRADIENT_FILL_RECT_H );
3508     ok( !ret, "GdiGradientFill succeeded\n" );
3509     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3510     SetLastError( 0xdeadbeef );
3511     ret = pGdiGradientFill( hdc, vt, 3, rect, 0, GRADIENT_FILL_RECT_H );
3512     ok( !ret, "GdiGradientFill succeeded\n" );
3513     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3514     SetLastError( 0xdeadbeef );
3515     ret = pGdiGradientFill( hdc, vt, 3, rect, 3, GRADIENT_FILL_RECT_H );
3516     ok( !ret, "GdiGradientFill succeeded\n" );
3517     ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3518     rect[2].UpperLeft = rect[2].LowerRight = 1;
3519     SetLastError( 0xdeadbeef );
3520     ret = pGdiGradientFill( hdc, vt, 3, rect, 3, GRADIENT_FILL_RECT_H );
3521     ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3522     SetLastError( 0xdeadbeef );
3523     ret = pGdiGradientFill( hdc, vt, 1, rect, 1, GRADIENT_FILL_RECT_H );
3524     ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3525     SetLastError( 0xdeadbeef );
3526     ret = pGdiGradientFill( hdc, vt, 1, tri, 0, GRADIENT_FILL_TRIANGLE );
3527     ok( !ret, "GdiGradientFill succeeded\n" );
3528     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3529     SetLastError( 0xdeadbeef );
3530     ret = pGdiGradientFill( hdc, vt, 1, tri, 1, GRADIENT_FILL_TRIANGLE );
3531     ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3532     SetLastError( 0xdeadbeef );
3533     ret = pGdiGradientFill( hdc, vt, 3, tri, 2, GRADIENT_FILL_TRIANGLE );
3534     ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3535     SetLastError( 0xdeadbeef );
3536     ret = pGdiGradientFill( hdc, vt, 3, tri, 3, GRADIENT_FILL_TRIANGLE );
3537     ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3538     SetLastError( 0xdeadbeef );
3539     ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3540     ok( !ret, "GdiGradientFill succeeded\n" );
3541     ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3542     tri[3].Vertex3 = 1;
3543     SetLastError( 0xdeadbeef );
3544     ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3545     ok( !ret, "GdiGradientFill succeeded\n" );
3546     ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3547     tri[3].Vertex3 = 0;
3548     SetLastError( 0xdeadbeef );
3549     ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3550     ok( !ret, "GdiGradientFill succeeded\n" );
3551     ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3552     tri[3].Vertex1 = tri[3].Vertex2 = tri[3].Vertex3 = 1;
3553     SetLastError( 0xdeadbeef );
3554     ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3555     ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3556
3557     DeleteDC( hdc );
3558     DeleteObject( bmp );
3559 }
3560
3561 static void test_clipping(void)
3562 {
3563     HBITMAP bmpDst;
3564     HBITMAP bmpSrc;
3565     HRGN hRgn;
3566     LPVOID bits;
3567     BOOL result;
3568
3569     HDC hdcDst = CreateCompatibleDC( NULL );
3570     HDC hdcSrc = CreateCompatibleDC( NULL );
3571
3572     BITMAPINFO bmpinfo={{0}};
3573     bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3574     bmpinfo.bmiHeader.biWidth = 100;
3575     bmpinfo.bmiHeader.biHeight = 100;
3576     bmpinfo.bmiHeader.biPlanes = 1;
3577     bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3578     bmpinfo.bmiHeader.biCompression = BI_RGB;
3579
3580     bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3581     ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3582     SelectObject( hdcDst, bmpDst );
3583
3584     bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3585     ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3586     SelectObject( hdcSrc, bmpSrc );
3587
3588     result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3589     ok(result, "BitBlt failed\n");
3590
3591     hRgn = CreateRectRgn( 0,0,0,0 );
3592     SelectClipRgn( hdcDst, hRgn );
3593
3594     result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3595     ok(result, "BitBlt failed\n");
3596
3597     DeleteObject( bmpDst );
3598     DeleteObject( bmpSrc );
3599     DeleteObject( hRgn );
3600     DeleteDC( hdcDst );
3601     DeleteDC( hdcSrc );
3602 }
3603
3604 static void test_32bit_bitmap_blt(void)
3605 {
3606     BITMAPINFO biDst;
3607     HBITMAP bmpSrc, bmpDst;
3608     HBITMAP oldSrc, oldDst;
3609     HDC hdcSrc, hdcDst, hdcScreen;
3610     UINT32 *dstBuffer;
3611     DWORD colorSrc = 0x11223344;
3612
3613     memset(&biDst, 0, sizeof(BITMAPINFO));
3614     biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3615     biDst.bmiHeader.biWidth = 2;
3616     biDst.bmiHeader.biHeight = -2;
3617     biDst.bmiHeader.biPlanes = 1;
3618     biDst.bmiHeader.biBitCount = 32;
3619     biDst.bmiHeader.biCompression = BI_RGB;
3620
3621     hdcScreen = CreateCompatibleDC(0);
3622     if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3623     {
3624         DeleteDC(hdcScreen);
3625         trace("Skipping 32-bit DDB test\n");
3626         return;
3627     }
3628
3629     hdcSrc = CreateCompatibleDC(hdcScreen);
3630     bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3631     oldSrc = SelectObject(hdcSrc, bmpSrc);
3632
3633     hdcDst = CreateCompatibleDC(hdcScreen);
3634     bmpDst = CreateDIBSection(hdcDst, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3635     oldDst = SelectObject(hdcDst, bmpDst);
3636
3637     StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3638     ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3639
3640     /* Tidy up */
3641     SelectObject(hdcDst, oldDst);
3642     DeleteObject(bmpDst);
3643     DeleteDC(hdcDst);
3644
3645     SelectObject(hdcSrc, oldSrc);
3646     DeleteObject(bmpSrc);
3647     DeleteDC(hdcSrc);
3648
3649     DeleteDC(hdcScreen);
3650 }
3651
3652 /*
3653  * Used by test_GetDIBits_top_down to create the bitmap to test against.
3654  */
3655 static void setup_picture(char *picture, int bpp)
3656 {
3657     int i;
3658
3659     switch(bpp)
3660     {
3661         case 16:
3662         case 32:
3663             /*Set the first byte in each pixel to the index of that pixel.*/
3664             for (i = 0; i < 4; i++)
3665                 picture[i * (bpp / 8)] = i;
3666             break;
3667         case 24:
3668             picture[0] = 0;
3669             picture[3] = 1;
3670             /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
3671             picture[8] = 2;
3672             picture[11] = 3;
3673             break;
3674     }
3675 }
3676
3677 static void test_GetDIBits_top_down(int bpp)
3678 {
3679     BITMAPINFO bi;
3680     HBITMAP bmptb, bmpbt;
3681     HDC hdc;
3682     int pictureOut[4];
3683     int *picture;
3684     int statusCode;
3685
3686     memset( &bi, 0, sizeof(bi) );
3687     bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
3688     bi.bmiHeader.biWidth=2;
3689     bi.bmiHeader.biHeight=2;
3690     bi.bmiHeader.biPlanes=1;
3691     bi.bmiHeader.biBitCount=bpp;
3692     bi.bmiHeader.biCompression=BI_RGB;
3693
3694     /*Get the device context for the screen.*/
3695     hdc = GetDC(NULL);
3696     ok(hdc != NULL, "Could not get a handle to a device context.\n");
3697
3698     /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
3699     bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3700     ok(bmpbt != NULL, "Could not create a DIB section.\n");
3701     /*Now that we have a pointer to the pixels, we write to them.*/
3702     setup_picture((char*)picture, bpp);
3703     /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
3704     bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
3705     bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3706     ok(bmptb != NULL, "Could not create a DIB section.\n");
3707     /*Write to this top to bottom bitmap.*/
3708     setup_picture((char*)picture, bpp);
3709
3710     bi.bmiHeader.biWidth = 1;
3711
3712     bi.bmiHeader.biHeight = 2;
3713     statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3714     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3715     /*Check the first byte of the pixel.*/
3716     ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3717     statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3718     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3719     ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3720     /*Check second scanline.*/
3721     statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3722     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3723     ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3724     statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3725     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3726     ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3727     /*Check both scanlines.*/
3728     statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3729     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3730     ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3731     ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3732     statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3733     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3734     ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3735     ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3736
3737     /*Make destination bitmap top-down.*/
3738     bi.bmiHeader.biHeight = -2;
3739     statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3740     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3741     ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3742     statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3743     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3744     ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3745     /*Check second scanline.*/
3746     statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3747     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3748     ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3749     statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3750     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3751     ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3752     /*Check both scanlines.*/
3753     statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3754     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3755     ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3756     ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3757     statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3758     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3759     ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3760     ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3761
3762     DeleteObject(bmpbt);
3763     DeleteObject(bmptb);
3764 }
3765
3766 static void test_GetSetDIBits_rtl(void)
3767 {
3768     HDC hdc, hdc_mem;
3769     HBITMAP bitmap, orig_bitmap;
3770     BITMAPINFO info;
3771     int ret;
3772     DWORD bits_1[8 * 8], bits_2[8 * 8];
3773
3774     if(!pSetLayout)
3775     {
3776         win_skip("Don't have SetLayout\n");
3777         return;
3778     }
3779
3780     hdc = GetDC( NULL );
3781     hdc_mem = CreateCompatibleDC( hdc );
3782     pSetLayout( hdc_mem, LAYOUT_LTR );
3783
3784     bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
3785     orig_bitmap = SelectObject( hdc_mem, bitmap );
3786     SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
3787     SelectObject( hdc_mem, orig_bitmap );
3788
3789     info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3790     info.bmiHeader.biWidth = 8;
3791     info.bmiHeader.biHeight = 8;
3792     info.bmiHeader.biPlanes = 1;
3793     info.bmiHeader.biBitCount = 32;
3794     info.bmiHeader.biCompression = BI_RGB;
3795
3796     /* First show that GetDIBits ignores the layout mode. */
3797
3798     ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3799     ok(ret == 8, "got %d\n", ret);
3800     ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
3801
3802     pSetLayout( hdc_mem, LAYOUT_RTL );
3803
3804     ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3805     ok(ret == 8, "got %d\n", ret);
3806
3807     ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3808
3809     /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
3810        followed by a GetDIBits and show that the bits remain unchanged. */
3811
3812     pSetLayout( hdc_mem, LAYOUT_LTR );
3813
3814     ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3815     ok(ret == 8, "got %d\n", ret);
3816     ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3817     ok(ret == 8, "got %d\n", ret);
3818     ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3819
3820     pSetLayout( hdc_mem, LAYOUT_RTL );
3821
3822     ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3823     ok(ret == 8, "got %d\n", ret);
3824     ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3825     ok(ret == 8, "got %d\n", ret);
3826     ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3827
3828     DeleteObject( bitmap );
3829     DeleteDC( hdc_mem );
3830     ReleaseDC( NULL, hdc );
3831 }
3832
3833 static void test_GetDIBits_scanlines(void)
3834 {
3835     BITMAPINFO *info;
3836     DWORD *dib_bits;
3837     HDC hdc = GetDC( NULL );
3838     HBITMAP dib;
3839     DWORD data[128], inverted_bits[64];
3840     int i, ret;
3841
3842     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
3843
3844     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
3845     info->bmiHeader.biWidth       = 8;
3846     info->bmiHeader.biHeight      = 8;
3847     info->bmiHeader.biPlanes      = 1;
3848     info->bmiHeader.biBitCount    = 32;
3849     info->bmiHeader.biCompression = BI_RGB;
3850
3851     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3852
3853     for (i = 0; i < 64; i++)
3854     {
3855         dib_bits[i] = i;
3856         inverted_bits[56 - (i & ~7) + (i & 7)] = i;
3857     }
3858
3859     /* b-u -> b-u */
3860
3861     memset( data, 0xaa, sizeof(data) );
3862
3863     ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3864     ok( ret == 8, "got %d\n", ret );
3865     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3866     memset( data, 0xaa, sizeof(data) );
3867
3868     ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3869     ok( ret == 5, "got %d\n", ret );
3870     ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
3871     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3872     memset( data, 0xaa, sizeof(data) );
3873
3874     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3875     ok( ret == 7, "got %d\n", ret );
3876     ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
3877     for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3878     memset( data, 0xaa, sizeof(data) );
3879
3880     ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3881     ok( ret == 1, "got %d\n", ret );
3882     for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3883     memset( data, 0xaa, sizeof(data) );
3884
3885     info->bmiHeader.biHeight = 16;
3886     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3887     ok( ret == 5, "got %d\n", ret );
3888     for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3889     ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
3890     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3891     memset( data, 0xaa, sizeof(data) );
3892
3893     ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3894     ok( ret == 6, "got %d\n", ret );
3895     for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3896     ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
3897     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3898     memset( data, 0xaa, sizeof(data) );
3899
3900     ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3901     ok( ret == 0, "got %d\n", ret );
3902     for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3903     for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3904     memset( data, 0xaa, sizeof(data) );
3905
3906     info->bmiHeader.biHeight = 5;
3907     ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3908     ok( ret == 2, "got %d\n", ret );
3909     ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
3910     for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3911     memset( data, 0xaa, sizeof(data) );
3912
3913     /* b-u -> t-d */
3914
3915     info->bmiHeader.biHeight = -8;
3916     ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3917     ok( ret == 8, "got %d\n", ret );
3918     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3919     memset( data, 0xaa, sizeof(data) );
3920
3921     ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3922     ok( ret == 5, "got %d\n", ret );
3923     ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
3924     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3925     memset( data, 0xaa, sizeof(data) );
3926
3927     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3928     ok( ret == 7, "got %d\n", ret );
3929     ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3930     for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3931     memset( data, 0xaa, sizeof(data) );
3932
3933     ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3934     ok( ret == 4, "got %d\n", ret );
3935     ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
3936     for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3937     memset( data, 0xaa, sizeof(data) );
3938
3939     ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3940     ok( ret == 5, "got %d\n", ret );
3941     ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3942     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3943     memset( data, 0xaa, sizeof(data) );
3944
3945     ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3946     ok( ret == 5, "got %d\n", ret );
3947     ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3948     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3949     memset( data, 0xaa, sizeof(data) );
3950
3951     info->bmiHeader.biHeight = -16;
3952     ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3953     ok( ret == 8, "got %d\n", ret );
3954     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3955     for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3956     memset( data, 0xaa, sizeof(data) );
3957
3958     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3959     ok( ret == 5, "got %d\n", ret );
3960     ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
3961     for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3962     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3963     memset( data, 0xaa, sizeof(data) );
3964
3965     ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3966     ok( ret == 8, "got %d\n", ret );
3967     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3968     for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3969     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3970     memset( data, 0xaa, sizeof(data) );
3971
3972     ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3973     ok( ret == 8, "got %d\n", ret );
3974     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3975     for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3976     for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3977     memset( data, 0xaa, sizeof(data) );
3978
3979     ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3980     ok( ret == 7, "got %d\n", ret );
3981     ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3982     for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3983     memset( data, 0xaa, sizeof(data) );
3984
3985     ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
3986     ok( ret == 1, "got %d\n", ret );
3987     for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3988     memset( data, 0xaa, sizeof(data) );
3989
3990     info->bmiHeader.biHeight = -5;
3991     ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3992     ok( ret == 2, "got %d\n", ret );
3993     ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
3994     for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3995     memset( data, 0xaa, sizeof(data) );
3996
3997     DeleteObject( dib );
3998
3999     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4000     info->bmiHeader.biWidth       = 8;
4001     info->bmiHeader.biHeight      = -8;
4002     info->bmiHeader.biPlanes      = 1;
4003     info->bmiHeader.biBitCount    = 32;
4004     info->bmiHeader.biCompression = BI_RGB;
4005
4006     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4007
4008     for (i = 0; i < 64; i++) dib_bits[i] = i;
4009
4010     /* t-d -> t-d */
4011
4012     info->bmiHeader.biHeight = -8;
4013     ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4014     ok( ret == 8, "got %d\n", ret );
4015     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4016     memset( data, 0xaa, sizeof(data) );
4017
4018     ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4019     ok( ret == 5, "got %d\n", ret );
4020     ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
4021     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4022     memset( data, 0xaa, sizeof(data) );
4023
4024     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4025     ok( ret == 7, "got %d\n", ret );
4026     ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
4027     for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4028     memset( data, 0xaa, sizeof(data) );
4029
4030     ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4031     ok( ret == 4, "got %d\n", ret );
4032     ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
4033     for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4034     memset( data, 0xaa, sizeof(data) );
4035
4036     ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
4037     ok( ret == 5, "got %d\n", ret );
4038     ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
4039     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4040     memset( data, 0xaa, sizeof(data) );
4041
4042     ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
4043     ok( ret == 5, "got %d\n", ret );
4044     ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
4045     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4046     memset( data, 0xaa, sizeof(data) );
4047
4048     info->bmiHeader.biHeight = -16;
4049     ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
4050     ok( ret == 8, "got %d\n", ret );
4051     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4052     for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4053     memset( data, 0xaa, sizeof(data) );
4054
4055     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4056     ok( ret == 5, "got %d\n", ret );
4057     ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
4058     for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4059     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4060     memset( data, 0xaa, sizeof(data) );
4061
4062     ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4063     ok( ret == 8, "got %d\n", ret );
4064     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4065     for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4066     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4067     memset( data, 0xaa, sizeof(data) );
4068
4069     ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4070     ok( ret == 8, "got %d\n", ret );
4071     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4072     for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4073     for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4074     memset( data, 0xaa, sizeof(data) );
4075
4076     ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4077     ok( ret == 7, "got %d\n", ret );
4078     ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
4079     for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4080     memset( data, 0xaa, sizeof(data) );
4081
4082     info->bmiHeader.biHeight = -5;
4083     ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4084     ok( ret == 2, "got %d\n", ret );
4085     ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
4086     for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4087     memset( data, 0xaa, sizeof(data) );
4088
4089
4090     /* t-d -> b-u */
4091
4092     info->bmiHeader.biHeight = 8;
4093
4094     ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4095     ok( ret == 8, "got %d\n", ret );
4096     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4097     memset( data, 0xaa, sizeof(data) );
4098
4099     ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4100     ok( ret == 5, "got %d\n", ret );
4101     ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
4102     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4103     memset( data, 0xaa, sizeof(data) );
4104
4105     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4106     ok( ret == 7, "got %d\n", ret );
4107     ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
4108     for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4109     memset( data, 0xaa, sizeof(data) );
4110
4111     ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4112     ok( ret == 1, "got %d\n", ret );
4113     for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4114     memset( data, 0xaa, sizeof(data) );
4115
4116     info->bmiHeader.biHeight = 16;
4117     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4118     ok( ret == 5, "got %d\n", ret );
4119     for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4120     ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
4121     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4122     memset( data, 0xaa, sizeof(data) );
4123
4124     ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
4125     ok( ret == 6, "got %d\n", ret );
4126     for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4127     ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
4128     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4129     memset( data, 0xaa, sizeof(data) );
4130
4131     ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
4132     ok( ret == 0, "got %d\n", ret );
4133     for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4134     for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4135     memset( data, 0xaa, sizeof(data) );
4136
4137     info->bmiHeader.biHeight = 5;
4138     ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4139     ok( ret == 2, "got %d\n", ret );
4140     ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
4141     for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4142     memset( data, 0xaa, sizeof(data) );
4143
4144     DeleteObject( dib );
4145
4146     ReleaseDC( NULL, hdc );
4147     HeapFree( GetProcessHeap(), 0, info );
4148 }
4149
4150
4151 static void test_SetDIBits(void)
4152 {
4153     char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
4154     LOGPALETTE *pal = (LOGPALETTE *)palbuf;
4155     PALETTEENTRY *palent = pal->palPalEntry;
4156     HPALETTE palette;
4157     BITMAPINFO *info;
4158     DWORD *dib_bits;
4159     HDC hdc = GetDC( NULL );
4160     DWORD data[128], inverted_data[128];
4161     HBITMAP dib;
4162     int i, ret;
4163
4164     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4165
4166     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4167     info->bmiHeader.biWidth       = 8;
4168     info->bmiHeader.biHeight      = 8;
4169     info->bmiHeader.biPlanes      = 1;
4170     info->bmiHeader.biBitCount    = 32;
4171     info->bmiHeader.biCompression = BI_RGB;
4172
4173     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4174     memset( dib_bits, 0xaa, 64 * 4 );
4175
4176     for (i = 0; i < 128; i++)
4177     {
4178         data[i] = i;
4179         inverted_data[120 - (i & ~7) + (i & 7)] = i;
4180     }
4181
4182     /* b-u -> b-u */
4183
4184     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4185     ok( ret == 8, "got %d\n", ret );
4186     ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4187     memset( dib_bits, 0xaa, 64 * 4 );
4188
4189     ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4190     ok( ret == 5, "got %d\n", ret );
4191     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4192     ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
4193     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4194     memset( dib_bits, 0xaa, 64 * 4 );
4195
4196     /* top of dst is aligned with startscans down for the top of the src.
4197        Then starting from the bottom of src, lines rows are copied across. */
4198
4199     info->bmiHeader.biHeight = 16;
4200     ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4201     ok( ret == 12, "got %d\n", ret );
4202     ok( !memcmp( dib_bits, data + 56,  40 * 4 ), "bits differ\n");
4203     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4204     memset( dib_bits, 0xaa, 64 * 4 );
4205
4206     info->bmiHeader.biHeight = 5;
4207     ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4208     ok( ret == 2, "got %d\n", ret );
4209     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4210     ok( !memcmp( dib_bits + 32, data,  16 * 4 ), "bits differ\n");
4211     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4212     memset( dib_bits, 0xaa, 64 * 4 );
4213
4214     /* t-d -> b-u */
4215     info->bmiHeader.biHeight = -8;
4216     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4217     ok( ret == 8, "got %d\n", ret );
4218     ok( !memcmp( dib_bits, inverted_data + 64,  64 * 4 ), "bits differ\n");
4219     memset( dib_bits, 0xaa, 64 * 4 );
4220
4221     /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
4222        we copy lines rows from the top of the src */
4223
4224     ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4225     ok( ret == 5, "got %d\n", ret );
4226     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4227     ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
4228     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4229     memset( dib_bits, 0xaa, 64 * 4 );
4230
4231     info->bmiHeader.biHeight = -16;
4232     ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4233     ok( ret == 12, "got %d\n", ret );
4234     ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
4235     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4236     memset( dib_bits, 0xaa, 64 * 4 );
4237
4238     ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4239     ok( ret == 12, "got %d\n", ret );
4240     ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4241     memset( dib_bits, 0xaa, 64 * 4 );
4242
4243     ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4244     ok( ret == 12, "got %d\n", ret );
4245     ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
4246     memset( dib_bits, 0xaa, 64 * 4 );
4247
4248     info->bmiHeader.biHeight = -5;
4249     ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4250     ok( ret == 2, "got %d\n", ret );
4251     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4252     ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
4253     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4254     memset( dib_bits, 0xaa, 64 * 4 );
4255
4256     DeleteObject( dib );
4257
4258     info->bmiHeader.biHeight = -8;
4259
4260     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4261     memset( dib_bits, 0xaa, 16 * 16 * 4 );
4262
4263     /* t-d -> t-d */
4264
4265     /* like the t-d -> b-u case. */
4266
4267     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4268     ok( ret == 8, "got %d\n", ret );
4269     ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4270     memset( dib_bits, 0xaa, 64 * 4 );
4271
4272     ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4273     ok( ret == 5, "got %d\n", ret );
4274     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4275     ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
4276     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4277     memset( dib_bits, 0xaa, 64 * 4 );
4278
4279     info->bmiHeader.biHeight = -16;
4280     ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4281     ok( ret == 12, "got %d\n", ret );
4282     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4283     ok( !memcmp( dib_bits + 24, data,  40 * 4 ), "bits differ\n");
4284     memset( dib_bits, 0xaa, 64 * 4 );
4285
4286     info->bmiHeader.biHeight = -5;
4287     ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4288     ok( ret == 2, "got %d\n", ret );
4289     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4290     ok( !memcmp( dib_bits + 16, data,  16 * 4 ), "bits differ\n");
4291     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4292     memset( dib_bits, 0xaa, 64 * 4 );
4293
4294     /* b-u -> t-d */
4295     /* like the b-u -> b-u case */
4296
4297     info->bmiHeader.biHeight = 8;
4298     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4299     ok( ret == 8, "got %d\n", ret );
4300     ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4301     memset( dib_bits, 0xaa, 64 * 4 );
4302
4303     ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4304     ok( ret == 5, "got %d\n", ret );
4305     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4306     ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
4307     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4308     memset( dib_bits, 0xaa, 64 * 4 );
4309
4310     info->bmiHeader.biHeight = 16;
4311     ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4312     ok( ret == 12, "got %d\n", ret );
4313     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4314     ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
4315     memset( dib_bits, 0xaa, 64 * 4 );
4316
4317     info->bmiHeader.biHeight = 5;
4318     ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4319     ok( ret == 2, "got %d\n", ret );
4320     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4321     ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
4322     for (i = 32; 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     /* handling of partial color table */
4326
4327     info->bmiHeader.biHeight   = -8;
4328     info->bmiHeader.biBitCount = 8;
4329     info->bmiHeader.biClrUsed  = 137;
4330     for (i = 0; i < 256; i++)
4331     {
4332         info->bmiColors[i].rgbRed      = 255 - i;
4333         info->bmiColors[i].rgbGreen    = i * 2;
4334         info->bmiColors[i].rgbBlue     = i;
4335         info->bmiColors[i].rgbReserved = 0;
4336     }
4337     for (i = 0; i < 64; i++) ((BYTE *)data)[i] = i * 4 + 1;
4338     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4339     ok( ret == 8, "got %d\n", ret );
4340     for (i = 0; i < 64; i++)
4341     {
4342         int idx = i * 4 + 1;
4343         DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : (info->bmiColors[idx].rgbRed << 16 |
4344                                                                info->bmiColors[idx].rgbGreen << 8 |
4345                                                                info->bmiColors[idx].rgbBlue);
4346         ok( dib_bits[i] == expect, "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
4347     }
4348     memset( dib_bits, 0xaa, 64 * 4 );
4349
4350     /* handling of DIB_PAL_COLORS */
4351
4352     pal->palVersion = 0x300;
4353     pal->palNumEntries = 137;
4354     info->bmiHeader.biClrUsed = 221;
4355     for (i = 0; i < 256; i++)
4356     {
4357         palent[i].peRed   = i * 2;
4358         palent[i].peGreen = 255 - i;
4359         palent[i].peBlue  = i;
4360     }
4361     palette = CreatePalette( pal );
4362     ok( palette != 0, "palette creation failed\n" );
4363     SelectPalette( hdc, palette, FALSE );
4364     for (i = 0; i < 256; i++) ((WORD *)info->bmiColors)[i] = 255 - i;
4365     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_PAL_COLORS );
4366     ok( ret == 8, "got %d\n", ret );
4367     for (i = 0; i < 64; i++)
4368     {
4369         int idx = i * 4 + 1;
4370         int ent = (255 - idx) % pal->palNumEntries;
4371         DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 :
4372                         (palent[ent].peRed << 16 | palent[ent].peGreen << 8 | palent[ent].peBlue);
4373         ok( dib_bits[i] == expect || broken(dib_bits[i] == 0),  /* various Windows versions get some values wrong */
4374             "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
4375     }
4376     memset( dib_bits, 0xaa, 64 * 4 );
4377
4378     ReleaseDC( NULL, hdc );
4379     DeleteObject( dib );
4380     DeleteObject( palette );
4381     HeapFree( GetProcessHeap(), 0, info );
4382 }
4383
4384 static void test_SetDIBits_RLE4(void)
4385 {
4386     BITMAPINFO *info;
4387     DWORD *dib_bits;
4388     HDC hdc = GetDC( NULL );
4389     BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00,     /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
4390                            0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
4391                            0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00,     /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
4392                            0x00, 0x02, 0x01, 0x02, 0x05, 0x87,     /* dx=1, dy=2, 8, 7, 8, 7, 8 */
4393                            0x00, 0x01 };                           /* <eod> */
4394     HBITMAP dib;
4395     int i, ret;
4396     DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
4397                             0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
4398                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4399                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4400                             0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
4401                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4402                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4403                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4404
4405     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4406
4407     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4408     info->bmiHeader.biWidth       = 8;
4409     info->bmiHeader.biHeight      = 8;
4410     info->bmiHeader.biPlanes      = 1;
4411     info->bmiHeader.biBitCount    = 32;
4412     info->bmiHeader.biCompression = BI_RGB;
4413
4414     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4415     memset( dib_bits, 0xaa, 64 * 4 );
4416
4417     info->bmiHeader.biBitCount    = 4;
4418     info->bmiHeader.biCompression = BI_RLE4;
4419     info->bmiHeader.biSizeImage   = sizeof(rle4_data);
4420
4421     for (i = 0; i < 16; i++)
4422     {
4423         info->bmiColors[i].rgbRed      = i;
4424         info->bmiColors[i].rgbGreen    = i;
4425         info->bmiColors[i].rgbBlue     = i;
4426         info->bmiColors[i].rgbReserved = 0;
4427     }
4428
4429     ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
4430     ok( ret == 8, "got %d\n", ret );
4431     ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
4432     memset( dib_bits, 0xaa, 64 * 4 );
4433
4434     DeleteObject( dib );
4435     ReleaseDC( NULL, hdc );
4436     HeapFree( GetProcessHeap(), 0, info );
4437 }
4438
4439 static void test_SetDIBits_RLE8(void)
4440 {
4441     BITMAPINFO *info;
4442     DWORD *dib_bits;
4443     HDC hdc = GetDC( NULL );
4444     BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00,     /* 2, 2, 2, f0, f0, f0, f0, <eol> */
4445                            0x00, 0x03, 0x04, 0x05, 0x06, 0x00,     /* 4, 5, 6, <pad> */
4446                            0x00, 0x02, 0x01, 0x02, 0x05, 0x80,     /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4447                            0x00, 0x01 };                           /* <eod> */
4448     HBITMAP dib;
4449     int i, ret;
4450     DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4451                             0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4452                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4453                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4454                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4455                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4456                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4457                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4458     DWORD top_down[64]  = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4459                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4460                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4461                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4462                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4463                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4464                             0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4465                             0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4466
4467     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4468
4469     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4470     info->bmiHeader.biWidth       = 8;
4471     info->bmiHeader.biHeight      = 8;
4472     info->bmiHeader.biPlanes      = 1;
4473     info->bmiHeader.biBitCount    = 32;
4474     info->bmiHeader.biCompression = BI_RGB;
4475
4476     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4477     memset( dib_bits, 0xaa, 64 * 4 );
4478
4479     info->bmiHeader.biBitCount    = 8;
4480     info->bmiHeader.biCompression = BI_RLE8;
4481     info->bmiHeader.biSizeImage   = sizeof(rle8_data);
4482
4483     for (i = 0; i < 256; i++)
4484     {
4485         info->bmiColors[i].rgbRed      = i;
4486         info->bmiColors[i].rgbGreen    = i;
4487         info->bmiColors[i].rgbBlue     = i;
4488         info->bmiColors[i].rgbReserved = 0;
4489     }
4490
4491     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4492     ok( ret == 8, "got %d\n", ret );
4493     ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4494     memset( dib_bits, 0xaa, 64 * 4 );
4495
4496     /* startscan and lines are ignored, unless lines == 0 */
4497     ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4498     ok( ret == 8, "got %d\n", ret );
4499     ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4500     memset( dib_bits, 0xaa, 64 * 4 );
4501
4502     ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4503     ok( ret == 8, "got %d\n", ret );
4504     ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4505     memset( dib_bits, 0xaa, 64 * 4 );
4506
4507     ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4508     ok( ret == 0, "got %d\n", ret );
4509     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4510     memset( dib_bits, 0xaa, 64 * 4 );
4511
4512     /* reduce width to 4, left-hand side of dst is touched. */
4513     info->bmiHeader.biWidth = 4;
4514     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4515     ok( ret == 8, "got %d\n", ret );
4516     for (i = 0; i < 64; i++)
4517     {
4518         DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4519         ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4520     }
4521     memset( dib_bits, 0xaa, 64 * 4 );
4522
4523     /* Show that the top lines are aligned by adjusting the height of the src */
4524
4525     /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4526     info->bmiHeader.biWidth  = 8;
4527     info->bmiHeader.biHeight = 4;
4528     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4529     ok( ret == 4, "got %d\n", ret );
4530     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4531     ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4532     memset( dib_bits, 0xaa, 64 * 4 );
4533
4534     /* increase the height to 9 -> everything moves down one row. */
4535     info->bmiHeader.biHeight = 9;
4536     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4537     ok( ret == 9, "got %d\n", ret );
4538     ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4539     for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4540     memset( dib_bits, 0xaa, 64 * 4 );
4541
4542     /* top-down compressed dibs are invalid */
4543     info->bmiHeader.biHeight = -8;
4544     SetLastError( 0xdeadbeef );
4545     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4546     ok( ret == 0, "got %d\n", ret );
4547     ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4548     DeleteObject( dib );
4549
4550     /* top-down dst */
4551
4552     info->bmiHeader.biHeight      = -8;
4553     info->bmiHeader.biBitCount    = 32;
4554     info->bmiHeader.biCompression = BI_RGB;
4555     info->bmiHeader.biSizeImage   = 0;
4556
4557     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4558     memset( dib_bits, 0xaa, 16 * 16 * 4 );
4559
4560     info->bmiHeader.biHeight      = 8;
4561     info->bmiHeader.biBitCount    = 8;
4562     info->bmiHeader.biCompression = BI_RLE8;
4563     info->bmiHeader.biSizeImage   = sizeof(rle8_data);
4564
4565     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4566     ok( ret == 8, "got %d\n", ret );
4567     ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4568     memset( dib_bits, 0xaa, 64 * 4 );
4569
4570     info->bmiHeader.biHeight = 4;
4571     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4572     ok( ret == 4, "got %d\n", ret );
4573     ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4574     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4575     memset( dib_bits, 0xaa, 64 * 4 );
4576
4577     info->bmiHeader.biHeight = 9;
4578     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4579     ok( ret == 9, "got %d\n", ret );
4580     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4581     ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4582     memset( dib_bits, 0xaa, 64 * 4 );
4583
4584     DeleteObject( dib );
4585     ReleaseDC( NULL, hdc );
4586     HeapFree( GetProcessHeap(), 0, info );
4587 }
4588
4589 static void test_SetDIBitsToDevice(void)
4590 {
4591     char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
4592     LOGPALETTE *pal = (LOGPALETTE *)palbuf;
4593     PALETTEENTRY *palent = pal->palPalEntry;
4594     HPALETTE palette;
4595     BITMAPINFO *info;
4596     DWORD *dib_bits;
4597     HDC hdc = CreateCompatibleDC( 0 );
4598     DWORD data[128], inverted_data[128];
4599     HBITMAP dib;
4600     int i, ret;
4601
4602     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4603
4604     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4605     info->bmiHeader.biWidth       = 8;
4606     info->bmiHeader.biHeight      = 8;
4607     info->bmiHeader.biPlanes      = 1;
4608     info->bmiHeader.biBitCount    = 32;
4609     info->bmiHeader.biCompression = BI_RGB;
4610
4611     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4612     memset( dib_bits, 0xaa, 64 * 4 );
4613     SelectObject( hdc, dib );
4614
4615     for (i = 0; i < 128; i++)
4616     {
4617         data[i] = i;
4618         inverted_data[120 - (i & ~7) + (i & 7)] = i;
4619     }
4620
4621     /* b-u -> b-u */
4622
4623     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4624     ok( ret == 8, "got %d\n", ret );
4625     for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4626     memset( dib_bits, 0xaa, 64 * 4 );
4627
4628     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4629     ok( ret == 5, "got %d\n", ret );
4630     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4631     for (i = 8; i < 48; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4632     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4633     memset( dib_bits, 0xaa, 64 * 4 );
4634
4635     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 3, 1, 5, data, info, DIB_RGB_COLORS );
4636     ok( ret == 5, "got %d\n", ret );
4637     for (i = 0; i < 24; i++) ok( dib_bits[i] == data[i + 16], "%d: got %08x\n", i, dib_bits[i] );
4638     for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4639     memset( dib_bits, 0xaa, 64 * 4 );
4640
4641     info->bmiHeader.biHeight = 16;
4642     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4643     ok( ret == 7, "got %d\n", ret );
4644     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4645     for (i = 8; i < 64; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4646     memset( dib_bits, 0xaa, 64 * 4 );
4647
4648     ret = SetDIBitsToDevice( hdc, 0, 2, 8, 8, 0, 6, 1, 12, data, info, DIB_RGB_COLORS );
4649     ok( ret == 12, "got %d\n", ret );
4650     for (i = 0; i < 40; i++) ok( dib_bits[i] == data[i + 56], "%d: got %08x\n", i, dib_bits[i] );
4651     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4652     memset( dib_bits, 0xaa, 64 * 4 );
4653
4654     ret = SetDIBitsToDevice( hdc, 0, -4, 8, 8, 0, 3, 1, 12, data, info, DIB_RGB_COLORS );
4655     ok( ret == 10, "got %d\n", ret );
4656     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4657     for (i = 32; i < 64; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4658     memset( dib_bits, 0xaa, 64 * 4 );
4659
4660     ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, -3, 1, 12, data, info, DIB_RGB_COLORS );
4661     ok( ret == 4, "got %d\n", ret );
4662     for (i = 0; i < 32; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4663     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4664     memset( dib_bits, 0xaa, 64 * 4 );
4665
4666     ret = SetDIBitsToDevice( hdc, 0, 2, 8, 5, 0, -2, 1, 12, data, info, DIB_RGB_COLORS );
4667     ok( ret == 2, "got %d\n", ret );
4668     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4669     for (i = 32; i < 48; i++) ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4670     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4671     memset( dib_bits, 0xaa, 64 * 4 );
4672
4673     info->bmiHeader.biHeight = 5;
4674     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 2, 2, data, info, DIB_RGB_COLORS );
4675     ok( ret == 2, "got %d\n", ret );
4676     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4677     for (i = 16; i < 32; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4678     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4679     memset( dib_bits, 0xaa, 64 * 4 );
4680
4681     ret = SetDIBitsToDevice( hdc, 3, 3, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4682     ok( ret == 3, "got %d\n", ret );
4683     for (i = 0; i < 64; i++)
4684         if (i == 27 || i == 28 || i == 35 || i == 36)
4685             ok( dib_bits[i] == data[i - 18], "%d: got %08x\n", i, dib_bits[i] );
4686         else
4687             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4688     memset( dib_bits, 0xaa, 64 * 4 );
4689
4690     ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4691     ok( ret == 5, "got %d\n", ret );
4692     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4693     memset( dib_bits, 0xaa, 64 * 4 );
4694
4695     ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4696     ok( ret == 0, "got %d\n", ret );
4697     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4698     memset( dib_bits, 0xaa, 64 * 4 );
4699
4700     SetMapMode( hdc, MM_ANISOTROPIC );
4701     SetWindowExtEx( hdc, 3, 3, NULL );
4702     ret = SetDIBitsToDevice( hdc, 2, 2, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4703     ok( ret == 3, "got %d\n", ret );
4704     for (i = 0; i < 64; i++)
4705         if (i == 41 || i == 42 || i == 49 || i == 50)
4706             ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4707         else
4708             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4709     memset( dib_bits, 0xaa, 64 * 4 );
4710
4711     SetWindowExtEx( hdc, -1, -1, NULL );
4712     ret = SetDIBitsToDevice( hdc, 2, 2, 4, 4, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4713     ok( ret == 4, "got %d\n", ret );
4714     for (i = 0; i < 64; i++)
4715         if (i == 48 || i == 49 || i == 56 || i == 57)
4716             ok( dib_bits[i] == data[i - 37], "%d: got %08x\n", i, dib_bits[i] );
4717         else
4718             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4719     memset( dib_bits, 0xaa, 64 * 4 );
4720     SetMapMode( hdc, MM_TEXT );
4721
4722     if (pSetLayout)
4723     {
4724         pSetLayout( hdc, LAYOUT_RTL );
4725         ret = SetDIBitsToDevice( hdc, 1, 2, 3, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4726         ok( ret == 3, "got %d\n", ret );
4727         for (i = 0; i < 64; i++)
4728             if (i == 36 || i == 37 || i == 38 || i == 44 || i == 45 || i == 46)
4729                 ok( dib_bits[i] == data[i - 27], "%d: got %08x\n", i, dib_bits[i] );
4730             else
4731                 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4732         memset( dib_bits, 0xaa, 64 * 4 );
4733         pSetLayout( hdc, LAYOUT_LTR );
4734     }
4735
4736     /* t-d -> b-u */
4737     info->bmiHeader.biHeight = -8;
4738     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4739     ok( ret == 8, "got %d\n", ret );
4740     for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4741     memset( dib_bits, 0xaa, 64 * 4 );
4742
4743     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4744     ok( ret == 5, "got %d\n", ret );
4745     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4746     for (i = 8; i < 48; i++) ok( dib_bits[i] == inverted_data[i + 80], "%d: got %08x\n", i, dib_bits[i] );
4747     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4748     memset( dib_bits, 0xaa, 64 * 4 );
4749
4750     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 4, 1, 5, data, info, DIB_RGB_COLORS );
4751     ok( ret == 5, "got %d\n", ret );
4752     for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4753     for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4754     memset( dib_bits, 0xaa, 64 * 4 );
4755
4756     info->bmiHeader.biHeight = -16;
4757     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4758     ok( ret == 12, "got %d\n", ret );
4759     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4760     for (i = 8; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4761     memset( dib_bits, 0xaa, 64 * 4 );
4762
4763     ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, 7, 1, 12, data, info, DIB_RGB_COLORS );
4764     ok( ret == 12, "got %d\n", ret );
4765     for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4766     for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4767     memset( dib_bits, 0xaa, 64 * 4 );
4768
4769     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 4, 12, data, info, DIB_RGB_COLORS );
4770     ok( ret == 12, "got %d\n", ret );
4771     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4772     for (i = 32; i < 64; i++) ok( dib_bits[i] == inverted_data[i], "%d: got %08x\n", i, dib_bits[i] );
4773     memset( dib_bits, 0xaa, 64 * 4 );
4774
4775     ret = SetDIBitsToDevice( hdc, 0, -3, 8, 8, 0, 2, 4, 12, data, info, DIB_RGB_COLORS );
4776     ok( ret == 12, "got %d\n", ret );
4777     for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4778     for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4779     memset( dib_bits, 0xaa, 64 * 4 );
4780
4781     ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, -2, 4, 12, data, info, DIB_RGB_COLORS );
4782     ok( ret == 12, "got %d\n", ret );
4783     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4784     for (i = 24; i < 40; i++) ok( dib_bits[i] == inverted_data[i + 8], "%d: got %08x\n", i, dib_bits[i] );
4785     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4786     memset( dib_bits, 0xaa, 64 * 4 );
4787
4788     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 5, 12, data, info, DIB_RGB_COLORS );
4789     ok( ret == 12, "got %d\n", ret );
4790     for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4791     for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4792     memset( dib_bits, 0xaa, 64 * 4 );
4793
4794     ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4795     ok( ret == 12, "got %d\n", ret );
4796     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4797     memset( dib_bits, 0xaa, 64 * 4 );
4798
4799     ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -2, -4, 0, 12, data, info, DIB_RGB_COLORS );
4800     ok( ret == 12, "got %d\n", ret );
4801     for (i = 0; i < 64; i++)
4802         if (i == 31 || i == 39 || i == 47 || i == 55 || i == 63)
4803             ok( dib_bits[i] == inverted_data[i + 1], "%d: got %08x\n", i, dib_bits[i] );
4804         else
4805             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4806     memset( dib_bits, 0xaa, 64 * 4 );
4807
4808     info->bmiHeader.biHeight = -5;
4809     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4810     ok( ret == 2, "got %d\n", ret );
4811     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4812     for (i = 8; i < 24; i++) ok( dib_bits[i] == inverted_data[i + 104], "%d: got %08x\n", i, dib_bits[i] );
4813     for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4814     memset( dib_bits, 0xaa, 64 * 4 );
4815
4816     ret = SetDIBitsToDevice( hdc, 5, 4, 2, 2, 6, 3, 1, 5, data, info, DIB_RGB_COLORS );
4817     ok( ret == 5, "got %d\n", ret );
4818     for (i = 0; i < 64; i++)
4819         if (i == 21 || i == 22 || i == 29 || i == 30)
4820             ok( dib_bits[i] == inverted_data[i + 89], "%d: got %08x\n", i, dib_bits[i] );
4821         else
4822             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4823     memset( dib_bits, 0xaa, 64 * 4 );
4824
4825     ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4826     ok( ret == 5, "got %d\n", ret );
4827     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4828     memset( dib_bits, 0xaa, 64 * 4 );
4829
4830     info->bmiHeader.biHeight = -8;
4831
4832     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4833     DeleteObject( SelectObject( hdc, dib ));
4834     memset( dib_bits, 0xaa, 16 * 16 * 4 );
4835
4836     /* t-d -> t-d */
4837
4838     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4839     ok( ret == 8, "got %d\n", ret );
4840     for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4841     memset( dib_bits, 0xaa, 64 * 4 );
4842
4843     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4844     ok( ret == 5, "got %d\n", ret );
4845     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4846     for (i = 16; i < 56; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4847     for (i = 56; 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     ret = SetDIBitsToDevice( hdc, 0, 3, 8, 3, 0, 2, 1, 5, data, info, DIB_RGB_COLORS );
4851     ok( ret == 5, "got %d\n", ret );
4852     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4853     for (i = 24; i < 48; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4854     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4855     memset( dib_bits, 0xaa, 64 * 4 );
4856
4857     info->bmiHeader.biHeight = -16;
4858     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4859     ok( ret == 12, "got %d\n", ret );
4860     for (i = 0; i < 56; i++) ok( dib_bits[i] == data[i + 40], "%d: got %08x\n", i, dib_bits[i] );
4861     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4862     memset( dib_bits, 0xaa, 64 * 4 );
4863
4864     ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -1, -8, 0, 12, data, info, DIB_RGB_COLORS );
4865     ok( ret == 12, "got %d\n", ret );
4866     for (i = 0; i < 64; i++)
4867         if (i == 6 || i == 7)
4868             ok( dib_bits[i] == data[i + 82], "%d: got %08x\n", i, dib_bits[i] );
4869         else
4870             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4871     memset( dib_bits, 0xaa, 64 * 4 );
4872
4873     info->bmiHeader.biHeight = -5;
4874     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4875     ok( ret == 2, "got %d\n", ret );
4876     for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4877     for (i = 40; i < 56; i++) ok( dib_bits[i] == data[i - 40], "%d: got %08x\n", i, dib_bits[i] );
4878     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4879     memset( dib_bits, 0xaa, 64 * 4 );
4880
4881     ret = SetDIBitsToDevice( hdc, 7, 2, 8, 8, 1, 0, 0, 5, data, info, DIB_RGB_COLORS );
4882     ok( ret == 5, "got %d\n", ret );
4883     for (i = 0; i < 64; i++)
4884         if (i == 47 || i == 55 || i == 63)
4885             ok( dib_bits[i] == data[i - 46], "%d: got %08x\n", i, dib_bits[i] );
4886         else
4887             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4888     memset( dib_bits, 0xaa, 64 * 4 );
4889
4890     ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4891     ok( ret == 5, "got %d\n", ret );
4892     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4893     memset( dib_bits, 0xaa, 64 * 4 );
4894
4895     /* b-u -> t-d */
4896
4897     info->bmiHeader.biHeight = 8;
4898     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4899     ok( ret == 8, "got %d\n", ret );
4900     for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4901     memset( dib_bits, 0xaa, 64 * 4 );
4902
4903     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4904     ok( ret == 5, "got %d\n", ret );
4905     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4906     for (i = 16; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4907     for (i = 56; 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     info->bmiHeader.biHeight = 16;
4911     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4912     ok( ret == 7, "got %d\n", ret );
4913     for (i = 0; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4914     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4915     memset( dib_bits, 0xaa, 64 * 4 );
4916
4917     ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, 0, -4, 1, 12, data, info, DIB_RGB_COLORS );
4918     ok( ret == 3, "got %d\n", ret );
4919     for (i = 0; i < 64; i++)
4920         if ((i >= 36 && i <= 39) || (i >= 44 && i <= 47) || (i >= 52 && i <= 55))
4921             ok( dib_bits[i] == inverted_data[i + 68], "%d: got %08x\n", i, dib_bits[i] );
4922         else
4923             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4924     memset( dib_bits, 0xaa, 64 * 4 );
4925
4926     ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, -30, -30, 1, 12, data, info, DIB_RGB_COLORS );
4927     ok( ret == 0, "got %d\n", ret );
4928     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4929     memset( dib_bits, 0xaa, 64 * 4 );
4930
4931     ret = SetDIBitsToDevice( hdc, 5, -5, 8, 16, -2, -4, 4, 12, data, info, DIB_RGB_COLORS );
4932     ok( ret == 8, "got %d\n", ret );
4933     for (i = 0; i < 64; i++)
4934         if (i == 7 || i == 15 || i == 23)
4935             ok( dib_bits[i] == inverted_data[i + 97], "%d: got %08x\n", i, dib_bits[i] );
4936         else
4937             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4938     memset( dib_bits, 0xaa, 64 * 4 );
4939
4940     info->bmiHeader.biHeight = 5;
4941     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4942     ok( ret == 2, "got %d\n", ret );
4943     for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4944     for (i = 40; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4945     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4946     memset( dib_bits, 0xaa, 64 * 4 );
4947
4948     ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4949     ok( ret == 5, "got %d\n", ret );
4950     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4951     memset( dib_bits, 0xaa, 64 * 4 );
4952
4953     /* handling of partial color table */
4954
4955     info->bmiHeader.biHeight   = -8;
4956     info->bmiHeader.biBitCount = 8;
4957     info->bmiHeader.biClrUsed  = 137;
4958     for (i = 0; i < 256; i++)
4959     {
4960         info->bmiColors[i].rgbRed      = 255 - i;
4961         info->bmiColors[i].rgbGreen    = i * 2;
4962         info->bmiColors[i].rgbBlue     = i;
4963         info->bmiColors[i].rgbReserved = 0;
4964     }
4965     for (i = 0; i < 64; i++) ((BYTE *)data)[i] = i * 4 + 1;
4966     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4967     ok( ret == 8, "got %d\n", ret );
4968     for (i = 0; i < 64; i++)
4969     {
4970         int idx = i * 4 + 1;
4971         DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : (info->bmiColors[idx].rgbRed << 16 |
4972                                                                info->bmiColors[idx].rgbGreen << 8 |
4973                                                                info->bmiColors[idx].rgbBlue);
4974         ok( dib_bits[i] == expect, "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
4975     }
4976     memset( dib_bits, 0xaa, 64 * 4 );
4977
4978     /* handling of DIB_PAL_COLORS */
4979
4980     pal->palVersion = 0x300;
4981     pal->palNumEntries = 137;
4982     info->bmiHeader.biClrUsed = 221;
4983     for (i = 0; i < 256; i++)
4984     {
4985         palent[i].peRed   = i * 2;
4986         palent[i].peGreen = 255 - i;
4987         palent[i].peBlue  = i;
4988     }
4989     palette = CreatePalette( pal );
4990     ok( palette != 0, "palette creation failed\n" );
4991     SelectPalette( hdc, palette, FALSE );
4992     for (i = 0; i < 256; i++) ((WORD *)info->bmiColors)[i] = 255 - i;
4993     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_PAL_COLORS );
4994     ok( ret == 8, "got %d\n", ret );
4995     for (i = 0; i < 64; i++)
4996     {
4997         int idx = i * 4 + 1;
4998         int ent = (255 - idx) % pal->palNumEntries;
4999         DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 :
5000                         (palent[ent].peRed << 16 | palent[ent].peGreen << 8 | palent[ent].peBlue);
5001         ok( dib_bits[i] == expect || broken(dib_bits[i] == 0),
5002             "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
5003     }
5004     memset( dib_bits, 0xaa, 64 * 4 );
5005
5006     DeleteDC( hdc );
5007     DeleteObject( dib );
5008     DeleteObject( palette );
5009     HeapFree( GetProcessHeap(), 0, info );
5010 }
5011
5012 static void test_SetDIBitsToDevice_RLE8(void)
5013 {
5014     BITMAPINFO *info;
5015     DWORD *dib_bits;
5016     HDC hdc = CreateCompatibleDC( 0 );
5017     BYTE rle8_data[20] = { 0x04, 0x02, 0x03, 0xf0, 0x00, 0x00,     /* 2, 2, 2, 2, f0, f0, f0, <eol> */
5018                            0x00, 0x03, 0x04, 0x05, 0x06, 0x00,     /* 4, 5, 6, <pad> */
5019                            0x00, 0x02, 0x01, 0x02, 0x05, 0x80,     /* dx=1, dy=2, 80, 80, 80, 80, (80) */
5020                            0x00, 0x01 };                           /* <eod> */
5021     HBITMAP dib;
5022     int i, ret;
5023     DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
5024                             0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5025                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5026                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
5027                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5028                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5029                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5030                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
5031     DWORD top_down[64]  = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5032                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5033                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5034                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5035                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
5036                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5037                             0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5038                             0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
5039
5040     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
5041
5042     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
5043     info->bmiHeader.biWidth       = 8;
5044     info->bmiHeader.biHeight      = 8;
5045     info->bmiHeader.biPlanes      = 1;
5046     info->bmiHeader.biBitCount    = 32;
5047     info->bmiHeader.biCompression = BI_RGB;
5048
5049     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5050     memset( dib_bits, 0xaa, 64 * 4 );
5051     SelectObject( hdc, dib );
5052
5053     info->bmiHeader.biBitCount    = 8;
5054     info->bmiHeader.biCompression = BI_RLE8;
5055     info->bmiHeader.biSizeImage   = sizeof(rle8_data);
5056
5057     for (i = 0; i < 256; i++)
5058     {
5059         info->bmiColors[i].rgbRed      = i;
5060         info->bmiColors[i].rgbGreen    = i;
5061         info->bmiColors[i].rgbBlue     = i;
5062         info->bmiColors[i].rgbReserved = 0;
5063     }
5064
5065     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5066     ok( ret == 8, "got %d\n", ret );
5067     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5068     memset( dib_bits, 0xaa, 64 * 4 );
5069
5070     /* startscan and lines are ignored, unless lines == 0 */
5071     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 8, rle8_data, info, DIB_RGB_COLORS );
5072     ok( ret == 8, "got %d\n", ret );
5073     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5074     memset( dib_bits, 0xaa, 64 * 4 );
5075
5076     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 1, rle8_data, info, DIB_RGB_COLORS );
5077     ok( ret == 8, "got %d\n", ret );
5078     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5079     memset( dib_bits, 0xaa, 64 * 4 );
5080
5081     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 0, rle8_data, info, DIB_RGB_COLORS );
5082     ok( ret == 0, "got %d\n", ret );
5083     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5084     memset( dib_bits, 0xaa, 64 * 4 );
5085
5086     info->bmiHeader.biWidth = 2;
5087     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5088     ok( ret == 8, "got %d\n", ret );
5089     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5090     memset( dib_bits, 0xaa, 64 * 4 );
5091
5092     info->bmiHeader.biWidth  = 8;
5093     info->bmiHeader.biHeight = 2;
5094     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5095     ok( ret == 2, "got %d\n", ret );
5096     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5097     memset( dib_bits, 0xaa, 64 * 4 );
5098
5099     info->bmiHeader.biHeight = 9;
5100     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5101     ok( ret == 9, "got %d\n", ret );
5102     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5103     memset( dib_bits, 0xaa, 64 * 4 );
5104
5105     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5106     ok( ret == 9, "got %d\n", ret );
5107     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5108     memset( dib_bits, 0xaa, 64 * 4 );
5109
5110     info->bmiHeader.biHeight = 8;
5111     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 9, rle8_data, info, DIB_RGB_COLORS );
5112     ok( ret == 8, "got %d\n", ret );
5113     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5114     memset( dib_bits, 0xaa, 64 * 4 );
5115
5116     ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5117     ok( ret == 8, "got %d\n", ret );
5118     for (i = 0; i < 40; i++) ok( dib_bits[i] == bottom_up[i + 24], "%d: got %08x\n", i, dib_bits[i] );
5119     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5120     memset( dib_bits, 0xaa, 64 * 4 );
5121
5122     ret = SetDIBitsToDevice( hdc, 0, 3, 4, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5123     ok( ret == 8, "got %d\n", ret );
5124     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5125     for (i = 8; i < 40; i++)
5126         if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5127         else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5128     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5129     memset( dib_bits, 0xaa, 64 * 4 );
5130
5131     ret = SetDIBitsToDevice( hdc, 3, 3, 8, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5132     ok( ret == 8, "got %d\n", ret );
5133     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5134     for (i = 8; i < 40; i++)
5135         if ((i & 7) < 3) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5136         else ok( dib_bits[i] == bottom_up[i - 11], "%d: got %08x\n", i, dib_bits[i] );
5137     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5138     memset( dib_bits, 0xaa, 64 * 4 );
5139
5140     ret = SetDIBitsToDevice( hdc, 2, 3, 8, 4, 2, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5141     ok( ret == 8, "got %d\n", ret );
5142     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5143     for (i = 8; i < 40; i++)
5144         if ((i & 7) < 2) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5145         else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5146     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5147     memset( dib_bits, 0xaa, 64 * 4 );
5148
5149     info->bmiHeader.biWidth = 37;
5150     info->bmiHeader.biHeight = 37;
5151     ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
5152     ok( ret == 37, "got %d\n", ret );
5153     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5154     for (i = 24; i < 64; i++)
5155         if (i == 52) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
5156         else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5157         else ok( dib_bits[i] == bottom_up[i - 20], "%d: got %08x\n", i, dib_bits[i] );
5158     memset( dib_bits, 0xaa, 64 * 4 );
5159
5160     /* top-down compressed dibs are invalid */
5161     info->bmiHeader.biWidth = 8;
5162     info->bmiHeader.biHeight = -8;
5163     SetLastError( 0xdeadbeef );
5164     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5165     ok( ret == 0, "got %d\n", ret );
5166     ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
5167
5168     /* top-down dst */
5169
5170     info->bmiHeader.biHeight      = -8;
5171     info->bmiHeader.biBitCount    = 32;
5172     info->bmiHeader.biCompression = BI_RGB;
5173     info->bmiHeader.biSizeImage   = 0;
5174
5175     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5176     memset( dib_bits, 0xaa, 16 * 16 * 4 );
5177     DeleteObject( SelectObject( hdc, dib ));
5178
5179     info->bmiHeader.biHeight      = 8;
5180     info->bmiHeader.biBitCount    = 8;
5181     info->bmiHeader.biCompression = BI_RLE8;
5182     info->bmiHeader.biSizeImage   = sizeof(rle8_data);
5183
5184     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5185     ok( ret == 8, "got %d\n", ret );
5186     for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5187     memset( dib_bits, 0xaa, 64 * 4 );
5188
5189     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5190     ok( ret == 8, "got %d\n", ret );
5191     for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5192     memset( dib_bits, 0xaa, 64 * 4 );
5193
5194     info->bmiHeader.biHeight = 4;
5195     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5196     ok( ret == 4, "got %d\n", ret );
5197     for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5198     memset( dib_bits, 0xaa, 64 * 4 );
5199
5200     info->bmiHeader.biHeight = 9;
5201     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5202     ok( ret == 9, "got %d\n", ret );
5203     for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5204     memset( dib_bits, 0xaa, 64 * 4 );
5205
5206     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5207     ok( ret == 9, "got %d\n", ret );
5208     for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5209     memset( dib_bits, 0xaa, 64 * 4 );
5210
5211     ret = SetDIBitsToDevice( hdc, 2, 3, 8, 6, 2, 2, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5212     ok( ret == 9, "got %d\n", ret );
5213     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5214     for (i = 24; i < 64; i++) ok( dib_bits[i] == top_down[i - 24], "%d: got %08x\n", i, dib_bits[i] );
5215     memset( dib_bits, 0xaa, 64 * 4 );
5216
5217     info->bmiHeader.biWidth = 37;
5218     info->bmiHeader.biHeight = 37;
5219     ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
5220     ok( ret == 37, "got %d\n", ret );
5221     for (i = 0; i < 40; i++)
5222         if (i == 12) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
5223         else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5224         else ok( dib_bits[i] == top_down[i + 28], "%d: got %08x\n", i, dib_bits[i] );
5225     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5226     memset( dib_bits, 0xaa, 64 * 4 );
5227
5228     DeleteDC( hdc );
5229     DeleteObject( dib );
5230     HeapFree( GetProcessHeap(), 0, info );
5231 }
5232
5233 START_TEST(bitmap)
5234 {
5235     HMODULE hdll;
5236
5237     hdll = GetModuleHandle("gdi32.dll");
5238     pGdiAlphaBlend   = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
5239     pGdiGradientFill = (void*)GetProcAddress(hdll, "GdiGradientFill");
5240     pSetLayout       = (void*)GetProcAddress(hdll, "SetLayout");
5241
5242     test_createdibitmap();
5243     test_dibsections();
5244     test_dib_formats();
5245     test_mono_dibsection();
5246     test_bitmap();
5247     test_bmBits();
5248     test_GetDIBits_selected_DIB(1);
5249     test_GetDIBits_selected_DIB(4);
5250     test_GetDIBits_selected_DIB(8);
5251     test_GetDIBits_selected_DDB(TRUE);
5252     test_GetDIBits_selected_DDB(FALSE);
5253     test_GetDIBits();
5254     test_GetDIBits_BI_BITFIELDS();
5255     test_select_object();
5256     test_CreateBitmap();
5257     test_BitBlt();
5258     test_StretchBlt();
5259     test_StretchDIBits();
5260     test_GdiAlphaBlend();
5261     test_GdiGradientFill();
5262     test_32bit_bitmap_blt();
5263     test_bitmapinfoheadersize();
5264     test_get16dibits();
5265     test_clipping();
5266     test_GetDIBits_top_down(16);
5267     test_GetDIBits_top_down(24);
5268     test_GetDIBits_top_down(32);
5269     test_GetSetDIBits_rtl();
5270     test_GetDIBits_scanlines();
5271     test_SetDIBits();
5272     test_SetDIBits_RLE4();
5273     test_SetDIBits_RLE8();
5274     test_SetDIBitsToDevice();
5275     test_SetDIBitsToDevice_RLE8();
5276 }