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