msxml3: Skip leading space characters when loading from BSTR.
[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_ddb(void)
3605 {
3606     char buffer[sizeof(BITMAPINFOHEADER) + sizeof(DWORD)];
3607     BITMAPINFO *biDst = (BITMAPINFO *)buffer;
3608     HBITMAP bmpSrc, bmpDst;
3609     HBITMAP oldSrc, oldDst;
3610     HDC hdcSrc, hdcDst, hdcScreen;
3611     HBRUSH brush;
3612     DWORD *dstBuffer, *data;
3613     DWORD colorSrc = 0x40201008;
3614
3615     memset(biDst, 0, sizeof(BITMAPINFOHEADER));
3616     biDst->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3617     biDst->bmiHeader.biWidth = 1;
3618     biDst->bmiHeader.biHeight = -1;
3619     biDst->bmiHeader.biPlanes = 1;
3620     biDst->bmiHeader.biBitCount = 32;
3621     biDst->bmiHeader.biCompression = BI_RGB;
3622
3623     hdcScreen = CreateCompatibleDC(0);
3624     if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3625     {
3626         DeleteDC(hdcScreen);
3627         trace("Skipping 32-bit DDB test\n");
3628         return;
3629     }
3630
3631     hdcSrc = CreateCompatibleDC(hdcScreen);
3632     bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3633     oldSrc = SelectObject(hdcSrc, bmpSrc);
3634
3635     hdcDst = CreateCompatibleDC(hdcScreen);
3636     bmpDst = CreateDIBSection(hdcDst, biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3637     oldDst = SelectObject(hdcDst, bmpDst);
3638
3639     StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3640     ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3641
3642     if (pGdiAlphaBlend)
3643     {
3644         BLENDFUNCTION blend;
3645         BOOL ret;
3646
3647         blend.BlendOp = AC_SRC_OVER;
3648         blend.BlendFlags = 0;
3649         blend.SourceConstantAlpha = 128;
3650         blend.AlphaFormat = 0;
3651         dstBuffer[0] = 0x80808080;
3652         ret = pGdiAlphaBlend( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, blend );
3653         ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3654         ok(dstBuffer[0] == 0x60504844, "wrong color %x\n", dstBuffer[0]);
3655         blend.AlphaFormat = AC_SRC_ALPHA;
3656         dstBuffer[0] = 0x80808080;
3657         ret = pGdiAlphaBlend( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, blend );
3658         ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3659         ok(dstBuffer[0] == 0x90807874, "wrong color %x\n", dstBuffer[0]);
3660     }
3661
3662     data = (DWORD *)biDst->bmiColors;
3663     data[0] = 0x20304050;
3664     brush = CreateDIBPatternBrushPt( biDst, DIB_RGB_COLORS );
3665     ok( brush != 0, "brush creation failed\n" );
3666     SelectObject( hdcSrc, brush );
3667     PatBlt( hdcSrc, 0, 0, 1, 1, PATCOPY );
3668     BitBlt( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, SRCCOPY );
3669     ok(dstBuffer[0] == data[0], "Expected color=%x, received color=%x\n", data[0], dstBuffer[0]);
3670     SelectObject( hdcSrc, GetStockObject(BLACK_BRUSH) );
3671     DeleteObject( brush );
3672
3673     biDst->bmiHeader.biBitCount = 24;
3674     brush = CreateDIBPatternBrushPt( biDst, DIB_RGB_COLORS );
3675     ok( brush != 0, "brush creation failed\n" );
3676     SelectObject( hdcSrc, brush );
3677     PatBlt( hdcSrc, 0, 0, 1, 1, PATCOPY );
3678     BitBlt( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, SRCCOPY );
3679     ok(dstBuffer[0] == (data[0] & ~0xff000000),
3680        "Expected color=%x, received color=%x\n", data[0] & 0xff000000, dstBuffer[0]);
3681     SelectObject( hdcSrc, GetStockObject(BLACK_BRUSH) );
3682     DeleteObject( brush );
3683
3684     /* Tidy up */
3685     SelectObject(hdcDst, oldDst);
3686     DeleteObject(bmpDst);
3687     DeleteDC(hdcDst);
3688
3689     SelectObject(hdcSrc, oldSrc);
3690     DeleteObject(bmpSrc);
3691     DeleteDC(hdcSrc);
3692
3693     DeleteDC(hdcScreen);
3694 }
3695
3696 /*
3697  * Used by test_GetDIBits_top_down to create the bitmap to test against.
3698  */
3699 static void setup_picture(char *picture, int bpp)
3700 {
3701     int i;
3702
3703     switch(bpp)
3704     {
3705         case 16:
3706         case 32:
3707             /*Set the first byte in each pixel to the index of that pixel.*/
3708             for (i = 0; i < 4; i++)
3709                 picture[i * (bpp / 8)] = i;
3710             break;
3711         case 24:
3712             picture[0] = 0;
3713             picture[3] = 1;
3714             /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
3715             picture[8] = 2;
3716             picture[11] = 3;
3717             break;
3718     }
3719 }
3720
3721 static void test_GetDIBits_top_down(int bpp)
3722 {
3723     BITMAPINFO bi;
3724     HBITMAP bmptb, bmpbt;
3725     HDC hdc;
3726     int pictureOut[4];
3727     int *picture;
3728     int statusCode;
3729
3730     memset( &bi, 0, sizeof(bi) );
3731     bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
3732     bi.bmiHeader.biWidth=2;
3733     bi.bmiHeader.biHeight=2;
3734     bi.bmiHeader.biPlanes=1;
3735     bi.bmiHeader.biBitCount=bpp;
3736     bi.bmiHeader.biCompression=BI_RGB;
3737
3738     /*Get the device context for the screen.*/
3739     hdc = GetDC(NULL);
3740     ok(hdc != NULL, "Could not get a handle to a device context.\n");
3741
3742     /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
3743     bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3744     ok(bmpbt != NULL, "Could not create a DIB section.\n");
3745     /*Now that we have a pointer to the pixels, we write to them.*/
3746     setup_picture((char*)picture, bpp);
3747     /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
3748     bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
3749     bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3750     ok(bmptb != NULL, "Could not create a DIB section.\n");
3751     /*Write to this top to bottom bitmap.*/
3752     setup_picture((char*)picture, bpp);
3753
3754     bi.bmiHeader.biWidth = 1;
3755
3756     bi.bmiHeader.biHeight = 2;
3757     statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3758     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3759     /*Check the first byte of the pixel.*/
3760     ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3761     statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3762     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3763     ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3764     /*Check second scanline.*/
3765     statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3766     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3767     ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3768     statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3769     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3770     ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3771     /*Check both scanlines.*/
3772     statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3773     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3774     ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3775     ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3776     statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3777     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3778     ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3779     ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3780
3781     /*Make destination bitmap top-down.*/
3782     bi.bmiHeader.biHeight = -2;
3783     statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3784     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3785     ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3786     statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3787     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3788     ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3789     /*Check second scanline.*/
3790     statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3791     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3792     ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3793     statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3794     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3795     ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3796     /*Check both scanlines.*/
3797     statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3798     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3799     ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3800     ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3801     statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3802     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3803     ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3804     ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3805
3806     DeleteObject(bmpbt);
3807     DeleteObject(bmptb);
3808 }
3809
3810 static void test_GetSetDIBits_rtl(void)
3811 {
3812     HDC hdc, hdc_mem;
3813     HBITMAP bitmap, orig_bitmap;
3814     BITMAPINFO info;
3815     int ret;
3816     DWORD bits_1[8 * 8], bits_2[8 * 8];
3817
3818     if(!pSetLayout)
3819     {
3820         win_skip("Don't have SetLayout\n");
3821         return;
3822     }
3823
3824     hdc = GetDC( NULL );
3825     hdc_mem = CreateCompatibleDC( hdc );
3826     pSetLayout( hdc_mem, LAYOUT_LTR );
3827
3828     bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
3829     orig_bitmap = SelectObject( hdc_mem, bitmap );
3830     SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
3831     SelectObject( hdc_mem, orig_bitmap );
3832
3833     info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3834     info.bmiHeader.biWidth = 8;
3835     info.bmiHeader.biHeight = 8;
3836     info.bmiHeader.biPlanes = 1;
3837     info.bmiHeader.biBitCount = 32;
3838     info.bmiHeader.biCompression = BI_RGB;
3839
3840     /* First show that GetDIBits ignores the layout mode. */
3841
3842     ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3843     ok(ret == 8, "got %d\n", ret);
3844     ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
3845
3846     pSetLayout( hdc_mem, LAYOUT_RTL );
3847
3848     ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3849     ok(ret == 8, "got %d\n", ret);
3850
3851     ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3852
3853     /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
3854        followed by a GetDIBits and show that the bits remain unchanged. */
3855
3856     pSetLayout( hdc_mem, LAYOUT_LTR );
3857
3858     ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3859     ok(ret == 8, "got %d\n", ret);
3860     ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3861     ok(ret == 8, "got %d\n", ret);
3862     ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3863
3864     pSetLayout( hdc_mem, LAYOUT_RTL );
3865
3866     ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3867     ok(ret == 8, "got %d\n", ret);
3868     ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3869     ok(ret == 8, "got %d\n", ret);
3870     ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3871
3872     DeleteObject( bitmap );
3873     DeleteDC( hdc_mem );
3874     ReleaseDC( NULL, hdc );
3875 }
3876
3877 static void test_GetDIBits_scanlines(void)
3878 {
3879     BITMAPINFO *info;
3880     DWORD *dib_bits;
3881     HDC hdc = GetDC( NULL );
3882     HBITMAP dib;
3883     DWORD data[128], inverted_bits[64];
3884     int i, ret;
3885
3886     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
3887
3888     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
3889     info->bmiHeader.biWidth       = 8;
3890     info->bmiHeader.biHeight      = 8;
3891     info->bmiHeader.biPlanes      = 1;
3892     info->bmiHeader.biBitCount    = 32;
3893     info->bmiHeader.biCompression = BI_RGB;
3894
3895     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3896
3897     for (i = 0; i < 64; i++)
3898     {
3899         dib_bits[i] = i;
3900         inverted_bits[56 - (i & ~7) + (i & 7)] = i;
3901     }
3902
3903     /* b-u -> b-u */
3904
3905     memset( data, 0xaa, sizeof(data) );
3906
3907     ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3908     ok( ret == 8, "got %d\n", ret );
3909     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3910     memset( data, 0xaa, sizeof(data) );
3911
3912     ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3913     ok( ret == 5, "got %d\n", ret );
3914     ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
3915     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3916     memset( data, 0xaa, sizeof(data) );
3917
3918     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3919     ok( ret == 7, "got %d\n", ret );
3920     ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
3921     for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3922     memset( data, 0xaa, sizeof(data) );
3923
3924     ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3925     ok( ret == 1, "got %d\n", ret );
3926     for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3927     memset( data, 0xaa, sizeof(data) );
3928
3929     info->bmiHeader.biHeight = 16;
3930     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3931     ok( ret == 5, "got %d\n", ret );
3932     for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3933     ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
3934     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3935     memset( data, 0xaa, sizeof(data) );
3936
3937     ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3938     ok( ret == 6, "got %d\n", ret );
3939     for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3940     ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
3941     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3942     memset( data, 0xaa, sizeof(data) );
3943
3944     ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3945     ok( ret == 0, "got %d\n", ret );
3946     for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3947     for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3948     memset( data, 0xaa, sizeof(data) );
3949
3950     info->bmiHeader.biHeight = 5;
3951     ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3952     ok( ret == 2, "got %d\n", ret );
3953     ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
3954     for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3955     memset( data, 0xaa, sizeof(data) );
3956
3957     /* b-u -> t-d */
3958
3959     info->bmiHeader.biHeight = -8;
3960     ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3961     ok( ret == 8, "got %d\n", ret );
3962     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3963     memset( data, 0xaa, sizeof(data) );
3964
3965     ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3966     ok( ret == 5, "got %d\n", ret );
3967     ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
3968     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3969     memset( data, 0xaa, sizeof(data) );
3970
3971     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3972     ok( ret == 7, "got %d\n", ret );
3973     ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3974     for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3975     memset( data, 0xaa, sizeof(data) );
3976
3977     ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3978     ok( ret == 4, "got %d\n", ret );
3979     ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
3980     for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3981     memset( data, 0xaa, sizeof(data) );
3982
3983     ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3984     ok( ret == 5, "got %d\n", ret );
3985     ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3986     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3987     memset( data, 0xaa, sizeof(data) );
3988
3989     ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3990     ok( ret == 5, "got %d\n", ret );
3991     ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3992     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3993     memset( data, 0xaa, sizeof(data) );
3994
3995     info->bmiHeader.biHeight = -16;
3996     ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3997     ok( ret == 8, "got %d\n", ret );
3998     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3999     for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4000     memset( data, 0xaa, sizeof(data) );
4001
4002     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4003     ok( ret == 5, "got %d\n", ret );
4004     ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
4005     for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4006     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4007     memset( data, 0xaa, sizeof(data) );
4008
4009     ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4010     ok( ret == 8, "got %d\n", ret );
4011     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4012     for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4013     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4014     memset( data, 0xaa, sizeof(data) );
4015
4016     ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4017     ok( ret == 8, "got %d\n", ret );
4018     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4019     for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4020     for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4021     memset( data, 0xaa, sizeof(data) );
4022
4023     ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4024     ok( ret == 7, "got %d\n", ret );
4025     ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
4026     for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4027     memset( data, 0xaa, sizeof(data) );
4028
4029     ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
4030     ok( ret == 1, "got %d\n", ret );
4031     for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4032     memset( data, 0xaa, sizeof(data) );
4033
4034     info->bmiHeader.biHeight = -5;
4035     ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4036     ok( ret == 2, "got %d\n", ret );
4037     ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
4038     for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4039     memset( data, 0xaa, sizeof(data) );
4040
4041     DeleteObject( dib );
4042
4043     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4044     info->bmiHeader.biWidth       = 8;
4045     info->bmiHeader.biHeight      = -8;
4046     info->bmiHeader.biPlanes      = 1;
4047     info->bmiHeader.biBitCount    = 32;
4048     info->bmiHeader.biCompression = BI_RGB;
4049
4050     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4051
4052     for (i = 0; i < 64; i++) dib_bits[i] = i;
4053
4054     /* t-d -> t-d */
4055
4056     info->bmiHeader.biHeight = -8;
4057     ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4058     ok( ret == 8, "got %d\n", ret );
4059     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4060     memset( data, 0xaa, sizeof(data) );
4061
4062     ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4063     ok( ret == 5, "got %d\n", ret );
4064     ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
4065     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4066     memset( data, 0xaa, sizeof(data) );
4067
4068     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4069     ok( ret == 7, "got %d\n", ret );
4070     ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
4071     for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4072     memset( data, 0xaa, sizeof(data) );
4073
4074     ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4075     ok( ret == 4, "got %d\n", ret );
4076     ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
4077     for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4078     memset( data, 0xaa, sizeof(data) );
4079
4080     ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
4081     ok( ret == 5, "got %d\n", ret );
4082     ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
4083     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4084     memset( data, 0xaa, sizeof(data) );
4085
4086     ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
4087     ok( ret == 5, "got %d\n", ret );
4088     ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
4089     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4090     memset( data, 0xaa, sizeof(data) );
4091
4092     info->bmiHeader.biHeight = -16;
4093     ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
4094     ok( ret == 8, "got %d\n", ret );
4095     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4096     for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4097     memset( data, 0xaa, sizeof(data) );
4098
4099     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4100     ok( ret == 5, "got %d\n", ret );
4101     ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
4102     for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4103     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4104     memset( data, 0xaa, sizeof(data) );
4105
4106     ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4107     ok( ret == 8, "got %d\n", ret );
4108     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4109     for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4110     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4111     memset( data, 0xaa, sizeof(data) );
4112
4113     ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4114     ok( ret == 8, "got %d\n", ret );
4115     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4116     for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4117     for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4118     memset( data, 0xaa, sizeof(data) );
4119
4120     ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4121     ok( ret == 7, "got %d\n", ret );
4122     ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
4123     for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4124     memset( data, 0xaa, sizeof(data) );
4125
4126     info->bmiHeader.biHeight = -5;
4127     ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4128     ok( ret == 2, "got %d\n", ret );
4129     ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
4130     for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4131     memset( data, 0xaa, sizeof(data) );
4132
4133
4134     /* t-d -> b-u */
4135
4136     info->bmiHeader.biHeight = 8;
4137
4138     ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4139     ok( ret == 8, "got %d\n", ret );
4140     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4141     memset( data, 0xaa, sizeof(data) );
4142
4143     ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4144     ok( ret == 5, "got %d\n", ret );
4145     ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
4146     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4147     memset( data, 0xaa, sizeof(data) );
4148
4149     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4150     ok( ret == 7, "got %d\n", ret );
4151     ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
4152     for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4153     memset( data, 0xaa, sizeof(data) );
4154
4155     ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4156     ok( ret == 1, "got %d\n", ret );
4157     for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4158     memset( data, 0xaa, sizeof(data) );
4159
4160     info->bmiHeader.biHeight = 16;
4161     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4162     ok( ret == 5, "got %d\n", ret );
4163     for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4164     ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
4165     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4166     memset( data, 0xaa, sizeof(data) );
4167
4168     ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
4169     ok( ret == 6, "got %d\n", ret );
4170     for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4171     ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
4172     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4173     memset( data, 0xaa, sizeof(data) );
4174
4175     ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
4176     ok( ret == 0, "got %d\n", ret );
4177     for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4178     for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4179     memset( data, 0xaa, sizeof(data) );
4180
4181     info->bmiHeader.biHeight = 5;
4182     ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4183     ok( ret == 2, "got %d\n", ret );
4184     ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
4185     for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4186     memset( data, 0xaa, sizeof(data) );
4187
4188     DeleteObject( dib );
4189
4190     ReleaseDC( NULL, hdc );
4191     HeapFree( GetProcessHeap(), 0, info );
4192 }
4193
4194
4195 static void test_SetDIBits(void)
4196 {
4197     char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
4198     LOGPALETTE *pal = (LOGPALETTE *)palbuf;
4199     PALETTEENTRY *palent = pal->palPalEntry;
4200     HPALETTE palette;
4201     BITMAPINFO *info;
4202     DWORD *dib_bits;
4203     HDC hdc = GetDC( NULL );
4204     DWORD data[128], inverted_data[128];
4205     HBITMAP dib;
4206     int i, ret;
4207
4208     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4209
4210     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4211     info->bmiHeader.biWidth       = 8;
4212     info->bmiHeader.biHeight      = 8;
4213     info->bmiHeader.biPlanes      = 1;
4214     info->bmiHeader.biBitCount    = 32;
4215     info->bmiHeader.biCompression = BI_RGB;
4216
4217     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4218     memset( dib_bits, 0xaa, 64 * 4 );
4219
4220     for (i = 0; i < 128; i++)
4221     {
4222         data[i] = i;
4223         inverted_data[120 - (i & ~7) + (i & 7)] = i;
4224     }
4225
4226     /* b-u -> b-u */
4227
4228     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4229     ok( ret == 8, "got %d\n", ret );
4230     ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4231     memset( dib_bits, 0xaa, 64 * 4 );
4232
4233     ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4234     ok( ret == 5, "got %d\n", ret );
4235     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4236     ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
4237     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4238     memset( dib_bits, 0xaa, 64 * 4 );
4239
4240     /* top of dst is aligned with startscans down for the top of the src.
4241        Then starting from the bottom of src, lines rows are copied across. */
4242
4243     info->bmiHeader.biHeight = 16;
4244     ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4245     ok( ret == 12, "got %d\n", ret );
4246     ok( !memcmp( dib_bits, data + 56,  40 * 4 ), "bits differ\n");
4247     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4248     memset( dib_bits, 0xaa, 64 * 4 );
4249
4250     info->bmiHeader.biHeight = 5;
4251     ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4252     ok( ret == 2, "got %d\n", ret );
4253     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4254     ok( !memcmp( dib_bits + 32, data,  16 * 4 ), "bits differ\n");
4255     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4256     memset( dib_bits, 0xaa, 64 * 4 );
4257
4258     /* t-d -> b-u */
4259     info->bmiHeader.biHeight = -8;
4260     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4261     ok( ret == 8, "got %d\n", ret );
4262     ok( !memcmp( dib_bits, inverted_data + 64,  64 * 4 ), "bits differ\n");
4263     memset( dib_bits, 0xaa, 64 * 4 );
4264
4265     /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
4266        we copy lines rows from the top of the src */
4267
4268     ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4269     ok( ret == 5, "got %d\n", ret );
4270     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4271     ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
4272     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4273     memset( dib_bits, 0xaa, 64 * 4 );
4274
4275     info->bmiHeader.biHeight = -16;
4276     ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4277     ok( ret == 12, "got %d\n", ret );
4278     ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
4279     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4280     memset( dib_bits, 0xaa, 64 * 4 );
4281
4282     ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4283     ok( ret == 12, "got %d\n", ret );
4284     ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4285     memset( dib_bits, 0xaa, 64 * 4 );
4286
4287     ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4288     ok( ret == 12, "got %d\n", ret );
4289     ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
4290     memset( dib_bits, 0xaa, 64 * 4 );
4291
4292     info->bmiHeader.biHeight = -5;
4293     ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4294     ok( ret == 2, "got %d\n", ret );
4295     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4296     ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
4297     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4298     memset( dib_bits, 0xaa, 64 * 4 );
4299
4300     DeleteObject( dib );
4301
4302     info->bmiHeader.biHeight = -8;
4303
4304     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4305     memset( dib_bits, 0xaa, 16 * 16 * 4 );
4306
4307     /* t-d -> t-d */
4308
4309     /* like the t-d -> b-u case. */
4310
4311     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4312     ok( ret == 8, "got %d\n", ret );
4313     ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4314     memset( dib_bits, 0xaa, 64 * 4 );
4315
4316     ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4317     ok( ret == 5, "got %d\n", ret );
4318     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4319     ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
4320     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4321     memset( dib_bits, 0xaa, 64 * 4 );
4322
4323     info->bmiHeader.biHeight = -16;
4324     ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4325     ok( ret == 12, "got %d\n", ret );
4326     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4327     ok( !memcmp( dib_bits + 24, data,  40 * 4 ), "bits differ\n");
4328     memset( dib_bits, 0xaa, 64 * 4 );
4329
4330     info->bmiHeader.biHeight = -5;
4331     ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4332     ok( ret == 2, "got %d\n", ret );
4333     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4334     ok( !memcmp( dib_bits + 16, data,  16 * 4 ), "bits differ\n");
4335     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4336     memset( dib_bits, 0xaa, 64 * 4 );
4337
4338     /* b-u -> t-d */
4339     /* like the b-u -> b-u case */
4340
4341     info->bmiHeader.biHeight = 8;
4342     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4343     ok( ret == 8, "got %d\n", ret );
4344     ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4345     memset( dib_bits, 0xaa, 64 * 4 );
4346
4347     ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4348     ok( ret == 5, "got %d\n", ret );
4349     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4350     ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
4351     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4352     memset( dib_bits, 0xaa, 64 * 4 );
4353
4354     info->bmiHeader.biHeight = 16;
4355     ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4356     ok( ret == 12, "got %d\n", ret );
4357     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4358     ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
4359     memset( dib_bits, 0xaa, 64 * 4 );
4360
4361     info->bmiHeader.biHeight = 5;
4362     ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4363     ok( ret == 2, "got %d\n", ret );
4364     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4365     ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
4366     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4367     memset( dib_bits, 0xaa, 64 * 4 );
4368
4369     /* handling of partial color table */
4370
4371     info->bmiHeader.biHeight   = -8;
4372     info->bmiHeader.biBitCount = 8;
4373     info->bmiHeader.biClrUsed  = 137;
4374     for (i = 0; i < 256; i++)
4375     {
4376         info->bmiColors[i].rgbRed      = 255 - i;
4377         info->bmiColors[i].rgbGreen    = i * 2;
4378         info->bmiColors[i].rgbBlue     = i;
4379         info->bmiColors[i].rgbReserved = 0;
4380     }
4381     for (i = 0; i < 64; i++) ((BYTE *)data)[i] = i * 4 + 1;
4382     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4383     ok( ret == 8, "got %d\n", ret );
4384     for (i = 0; i < 64; i++)
4385     {
4386         int idx = i * 4 + 1;
4387         DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : (info->bmiColors[idx].rgbRed << 16 |
4388                                                                info->bmiColors[idx].rgbGreen << 8 |
4389                                                                info->bmiColors[idx].rgbBlue);
4390         ok( dib_bits[i] == expect, "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
4391     }
4392     memset( dib_bits, 0xaa, 64 * 4 );
4393
4394     /* handling of DIB_PAL_COLORS */
4395
4396     pal->palVersion = 0x300;
4397     pal->palNumEntries = 137;
4398     info->bmiHeader.biClrUsed = 221;
4399     for (i = 0; i < 256; i++)
4400     {
4401         palent[i].peRed   = i * 2;
4402         palent[i].peGreen = 255 - i;
4403         palent[i].peBlue  = i;
4404     }
4405     palette = CreatePalette( pal );
4406     ok( palette != 0, "palette creation failed\n" );
4407     SelectPalette( hdc, palette, FALSE );
4408     for (i = 0; i < 256; i++) ((WORD *)info->bmiColors)[i] = 255 - i;
4409     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_PAL_COLORS );
4410     ok( ret == 8, "got %d\n", ret );
4411     for (i = 0; i < 64; i++)
4412     {
4413         int idx = i * 4 + 1;
4414         int ent = (255 - idx) % pal->palNumEntries;
4415         DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 :
4416                         (palent[ent].peRed << 16 | palent[ent].peGreen << 8 | palent[ent].peBlue);
4417         ok( dib_bits[i] == expect || broken(dib_bits[i] == 0),  /* various Windows versions get some values wrong */
4418             "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
4419     }
4420     memset( dib_bits, 0xaa, 64 * 4 );
4421
4422     ReleaseDC( NULL, hdc );
4423     DeleteObject( dib );
4424     DeleteObject( palette );
4425     HeapFree( GetProcessHeap(), 0, info );
4426 }
4427
4428 static void test_SetDIBits_RLE4(void)
4429 {
4430     BITMAPINFO *info;
4431     DWORD *dib_bits;
4432     HDC hdc = GetDC( NULL );
4433     BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00,     /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
4434                            0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
4435                            0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00,     /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
4436                            0x00, 0x02, 0x01, 0x02, 0x05, 0x87,     /* dx=1, dy=2, 8, 7, 8, 7, 8 */
4437                            0x00, 0x01 };                           /* <eod> */
4438     HBITMAP dib;
4439     int i, ret;
4440     DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
4441                             0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
4442                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4443                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4444                             0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
4445                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4446                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4447                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4448
4449     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4450
4451     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4452     info->bmiHeader.biWidth       = 8;
4453     info->bmiHeader.biHeight      = 8;
4454     info->bmiHeader.biPlanes      = 1;
4455     info->bmiHeader.biBitCount    = 32;
4456     info->bmiHeader.biCompression = BI_RGB;
4457
4458     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4459     memset( dib_bits, 0xaa, 64 * 4 );
4460
4461     info->bmiHeader.biBitCount    = 4;
4462     info->bmiHeader.biCompression = BI_RLE4;
4463     info->bmiHeader.biSizeImage   = sizeof(rle4_data);
4464
4465     for (i = 0; i < 16; i++)
4466     {
4467         info->bmiColors[i].rgbRed      = i;
4468         info->bmiColors[i].rgbGreen    = i;
4469         info->bmiColors[i].rgbBlue     = i;
4470         info->bmiColors[i].rgbReserved = 0;
4471     }
4472
4473     ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
4474     ok( ret == 8, "got %d\n", ret );
4475     ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
4476     memset( dib_bits, 0xaa, 64 * 4 );
4477
4478     DeleteObject( dib );
4479     ReleaseDC( NULL, hdc );
4480     HeapFree( GetProcessHeap(), 0, info );
4481 }
4482
4483 static void test_SetDIBits_RLE8(void)
4484 {
4485     BITMAPINFO *info;
4486     DWORD *dib_bits;
4487     HDC hdc = GetDC( NULL );
4488     BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00,     /* 2, 2, 2, f0, f0, f0, f0, <eol> */
4489                            0x00, 0x03, 0x04, 0x05, 0x06, 0x00,     /* 4, 5, 6, <pad> */
4490                            0x00, 0x02, 0x01, 0x02, 0x05, 0x80,     /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4491                            0x00, 0x01 };                           /* <eod> */
4492     HBITMAP dib;
4493     int i, ret;
4494     DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4495                             0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4496                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4497                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4498                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4499                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4500                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4501                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4502     DWORD top_down[64]  = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4503                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4504                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4505                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4506                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4507                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4508                             0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4509                             0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4510
4511     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4512
4513     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4514     info->bmiHeader.biWidth       = 8;
4515     info->bmiHeader.biHeight      = 8;
4516     info->bmiHeader.biPlanes      = 1;
4517     info->bmiHeader.biBitCount    = 32;
4518     info->bmiHeader.biCompression = BI_RGB;
4519
4520     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4521     memset( dib_bits, 0xaa, 64 * 4 );
4522
4523     info->bmiHeader.biBitCount    = 8;
4524     info->bmiHeader.biCompression = BI_RLE8;
4525     info->bmiHeader.biSizeImage   = sizeof(rle8_data);
4526
4527     for (i = 0; i < 256; i++)
4528     {
4529         info->bmiColors[i].rgbRed      = i;
4530         info->bmiColors[i].rgbGreen    = i;
4531         info->bmiColors[i].rgbBlue     = i;
4532         info->bmiColors[i].rgbReserved = 0;
4533     }
4534
4535     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4536     ok( ret == 8, "got %d\n", ret );
4537     ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4538     memset( dib_bits, 0xaa, 64 * 4 );
4539
4540     /* startscan and lines are ignored, unless lines == 0 */
4541     ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4542     ok( ret == 8, "got %d\n", ret );
4543     ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4544     memset( dib_bits, 0xaa, 64 * 4 );
4545
4546     ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4547     ok( ret == 8, "got %d\n", ret );
4548     ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4549     memset( dib_bits, 0xaa, 64 * 4 );
4550
4551     ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4552     ok( ret == 0, "got %d\n", ret );
4553     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4554     memset( dib_bits, 0xaa, 64 * 4 );
4555
4556     /* reduce width to 4, left-hand side of dst is touched. */
4557     info->bmiHeader.biWidth = 4;
4558     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4559     ok( ret == 8, "got %d\n", ret );
4560     for (i = 0; i < 64; i++)
4561     {
4562         DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4563         ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4564     }
4565     memset( dib_bits, 0xaa, 64 * 4 );
4566
4567     /* Show that the top lines are aligned by adjusting the height of the src */
4568
4569     /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4570     info->bmiHeader.biWidth  = 8;
4571     info->bmiHeader.biHeight = 4;
4572     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4573     ok( ret == 4, "got %d\n", ret );
4574     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4575     ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4576     memset( dib_bits, 0xaa, 64 * 4 );
4577
4578     /* increase the height to 9 -> everything moves down one row. */
4579     info->bmiHeader.biHeight = 9;
4580     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4581     ok( ret == 9, "got %d\n", ret );
4582     ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4583     for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4584     memset( dib_bits, 0xaa, 64 * 4 );
4585
4586     /* top-down compressed dibs are invalid */
4587     info->bmiHeader.biHeight = -8;
4588     SetLastError( 0xdeadbeef );
4589     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4590     ok( ret == 0, "got %d\n", ret );
4591     ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4592     DeleteObject( dib );
4593
4594     /* top-down dst */
4595
4596     info->bmiHeader.biHeight      = -8;
4597     info->bmiHeader.biBitCount    = 32;
4598     info->bmiHeader.biCompression = BI_RGB;
4599     info->bmiHeader.biSizeImage   = 0;
4600
4601     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4602     memset( dib_bits, 0xaa, 16 * 16 * 4 );
4603
4604     info->bmiHeader.biHeight      = 8;
4605     info->bmiHeader.biBitCount    = 8;
4606     info->bmiHeader.biCompression = BI_RLE8;
4607     info->bmiHeader.biSizeImage   = sizeof(rle8_data);
4608
4609     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4610     ok( ret == 8, "got %d\n", ret );
4611     ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4612     memset( dib_bits, 0xaa, 64 * 4 );
4613
4614     info->bmiHeader.biHeight = 4;
4615     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4616     ok( ret == 4, "got %d\n", ret );
4617     ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4618     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4619     memset( dib_bits, 0xaa, 64 * 4 );
4620
4621     info->bmiHeader.biHeight = 9;
4622     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4623     ok( ret == 9, "got %d\n", ret );
4624     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4625     ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4626     memset( dib_bits, 0xaa, 64 * 4 );
4627
4628     DeleteObject( dib );
4629     ReleaseDC( NULL, hdc );
4630     HeapFree( GetProcessHeap(), 0, info );
4631 }
4632
4633 static void test_SetDIBitsToDevice(void)
4634 {
4635     char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
4636     LOGPALETTE *pal = (LOGPALETTE *)palbuf;
4637     PALETTEENTRY *palent = pal->palPalEntry;
4638     HPALETTE palette;
4639     BITMAPINFO *info;
4640     DWORD *dib_bits;
4641     HDC hdc = CreateCompatibleDC( 0 );
4642     DWORD data[128], inverted_data[128];
4643     HBITMAP dib;
4644     int i, ret;
4645
4646     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4647
4648     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4649     info->bmiHeader.biWidth       = 8;
4650     info->bmiHeader.biHeight      = 8;
4651     info->bmiHeader.biPlanes      = 1;
4652     info->bmiHeader.biBitCount    = 32;
4653     info->bmiHeader.biCompression = BI_RGB;
4654
4655     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4656     memset( dib_bits, 0xaa, 64 * 4 );
4657     SelectObject( hdc, dib );
4658
4659     for (i = 0; i < 128; i++)
4660     {
4661         data[i] = i;
4662         inverted_data[120 - (i & ~7) + (i & 7)] = i;
4663     }
4664
4665     /* b-u -> b-u */
4666
4667     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4668     ok( ret == 8, "got %d\n", ret );
4669     for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4670     memset( dib_bits, 0xaa, 64 * 4 );
4671
4672     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4673     ok( ret == 5, "got %d\n", ret );
4674     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4675     for (i = 8; i < 48; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4676     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4677     memset( dib_bits, 0xaa, 64 * 4 );
4678
4679     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 3, 1, 5, data, info, DIB_RGB_COLORS );
4680     ok( ret == 5, "got %d\n", ret );
4681     for (i = 0; i < 24; i++) ok( dib_bits[i] == data[i + 16], "%d: got %08x\n", i, dib_bits[i] );
4682     for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4683     memset( dib_bits, 0xaa, 64 * 4 );
4684
4685     info->bmiHeader.biHeight = 16;
4686     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4687     ok( ret == 7, "got %d\n", ret );
4688     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4689     for (i = 8; i < 64; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4690     memset( dib_bits, 0xaa, 64 * 4 );
4691
4692     ret = SetDIBitsToDevice( hdc, 0, 2, 8, 8, 0, 6, 1, 12, data, info, DIB_RGB_COLORS );
4693     ok( ret == 12, "got %d\n", ret );
4694     for (i = 0; i < 40; i++) ok( dib_bits[i] == data[i + 56], "%d: got %08x\n", i, dib_bits[i] );
4695     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4696     memset( dib_bits, 0xaa, 64 * 4 );
4697
4698     ret = SetDIBitsToDevice( hdc, 0, -4, 8, 8, 0, 3, 1, 12, data, info, DIB_RGB_COLORS );
4699     ok( ret == 10, "got %d\n", ret );
4700     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4701     for (i = 32; i < 64; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4702     memset( dib_bits, 0xaa, 64 * 4 );
4703
4704     ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, -3, 1, 12, data, info, DIB_RGB_COLORS );
4705     ok( ret == 4, "got %d\n", ret );
4706     for (i = 0; i < 32; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4707     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4708     memset( dib_bits, 0xaa, 64 * 4 );
4709
4710     ret = SetDIBitsToDevice( hdc, 0, 2, 8, 5, 0, -2, 1, 12, data, info, DIB_RGB_COLORS );
4711     ok( ret == 2, "got %d\n", ret );
4712     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4713     for (i = 32; i < 48; i++) ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4714     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4715     memset( dib_bits, 0xaa, 64 * 4 );
4716
4717     info->bmiHeader.biHeight = 5;
4718     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 2, 2, data, info, DIB_RGB_COLORS );
4719     ok( ret == 2, "got %d\n", ret );
4720     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4721     for (i = 16; i < 32; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4722     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4723     memset( dib_bits, 0xaa, 64 * 4 );
4724
4725     ret = SetDIBitsToDevice( hdc, 3, 3, 2, 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 == 27 || i == 28 || i == 35 || i == 36)
4729             ok( dib_bits[i] == data[i - 18], "%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
4734     ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4735     ok( ret == 5, "got %d\n", ret );
4736     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4737     memset( dib_bits, 0xaa, 64 * 4 );
4738
4739     ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4740     ok( ret == 0, "got %d\n", ret );
4741     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4742     memset( dib_bits, 0xaa, 64 * 4 );
4743
4744     SetMapMode( hdc, MM_ANISOTROPIC );
4745     SetWindowExtEx( hdc, 3, 3, NULL );
4746     ret = SetDIBitsToDevice( hdc, 2, 2, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4747     ok( ret == 3, "got %d\n", ret );
4748     for (i = 0; i < 64; i++)
4749         if (i == 41 || i == 42 || i == 49 || i == 50)
4750             ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4751         else
4752             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4753     memset( dib_bits, 0xaa, 64 * 4 );
4754
4755     SetWindowExtEx( hdc, -1, -1, NULL );
4756     ret = SetDIBitsToDevice( hdc, 2, 2, 4, 4, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4757     ok( ret == 4, "got %d\n", ret );
4758     for (i = 0; i < 64; i++)
4759         if (i == 48 || i == 49 || i == 56 || i == 57)
4760             ok( dib_bits[i] == data[i - 37], "%d: got %08x\n", i, dib_bits[i] );
4761         else
4762             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4763     memset( dib_bits, 0xaa, 64 * 4 );
4764     SetMapMode( hdc, MM_TEXT );
4765
4766     if (pSetLayout)
4767     {
4768         pSetLayout( hdc, LAYOUT_RTL );
4769         ret = SetDIBitsToDevice( hdc, 1, 2, 3, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4770         ok( ret == 3, "got %d\n", ret );
4771         for (i = 0; i < 64; i++)
4772             if (i == 36 || i == 37 || i == 38 || i == 44 || i == 45 || i == 46)
4773                 ok( dib_bits[i] == data[i - 27], "%d: got %08x\n", i, dib_bits[i] );
4774             else
4775                 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4776         memset( dib_bits, 0xaa, 64 * 4 );
4777         pSetLayout( hdc, LAYOUT_LTR );
4778     }
4779
4780     /* t-d -> b-u */
4781     info->bmiHeader.biHeight = -8;
4782     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4783     ok( ret == 8, "got %d\n", ret );
4784     for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4785     memset( dib_bits, 0xaa, 64 * 4 );
4786
4787     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4788     ok( ret == 5, "got %d\n", ret );
4789     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4790     for (i = 8; i < 48; i++) ok( dib_bits[i] == inverted_data[i + 80], "%d: got %08x\n", i, dib_bits[i] );
4791     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4792     memset( dib_bits, 0xaa, 64 * 4 );
4793
4794     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 4, 1, 5, data, info, DIB_RGB_COLORS );
4795     ok( ret == 5, "got %d\n", ret );
4796     for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4797     for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4798     memset( dib_bits, 0xaa, 64 * 4 );
4799
4800     info->bmiHeader.biHeight = -16;
4801     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4802     ok( ret == 12, "got %d\n", ret );
4803     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4804     for (i = 8; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4805     memset( dib_bits, 0xaa, 64 * 4 );
4806
4807     ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, 7, 1, 12, data, info, DIB_RGB_COLORS );
4808     ok( ret == 12, "got %d\n", ret );
4809     for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4810     for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4811     memset( dib_bits, 0xaa, 64 * 4 );
4812
4813     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 4, 12, data, info, DIB_RGB_COLORS );
4814     ok( ret == 12, "got %d\n", ret );
4815     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4816     for (i = 32; i < 64; i++) ok( dib_bits[i] == inverted_data[i], "%d: got %08x\n", i, dib_bits[i] );
4817     memset( dib_bits, 0xaa, 64 * 4 );
4818
4819     ret = SetDIBitsToDevice( hdc, 0, -3, 8, 8, 0, 2, 4, 12, data, info, DIB_RGB_COLORS );
4820     ok( ret == 12, "got %d\n", ret );
4821     for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4822     for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4823     memset( dib_bits, 0xaa, 64 * 4 );
4824
4825     ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, -2, 4, 12, data, info, DIB_RGB_COLORS );
4826     ok( ret == 12, "got %d\n", ret );
4827     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4828     for (i = 24; i < 40; i++) ok( dib_bits[i] == inverted_data[i + 8], "%d: got %08x\n", i, dib_bits[i] );
4829     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4830     memset( dib_bits, 0xaa, 64 * 4 );
4831
4832     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 5, 12, data, info, DIB_RGB_COLORS );
4833     ok( ret == 12, "got %d\n", ret );
4834     for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4835     for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4836     memset( dib_bits, 0xaa, 64 * 4 );
4837
4838     ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4839     ok( ret == 12, "got %d\n", ret );
4840     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4841     memset( dib_bits, 0xaa, 64 * 4 );
4842
4843     ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -2, -4, 0, 12, data, info, DIB_RGB_COLORS );
4844     ok( ret == 12, "got %d\n", ret );
4845     for (i = 0; i < 64; i++)
4846         if (i == 31 || i == 39 || i == 47 || i == 55 || i == 63)
4847             ok( dib_bits[i] == inverted_data[i + 1], "%d: got %08x\n", i, dib_bits[i] );
4848         else
4849             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4850     memset( dib_bits, 0xaa, 64 * 4 );
4851
4852     info->bmiHeader.biHeight = -5;
4853     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4854     ok( ret == 2, "got %d\n", ret );
4855     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4856     for (i = 8; i < 24; i++) ok( dib_bits[i] == inverted_data[i + 104], "%d: got %08x\n", i, dib_bits[i] );
4857     for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4858     memset( dib_bits, 0xaa, 64 * 4 );
4859
4860     ret = SetDIBitsToDevice( hdc, 5, 4, 2, 2, 6, 3, 1, 5, data, info, DIB_RGB_COLORS );
4861     ok( ret == 5, "got %d\n", ret );
4862     for (i = 0; i < 64; i++)
4863         if (i == 21 || i == 22 || i == 29 || i == 30)
4864             ok( dib_bits[i] == inverted_data[i + 89], "%d: got %08x\n", i, dib_bits[i] );
4865         else
4866             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4867     memset( dib_bits, 0xaa, 64 * 4 );
4868
4869     ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4870     ok( ret == 5, "got %d\n", ret );
4871     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4872     memset( dib_bits, 0xaa, 64 * 4 );
4873
4874     info->bmiHeader.biHeight = -8;
4875
4876     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4877     DeleteObject( SelectObject( hdc, dib ));
4878     memset( dib_bits, 0xaa, 16 * 16 * 4 );
4879
4880     /* t-d -> t-d */
4881
4882     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4883     ok( ret == 8, "got %d\n", ret );
4884     for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4885     memset( dib_bits, 0xaa, 64 * 4 );
4886
4887     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4888     ok( ret == 5, "got %d\n", ret );
4889     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4890     for (i = 16; i < 56; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4891     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4892     memset( dib_bits, 0xaa, 64 * 4 );
4893
4894     ret = SetDIBitsToDevice( hdc, 0, 3, 8, 3, 0, 2, 1, 5, data, info, DIB_RGB_COLORS );
4895     ok( ret == 5, "got %d\n", ret );
4896     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4897     for (i = 24; i < 48; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4898     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4899     memset( dib_bits, 0xaa, 64 * 4 );
4900
4901     info->bmiHeader.biHeight = -16;
4902     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4903     ok( ret == 12, "got %d\n", ret );
4904     for (i = 0; i < 56; i++) ok( dib_bits[i] == data[i + 40], "%d: got %08x\n", i, dib_bits[i] );
4905     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4906     memset( dib_bits, 0xaa, 64 * 4 );
4907
4908     ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -1, -8, 0, 12, data, info, DIB_RGB_COLORS );
4909     ok( ret == 12, "got %d\n", ret );
4910     for (i = 0; i < 64; i++)
4911         if (i == 6 || i == 7)
4912             ok( dib_bits[i] == data[i + 82], "%d: got %08x\n", i, dib_bits[i] );
4913         else
4914             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4915     memset( dib_bits, 0xaa, 64 * 4 );
4916
4917     info->bmiHeader.biHeight = -5;
4918     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4919     ok( ret == 2, "got %d\n", ret );
4920     for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4921     for (i = 40; i < 56; i++) ok( dib_bits[i] == data[i - 40], "%d: got %08x\n", i, dib_bits[i] );
4922     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4923     memset( dib_bits, 0xaa, 64 * 4 );
4924
4925     ret = SetDIBitsToDevice( hdc, 7, 2, 8, 8, 1, 0, 0, 5, data, info, DIB_RGB_COLORS );
4926     ok( ret == 5, "got %d\n", ret );
4927     for (i = 0; i < 64; i++)
4928         if (i == 47 || i == 55 || i == 63)
4929             ok( dib_bits[i] == data[i - 46], "%d: got %08x\n", i, dib_bits[i] );
4930         else
4931             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4932     memset( dib_bits, 0xaa, 64 * 4 );
4933
4934     ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4935     ok( ret == 5, "got %d\n", ret );
4936     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4937     memset( dib_bits, 0xaa, 64 * 4 );
4938
4939     /* b-u -> t-d */
4940
4941     info->bmiHeader.biHeight = 8;
4942     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4943     ok( ret == 8, "got %d\n", ret );
4944     for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4945     memset( dib_bits, 0xaa, 64 * 4 );
4946
4947     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4948     ok( ret == 5, "got %d\n", ret );
4949     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4950     for (i = 16; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4951     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4952     memset( dib_bits, 0xaa, 64 * 4 );
4953
4954     info->bmiHeader.biHeight = 16;
4955     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4956     ok( ret == 7, "got %d\n", ret );
4957     for (i = 0; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4958     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4959     memset( dib_bits, 0xaa, 64 * 4 );
4960
4961     ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, 0, -4, 1, 12, data, info, DIB_RGB_COLORS );
4962     ok( ret == 3, "got %d\n", ret );
4963     for (i = 0; i < 64; i++)
4964         if ((i >= 36 && i <= 39) || (i >= 44 && i <= 47) || (i >= 52 && i <= 55))
4965             ok( dib_bits[i] == inverted_data[i + 68], "%d: got %08x\n", i, dib_bits[i] );
4966         else
4967             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4968     memset( dib_bits, 0xaa, 64 * 4 );
4969
4970     ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, -30, -30, 1, 12, data, info, DIB_RGB_COLORS );
4971     ok( ret == 0, "got %d\n", ret );
4972     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4973     memset( dib_bits, 0xaa, 64 * 4 );
4974
4975     ret = SetDIBitsToDevice( hdc, 5, -5, 8, 16, -2, -4, 4, 12, data, info, DIB_RGB_COLORS );
4976     ok( ret == 8, "got %d\n", ret );
4977     for (i = 0; i < 64; i++)
4978         if (i == 7 || i == 15 || i == 23)
4979             ok( dib_bits[i] == inverted_data[i + 97], "%d: got %08x\n", i, dib_bits[i] );
4980         else
4981             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4982     memset( dib_bits, 0xaa, 64 * 4 );
4983
4984     info->bmiHeader.biHeight = 5;
4985     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4986     ok( ret == 2, "got %d\n", ret );
4987     for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4988     for (i = 40; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4989     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4990     memset( dib_bits, 0xaa, 64 * 4 );
4991
4992     ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4993     ok( ret == 5, "got %d\n", ret );
4994     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4995     memset( dib_bits, 0xaa, 64 * 4 );
4996
4997     /* handling of partial color table */
4998
4999     info->bmiHeader.biHeight   = -8;
5000     info->bmiHeader.biBitCount = 8;
5001     info->bmiHeader.biClrUsed  = 137;
5002     for (i = 0; i < 256; i++)
5003     {
5004         info->bmiColors[i].rgbRed      = 255 - i;
5005         info->bmiColors[i].rgbGreen    = i * 2;
5006         info->bmiColors[i].rgbBlue     = i;
5007         info->bmiColors[i].rgbReserved = 0;
5008     }
5009     for (i = 0; i < 64; i++) ((BYTE *)data)[i] = i * 4 + 1;
5010     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5011     ok( ret == 8, "got %d\n", ret );
5012     for (i = 0; i < 64; i++)
5013     {
5014         int idx = i * 4 + 1;
5015         DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : (info->bmiColors[idx].rgbRed << 16 |
5016                                                                info->bmiColors[idx].rgbGreen << 8 |
5017                                                                info->bmiColors[idx].rgbBlue);
5018         ok( dib_bits[i] == expect, "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
5019     }
5020     memset( dib_bits, 0xaa, 64 * 4 );
5021
5022     /* handling of DIB_PAL_COLORS */
5023
5024     pal->palVersion = 0x300;
5025     pal->palNumEntries = 137;
5026     info->bmiHeader.biClrUsed = 221;
5027     for (i = 0; i < 256; i++)
5028     {
5029         palent[i].peRed   = i * 2;
5030         palent[i].peGreen = 255 - i;
5031         palent[i].peBlue  = i;
5032     }
5033     palette = CreatePalette( pal );
5034     ok( palette != 0, "palette creation failed\n" );
5035     SelectPalette( hdc, palette, FALSE );
5036     for (i = 0; i < 256; i++) ((WORD *)info->bmiColors)[i] = 255 - i;
5037     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_PAL_COLORS );
5038     ok( ret == 8, "got %d\n", ret );
5039     for (i = 0; i < 64; i++)
5040     {
5041         int idx = i * 4 + 1;
5042         int ent = (255 - idx) % pal->palNumEntries;
5043         DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 :
5044                         (palent[ent].peRed << 16 | palent[ent].peGreen << 8 | palent[ent].peBlue);
5045         ok( dib_bits[i] == expect || broken(dib_bits[i] == 0),
5046             "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
5047     }
5048     memset( dib_bits, 0xaa, 64 * 4 );
5049
5050     DeleteDC( hdc );
5051     DeleteObject( dib );
5052     DeleteObject( palette );
5053     HeapFree( GetProcessHeap(), 0, info );
5054 }
5055
5056 static void test_SetDIBitsToDevice_RLE8(void)
5057 {
5058     BITMAPINFO *info;
5059     DWORD *dib_bits;
5060     HDC hdc = CreateCompatibleDC( 0 );
5061     BYTE rle8_data[20] = { 0x04, 0x02, 0x03, 0xf0, 0x00, 0x00,     /* 2, 2, 2, 2, f0, f0, f0, <eol> */
5062                            0x00, 0x03, 0x04, 0x05, 0x06, 0x00,     /* 4, 5, 6, <pad> */
5063                            0x00, 0x02, 0x01, 0x02, 0x05, 0x80,     /* dx=1, dy=2, 80, 80, 80, 80, (80) */
5064                            0x00, 0x01 };                           /* <eod> */
5065     HBITMAP dib;
5066     int i, ret;
5067     DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
5068                             0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5069                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5070                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
5071                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5072                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5073                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5074                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
5075     DWORD top_down[64]  = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5076                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5077                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5078                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5079                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
5080                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5081                             0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5082                             0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
5083
5084     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
5085
5086     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
5087     info->bmiHeader.biWidth       = 8;
5088     info->bmiHeader.biHeight      = 8;
5089     info->bmiHeader.biPlanes      = 1;
5090     info->bmiHeader.biBitCount    = 32;
5091     info->bmiHeader.biCompression = BI_RGB;
5092
5093     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5094     memset( dib_bits, 0xaa, 64 * 4 );
5095     SelectObject( hdc, dib );
5096
5097     info->bmiHeader.biBitCount    = 8;
5098     info->bmiHeader.biCompression = BI_RLE8;
5099     info->bmiHeader.biSizeImage   = sizeof(rle8_data);
5100
5101     for (i = 0; i < 256; i++)
5102     {
5103         info->bmiColors[i].rgbRed      = i;
5104         info->bmiColors[i].rgbGreen    = i;
5105         info->bmiColors[i].rgbBlue     = i;
5106         info->bmiColors[i].rgbReserved = 0;
5107     }
5108
5109     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5110     ok( ret == 8, "got %d\n", ret );
5111     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5112     memset( dib_bits, 0xaa, 64 * 4 );
5113
5114     /* startscan and lines are ignored, unless lines == 0 */
5115     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 8, rle8_data, info, DIB_RGB_COLORS );
5116     ok( ret == 8, "got %d\n", ret );
5117     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5118     memset( dib_bits, 0xaa, 64 * 4 );
5119
5120     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 1, rle8_data, info, DIB_RGB_COLORS );
5121     ok( ret == 8, "got %d\n", ret );
5122     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5123     memset( dib_bits, 0xaa, 64 * 4 );
5124
5125     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 0, rle8_data, info, DIB_RGB_COLORS );
5126     ok( ret == 0, "got %d\n", ret );
5127     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5128     memset( dib_bits, 0xaa, 64 * 4 );
5129
5130     info->bmiHeader.biWidth = 2;
5131     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5132     ok( ret == 8, "got %d\n", ret );
5133     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5134     memset( dib_bits, 0xaa, 64 * 4 );
5135
5136     info->bmiHeader.biWidth  = 8;
5137     info->bmiHeader.biHeight = 2;
5138     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5139     ok( ret == 2, "got %d\n", ret );
5140     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5141     memset( dib_bits, 0xaa, 64 * 4 );
5142
5143     info->bmiHeader.biHeight = 9;
5144     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5145     ok( ret == 9, "got %d\n", ret );
5146     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5147     memset( dib_bits, 0xaa, 64 * 4 );
5148
5149     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5150     ok( ret == 9, "got %d\n", ret );
5151     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5152     memset( dib_bits, 0xaa, 64 * 4 );
5153
5154     info->bmiHeader.biHeight = 8;
5155     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 9, rle8_data, info, DIB_RGB_COLORS );
5156     ok( ret == 8, "got %d\n", ret );
5157     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5158     memset( dib_bits, 0xaa, 64 * 4 );
5159
5160     ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5161     ok( ret == 8, "got %d\n", ret );
5162     for (i = 0; i < 40; i++) ok( dib_bits[i] == bottom_up[i + 24], "%d: got %08x\n", i, dib_bits[i] );
5163     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5164     memset( dib_bits, 0xaa, 64 * 4 );
5165
5166     ret = SetDIBitsToDevice( hdc, 0, 3, 4, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5167     ok( ret == 8, "got %d\n", ret );
5168     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5169     for (i = 8; i < 40; i++)
5170         if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5171         else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5172     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5173     memset( dib_bits, 0xaa, 64 * 4 );
5174
5175     ret = SetDIBitsToDevice( hdc, 3, 3, 8, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5176     ok( ret == 8, "got %d\n", ret );
5177     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5178     for (i = 8; i < 40; i++)
5179         if ((i & 7) < 3) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5180         else ok( dib_bits[i] == bottom_up[i - 11], "%d: got %08x\n", i, dib_bits[i] );
5181     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5182     memset( dib_bits, 0xaa, 64 * 4 );
5183
5184     ret = SetDIBitsToDevice( hdc, 2, 3, 8, 4, 2, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5185     ok( ret == 8, "got %d\n", ret );
5186     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5187     for (i = 8; i < 40; i++)
5188         if ((i & 7) < 2) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5189         else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5190     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5191     memset( dib_bits, 0xaa, 64 * 4 );
5192
5193     info->bmiHeader.biWidth = 37;
5194     info->bmiHeader.biHeight = 37;
5195     ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
5196     ok( ret == 37, "got %d\n", ret );
5197     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5198     for (i = 24; i < 64; i++)
5199         if (i == 52) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
5200         else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5201         else ok( dib_bits[i] == bottom_up[i - 20], "%d: got %08x\n", i, dib_bits[i] );
5202     memset( dib_bits, 0xaa, 64 * 4 );
5203
5204     /* top-down compressed dibs are invalid */
5205     info->bmiHeader.biWidth = 8;
5206     info->bmiHeader.biHeight = -8;
5207     SetLastError( 0xdeadbeef );
5208     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5209     ok( ret == 0, "got %d\n", ret );
5210     ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
5211
5212     /* top-down dst */
5213
5214     info->bmiHeader.biHeight      = -8;
5215     info->bmiHeader.biBitCount    = 32;
5216     info->bmiHeader.biCompression = BI_RGB;
5217     info->bmiHeader.biSizeImage   = 0;
5218
5219     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5220     memset( dib_bits, 0xaa, 16 * 16 * 4 );
5221     DeleteObject( SelectObject( hdc, dib ));
5222
5223     info->bmiHeader.biHeight      = 8;
5224     info->bmiHeader.biBitCount    = 8;
5225     info->bmiHeader.biCompression = BI_RLE8;
5226     info->bmiHeader.biSizeImage   = sizeof(rle8_data);
5227
5228     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5229     ok( ret == 8, "got %d\n", ret );
5230     for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5231     memset( dib_bits, 0xaa, 64 * 4 );
5232
5233     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5234     ok( ret == 8, "got %d\n", ret );
5235     for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5236     memset( dib_bits, 0xaa, 64 * 4 );
5237
5238     info->bmiHeader.biHeight = 4;
5239     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5240     ok( ret == 4, "got %d\n", ret );
5241     for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5242     memset( dib_bits, 0xaa, 64 * 4 );
5243
5244     info->bmiHeader.biHeight = 9;
5245     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5246     ok( ret == 9, "got %d\n", ret );
5247     for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5248     memset( dib_bits, 0xaa, 64 * 4 );
5249
5250     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5251     ok( ret == 9, "got %d\n", ret );
5252     for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5253     memset( dib_bits, 0xaa, 64 * 4 );
5254
5255     ret = SetDIBitsToDevice( hdc, 2, 3, 8, 6, 2, 2, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5256     ok( ret == 9, "got %d\n", ret );
5257     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5258     for (i = 24; i < 64; i++) ok( dib_bits[i] == top_down[i - 24], "%d: got %08x\n", i, dib_bits[i] );
5259     memset( dib_bits, 0xaa, 64 * 4 );
5260
5261     info->bmiHeader.biWidth = 37;
5262     info->bmiHeader.biHeight = 37;
5263     ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
5264     ok( ret == 37, "got %d\n", ret );
5265     for (i = 0; i < 40; i++)
5266         if (i == 12) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
5267         else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5268         else ok( dib_bits[i] == top_down[i + 28], "%d: got %08x\n", i, dib_bits[i] );
5269     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5270     memset( dib_bits, 0xaa, 64 * 4 );
5271
5272     DeleteDC( hdc );
5273     DeleteObject( dib );
5274     HeapFree( GetProcessHeap(), 0, info );
5275 }
5276
5277 START_TEST(bitmap)
5278 {
5279     HMODULE hdll;
5280
5281     hdll = GetModuleHandle("gdi32.dll");
5282     pGdiAlphaBlend   = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
5283     pGdiGradientFill = (void*)GetProcAddress(hdll, "GdiGradientFill");
5284     pSetLayout       = (void*)GetProcAddress(hdll, "SetLayout");
5285
5286     test_createdibitmap();
5287     test_dibsections();
5288     test_dib_formats();
5289     test_mono_dibsection();
5290     test_bitmap();
5291     test_bmBits();
5292     test_GetDIBits_selected_DIB(1);
5293     test_GetDIBits_selected_DIB(4);
5294     test_GetDIBits_selected_DIB(8);
5295     test_GetDIBits_selected_DDB(TRUE);
5296     test_GetDIBits_selected_DDB(FALSE);
5297     test_GetDIBits();
5298     test_GetDIBits_BI_BITFIELDS();
5299     test_select_object();
5300     test_CreateBitmap();
5301     test_BitBlt();
5302     test_StretchBlt();
5303     test_StretchDIBits();
5304     test_GdiAlphaBlend();
5305     test_GdiGradientFill();
5306     test_32bit_ddb();
5307     test_bitmapinfoheadersize();
5308     test_get16dibits();
5309     test_clipping();
5310     test_GetDIBits_top_down(16);
5311     test_GetDIBits_top_down(24);
5312     test_GetDIBits_top_down(32);
5313     test_GetSetDIBits_rtl();
5314     test_GetDIBits_scanlines();
5315     test_SetDIBits();
5316     test_SetDIBits_RLE4();
5317     test_SetDIBits_RLE8();
5318     test_SetDIBitsToDevice();
5319     test_SetDIBitsToDevice_RLE8();
5320 }