d3drm: Implement IDirect3DRMMeshImpl_GetGroupMaterial.
[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 void 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
3363     memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3364     bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3365     bitmapInfo.bmiHeader.biWidth = 2;
3366     bitmapInfo.bmiHeader.biHeight = -2;
3367     bitmapInfo.bmiHeader.biPlanes = 1;
3368     bitmapInfo.bmiHeader.biBitCount = 32;
3369     bitmapInfo.bmiHeader.biCompression = BI_RGB;
3370
3371     memset(dstBuffer, 0, 16);
3372     StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
3373                   nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3374                   srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
3375     ok(memcmp(dstBuffer, expected, 16) == 0,
3376         "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
3377         "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
3378         expected[0], expected[1], expected[2], expected[3],
3379         dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
3380         nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3381         nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
3382 }
3383
3384 static void test_StretchDIBits(void)
3385 {
3386     HBITMAP bmpDst;
3387     HBITMAP oldDst;
3388     HDC hdcScreen, hdcDst;
3389     UINT32 *dstBuffer, srcBuffer[4];
3390     HBRUSH hBrush, hOldBrush;
3391     BITMAPINFO biDst;
3392     UINT32 expected[4];
3393
3394     memset(&biDst, 0, sizeof(BITMAPINFO));
3395     biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3396     biDst.bmiHeader.biWidth = 2;
3397     biDst.bmiHeader.biHeight = -2;
3398     biDst.bmiHeader.biPlanes = 1;
3399     biDst.bmiHeader.biBitCount = 32;
3400     biDst.bmiHeader.biCompression = BI_RGB;
3401
3402     hdcScreen = CreateCompatibleDC(0);
3403     hdcDst = CreateCompatibleDC(hdcScreen);
3404
3405     /* Pixel Tests */
3406     bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3407         NULL, 0);
3408     oldDst = SelectObject(hdcDst, bmpDst);
3409
3410     hBrush = CreateSolidBrush(0x012345678);
3411     hOldBrush = SelectObject(hdcDst, hBrush);
3412
3413     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3414     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3415     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3416     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3417     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3418     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3419     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3420     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3421     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3422     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3423     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3424     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3425     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3426     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3427     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3428
3429     SelectObject(hdcDst, hOldBrush);
3430     DeleteObject(hBrush);
3431
3432     /* Top-down destination tests */
3433     srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3434     srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
3435
3436     expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
3437     expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
3438     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3439                                 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3440
3441     expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3442     expected[2] = 0x00000000, expected[3] = 0x00000000;
3443     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3444                                 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
3445
3446     expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
3447     expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
3448     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3449                                 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
3450
3451     expected[0] = 0x42441000, expected[1] = 0x00000000;
3452     expected[2] = 0x00000000, expected[3] = 0x00000000;
3453     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3454                                 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
3455
3456     expected[0] = 0x00000000, expected[1] = 0x00000000;
3457     expected[2] = 0x00000000, expected[3] = 0x00000000;
3458     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3459                                 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3460
3461     expected[0] = 0x00000000, expected[1] = 0x00000000;
3462     expected[2] = 0x00000000, expected[3] = 0x00000000;
3463     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3464                                 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3465
3466     expected[0] = 0x00000000, expected[1] = 0x00000000;
3467     expected[2] = 0x00000000, expected[3] = 0x00000000;
3468     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3469                                 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
3470
3471     expected[0] = 0x00000000, expected[1] = 0x00000000;
3472     expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
3473     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3474                                 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3475
3476     SelectObject(hdcDst, oldDst);
3477     DeleteObject(bmpDst);
3478
3479     /* Bottom up destination tests */
3480     biDst.bmiHeader.biHeight = 2;
3481     bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3482         NULL, 0);
3483     oldDst = SelectObject(hdcDst, bmpDst);
3484
3485     expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3486     expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
3487     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3488                                 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3489
3490     /* Tidy up */
3491     SelectObject(hdcDst, oldDst);
3492     DeleteObject(bmpDst);
3493     DeleteDC(hdcDst);
3494
3495     DeleteDC(hdcScreen);
3496 }
3497
3498 static void test_GdiAlphaBlend(void)
3499 {
3500     HDC hdcNull;
3501     HDC hdcDst;
3502     HBITMAP bmpDst;
3503     HBITMAP oldDst;
3504     BITMAPINFO *bmi;
3505     HDC hdcSrc;
3506     HBITMAP bmpSrc;
3507     HBITMAP oldSrc;
3508     LPVOID bits;
3509     BOOL ret;
3510     BLENDFUNCTION blend;
3511
3512     if (!pGdiAlphaBlend)
3513     {
3514         win_skip("GdiAlphaBlend() is not implemented\n");
3515         return;
3516     }
3517
3518     hdcNull = GetDC(NULL);
3519     hdcDst = CreateCompatibleDC(hdcNull);
3520     bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
3521     hdcSrc = CreateCompatibleDC(hdcNull);
3522
3523     bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3524     bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3525     bmi->bmiHeader.biHeight = 20;
3526     bmi->bmiHeader.biWidth = 20;
3527     bmi->bmiHeader.biBitCount = 32;
3528     bmi->bmiHeader.biPlanes = 1;
3529     bmi->bmiHeader.biCompression = BI_RGB;
3530     bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3531     ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3532
3533     oldDst = SelectObject(hdcDst, bmpDst);
3534     oldSrc = SelectObject(hdcSrc, bmpSrc);
3535
3536     blend.BlendOp = AC_SRC_OVER;
3537     blend.BlendFlags = 0;
3538     blend.SourceConstantAlpha = 128;
3539     blend.AlphaFormat = 0;
3540
3541     SetLastError(0xdeadbeef);
3542     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3543     ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3544
3545     SetLastError(0xdeadbeef);
3546     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3547     ok( !ret, "GdiAlphaBlend succeeded\n" );
3548     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3549
3550     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3551     ok( !ret, "GdiAlphaBlend succeeded\n" );
3552     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend);
3553     ok( !ret, "GdiAlphaBlend succeeded\n" );
3554     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3555     ok( !ret, "GdiAlphaBlend succeeded\n" );
3556     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3557     ok( !ret, "GdiAlphaBlend succeeded\n" );
3558
3559     SetWindowOrgEx(hdcSrc, -10, -10, NULL);
3560     SetLastError(0xdeadbeef);
3561     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3562     ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3563     SetLastError(0xdeadbeef);
3564     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3565     ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3566     SetMapMode(hdcSrc, MM_ANISOTROPIC);
3567     ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
3568     SetLastError(0xdeadbeef);
3569     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend);
3570     ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3571     SetLastError(0xdeadbeef);
3572     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend);
3573     ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3574
3575     SetMapMode(hdcDst, MM_ANISOTROPIC);
3576     SetViewportExtEx(hdcDst, -1, -1, NULL);
3577     SetLastError(0xdeadbeef);
3578     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 50, 50, blend);
3579     todo_wine
3580     ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3581     SetLastError(0xdeadbeef);
3582     ret = pGdiAlphaBlend(hdcDst, -20, -20, 20, 20, hdcSrc, 0, -1, 50, 50, blend);
3583     ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3584     SetLastError(0xdeadbeef);
3585     ret = pGdiAlphaBlend(hdcDst, -20, -20, -20, -20, hdcSrc, 0, -1, 50, 50, blend);
3586     ok( !ret, "GdiAlphaBlend succeeded\n" );
3587     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3588     SetLastError(0xdeadbeef);
3589     ret = pGdiAlphaBlend(hdcDst, -20, 0, -20, 20, hdcSrc, 0, -1, 50, 50, blend);
3590     ok( !ret, "GdiAlphaBlend succeeded\n" );
3591     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3592     SetLastError(0xdeadbeef);
3593     ret = pGdiAlphaBlend(hdcDst, 0, -20, 20, -20, hdcSrc, 0, -1, 50, 50, blend);
3594     ok( !ret, "GdiAlphaBlend succeeded\n" );
3595     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3596     SetMapMode(hdcDst, MM_TEXT);
3597
3598     SetViewportExtEx(hdcSrc, -1, -1, NULL);
3599     SetLastError(0xdeadbeef);
3600     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, -30, -30, blend);
3601     ok( !ret, "GdiAlphaBlend succeeded\n" );
3602     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3603     SetLastError(0xdeadbeef);
3604     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, 30, -30, blend);
3605     ok( !ret, "GdiAlphaBlend succeeded\n" );
3606     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3607     SetLastError(0xdeadbeef);
3608     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, -30, 30, 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, 0, 0, 20, 20, hdcSrc, -20, -20, 30, 30, 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, 0, 20, 20, hdcSrc, 20, 20, 30, 30, blend);
3617     ok( !ret, "GdiAlphaBlend succeeded\n" );
3618     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3619     SetLastError(0xdeadbeef);
3620     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -60, -60, 30, 30, blend);
3621     ok( !ret, "GdiAlphaBlend succeeded\n" );
3622     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3623     SetViewportExtEx(hdcSrc, 1, 1, NULL);
3624
3625     SetLastError(0xdeadbeef);
3626     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend);
3627     ok( !ret, "GdiAlphaBlend succeeded\n" );
3628     ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3629
3630     /* overlapping source and dest not allowed */
3631
3632     SetLastError(0xdeadbeef);
3633     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 19, 19, 20, 20, blend);
3634     ok( !ret, "GdiAlphaBlend succeeded\n" );
3635     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3636
3637     SetLastError(0xdeadbeef);
3638     ret = pGdiAlphaBlend(hdcDst, 20, 20, 20, 20, hdcDst, 1, 1, 20, 20, blend);
3639     ok( !ret, "GdiAlphaBlend succeeded\n" );
3640     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3641
3642     SetLastError(0xdeadbeef);
3643     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 20, 10, 20, 20, blend);
3644     ok( ret, "GdiAlphaBlend succeeded\n" );
3645     SetLastError(0xdeadbeef);
3646     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 10, 20, 20, 20, blend);
3647     ok( ret, "GdiAlphaBlend succeeded\n" );
3648
3649     /* AC_SRC_ALPHA requires 32-bpp BI_RGB format */
3650
3651     blend.AlphaFormat = AC_SRC_ALPHA;
3652     SetLastError(0xdeadbeef);
3653     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3654     ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3655
3656     bmi->bmiHeader.biCompression = BI_BITFIELDS;
3657     ((DWORD *)bmi->bmiColors)[0] = 0xff0000;
3658     ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3659     ((DWORD *)bmi->bmiColors)[2] = 0x0000ff;
3660     bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3661     ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3662     oldSrc = SelectObject(hdcSrc, bmpSrc);
3663     DeleteObject( oldSrc );
3664
3665     SetLastError(0xdeadbeef);
3666     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3667     ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3668
3669     bmi->bmiHeader.biCompression = BI_BITFIELDS;
3670     ((DWORD *)bmi->bmiColors)[0] = 0x0000ff;
3671     ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3672     ((DWORD *)bmi->bmiColors)[2] = 0xff0000;
3673     bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3674     ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3675     oldSrc = SelectObject(hdcSrc, bmpSrc);
3676     DeleteObject( oldSrc );
3677
3678     SetLastError(0xdeadbeef);
3679     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3680     ok( !ret, "GdiAlphaBlend succeeded\n" );
3681     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3682
3683     bmi->bmiHeader.biBitCount = 24;
3684     bmi->bmiHeader.biCompression = BI_RGB;
3685     bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3686     ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3687     oldSrc = SelectObject(hdcSrc, bmpSrc);
3688     DeleteObject( oldSrc );
3689
3690     SetLastError(0xdeadbeef);
3691     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3692     ok( !ret, "GdiAlphaBlend succeeded\n" );
3693     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3694
3695     bmi->bmiHeader.biBitCount = 1;
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     bmpSrc = CreateBitmap( 100, 100, 1, 1, NULL );
3707     ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3708     oldSrc = SelectObject(hdcSrc, bmpSrc);
3709     DeleteObject( oldSrc );
3710
3711     SetLastError(0xdeadbeef);
3712     ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3713     ok( !ret, "GdiAlphaBlend succeeded\n" );
3714     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3715
3716     SelectObject(hdcDst, oldDst);
3717     SelectObject(hdcSrc, oldSrc);
3718     DeleteObject(bmpSrc);
3719     DeleteObject(bmpDst);
3720     DeleteDC(hdcDst);
3721     DeleteDC(hdcSrc);
3722
3723     ReleaseDC(NULL, hdcNull);
3724
3725 }
3726
3727 static void test_GdiGradientFill(void)
3728 {
3729     HDC hdc;
3730     BOOL ret;
3731     HBITMAP bmp;
3732     BITMAPINFO *bmi;
3733     void *bits;
3734     GRADIENT_RECT rect[] = { { 0, 0 }, { 0, 1 }, { 2, 3 } };
3735     GRADIENT_TRIANGLE tri[] = { { 0, 0, 0 }, { 0, 1, 2 }, { 0, 2, 1 }, { 0, 1, 3 } };
3736     TRIVERTEX vt[3] = { { 2,  2,  0xff00, 0x0000, 0x0000, 0x8000 },
3737                         { 10, 10, 0x0000, 0xff00, 0x0000, 0x8000 },
3738                         { 20, 10, 0x0000, 0x0000, 0xff00, 0xff00 } };
3739
3740     if (!pGdiGradientFill)
3741     {
3742         win_skip( "GdiGradientFill is not implemented\n" );
3743         return;
3744     }
3745
3746     hdc = CreateCompatibleDC( NULL );
3747     bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3748     bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3749     bmi->bmiHeader.biHeight = 20;
3750     bmi->bmiHeader.biWidth = 20;
3751     bmi->bmiHeader.biBitCount = 32;
3752     bmi->bmiHeader.biPlanes = 1;
3753     bmi->bmiHeader.biCompression = BI_RGB;
3754     bmp = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3755     ok( bmp != NULL, "couldn't create bitmap\n" );
3756     SelectObject( hdc, bmp );
3757
3758     SetLastError( 0xdeadbeef );
3759     ret = pGdiGradientFill( hdc, vt, 3, rect, 1, GRADIENT_FILL_RECT_H );
3760     ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3761     SetLastError( 0xdeadbeef );
3762     ret = pGdiGradientFill( hdc, vt, 3, rect, 1, 3 );
3763     ok( !ret, "GdiGradientFill succeeded\n" );
3764     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3765     SetLastError( 0xdeadbeef );
3766     ret = pGdiGradientFill( (HDC)0xdead, vt, 3, rect, 1, GRADIENT_FILL_RECT_H );
3767     ok( !ret, "GdiGradientFill succeeded\n" );
3768     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3769     SetLastError( 0xdeadbeef );
3770     ret = pGdiGradientFill( NULL, NULL, 0, rect, 1, GRADIENT_FILL_RECT_H );
3771     ok( !ret, "GdiGradientFill succeeded\n" );
3772     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3773     ret = pGdiGradientFill( hdc, NULL, 0, rect, 1, GRADIENT_FILL_RECT_H );
3774     ok( !ret, "GdiGradientFill succeeded\n" );
3775     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3776     SetLastError( 0xdeadbeef );
3777     ret = pGdiGradientFill( hdc, NULL, 3, rect, 1, GRADIENT_FILL_RECT_H );
3778     ok( !ret, "GdiGradientFill succeeded\n" );
3779     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3780     SetLastError( 0xdeadbeef );
3781     ret = pGdiGradientFill( hdc, vt, 3, NULL, 0, GRADIENT_FILL_RECT_H );
3782     ok( !ret, "GdiGradientFill succeeded\n" );
3783     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3784     SetLastError( 0xdeadbeef );
3785     ret = pGdiGradientFill( hdc, vt, 3, NULL, 1, GRADIENT_FILL_RECT_H );
3786     ok( !ret, "GdiGradientFill succeeded\n" );
3787     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3788     SetLastError( 0xdeadbeef );
3789     ret = pGdiGradientFill( hdc, vt, 3, rect, 0, 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( hdc, vt, 3, rect, 3, GRADIENT_FILL_RECT_H );
3794     ok( !ret, "GdiGradientFill succeeded\n" );
3795     ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3796     rect[2].UpperLeft = rect[2].LowerRight = 1;
3797     SetLastError( 0xdeadbeef );
3798     ret = pGdiGradientFill( hdc, vt, 3, rect, 3, GRADIENT_FILL_RECT_H );
3799     ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3800     SetLastError( 0xdeadbeef );
3801     ret = pGdiGradientFill( hdc, vt, 1, rect, 1, GRADIENT_FILL_RECT_H );
3802     ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3803     SetLastError( 0xdeadbeef );
3804     ret = pGdiGradientFill( hdc, vt, 1, tri, 0, GRADIENT_FILL_TRIANGLE );
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, 1, tri, 1, GRADIENT_FILL_TRIANGLE );
3809     ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3810     SetLastError( 0xdeadbeef );
3811     ret = pGdiGradientFill( hdc, vt, 3, tri, 2, GRADIENT_FILL_TRIANGLE );
3812     ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3813     SetLastError( 0xdeadbeef );
3814     ret = pGdiGradientFill( hdc, vt, 3, tri, 3, GRADIENT_FILL_TRIANGLE );
3815     ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3816     SetLastError( 0xdeadbeef );
3817     ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3818     ok( !ret, "GdiGradientFill succeeded\n" );
3819     ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3820     tri[3].Vertex3 = 1;
3821     SetLastError( 0xdeadbeef );
3822     ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3823     ok( !ret, "GdiGradientFill succeeded\n" );
3824     ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3825     tri[3].Vertex3 = 0;
3826     SetLastError( 0xdeadbeef );
3827     ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3828     ok( !ret, "GdiGradientFill succeeded\n" );
3829     ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3830     tri[3].Vertex1 = tri[3].Vertex2 = tri[3].Vertex3 = 1;
3831     SetLastError( 0xdeadbeef );
3832     ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3833     ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3834
3835     DeleteDC( hdc );
3836     DeleteObject( bmp );
3837 }
3838
3839 static void test_clipping(void)
3840 {
3841     HBITMAP bmpDst;
3842     HBITMAP bmpSrc;
3843     HRGN hRgn;
3844     LPVOID bits;
3845     BOOL result;
3846
3847     HDC hdcDst = CreateCompatibleDC( NULL );
3848     HDC hdcSrc = CreateCompatibleDC( NULL );
3849
3850     BITMAPINFO bmpinfo={{0}};
3851     bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3852     bmpinfo.bmiHeader.biWidth = 100;
3853     bmpinfo.bmiHeader.biHeight = 100;
3854     bmpinfo.bmiHeader.biPlanes = 1;
3855     bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3856     bmpinfo.bmiHeader.biCompression = BI_RGB;
3857
3858     bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3859     ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3860     SelectObject( hdcDst, bmpDst );
3861
3862     bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3863     ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3864     SelectObject( hdcSrc, bmpSrc );
3865
3866     result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3867     ok(result, "BitBlt failed\n");
3868
3869     hRgn = CreateRectRgn( 0,0,0,0 );
3870     SelectClipRgn( hdcDst, hRgn );
3871
3872     result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3873     ok(result, "BitBlt failed\n");
3874
3875     DeleteObject( bmpDst );
3876     DeleteObject( bmpSrc );
3877     DeleteObject( hRgn );
3878     DeleteDC( hdcDst );
3879     DeleteDC( hdcSrc );
3880 }
3881
3882 static void test_32bit_ddb(void)
3883 {
3884     char buffer[sizeof(BITMAPINFOHEADER) + sizeof(DWORD)];
3885     BITMAPINFO *biDst = (BITMAPINFO *)buffer;
3886     HBITMAP bmpSrc, bmpDst;
3887     HBITMAP oldSrc, oldDst;
3888     HDC hdcSrc, hdcDst, hdcScreen;
3889     HBRUSH brush;
3890     DWORD *dstBuffer, *data;
3891     DWORD colorSrc = 0x40201008;
3892
3893     memset(biDst, 0, sizeof(BITMAPINFOHEADER));
3894     biDst->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3895     biDst->bmiHeader.biWidth = 1;
3896     biDst->bmiHeader.biHeight = -1;
3897     biDst->bmiHeader.biPlanes = 1;
3898     biDst->bmiHeader.biBitCount = 32;
3899     biDst->bmiHeader.biCompression = BI_RGB;
3900
3901     hdcScreen = CreateCompatibleDC(0);
3902     if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3903     {
3904         DeleteDC(hdcScreen);
3905         trace("Skipping 32-bit DDB test\n");
3906         return;
3907     }
3908
3909     hdcSrc = CreateCompatibleDC(hdcScreen);
3910     bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3911     oldSrc = SelectObject(hdcSrc, bmpSrc);
3912
3913     hdcDst = CreateCompatibleDC(hdcScreen);
3914     bmpDst = CreateDIBSection(hdcDst, biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3915     oldDst = SelectObject(hdcDst, bmpDst);
3916
3917     StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3918     ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3919
3920     if (pGdiAlphaBlend)
3921     {
3922         BLENDFUNCTION blend;
3923         BOOL ret;
3924
3925         blend.BlendOp = AC_SRC_OVER;
3926         blend.BlendFlags = 0;
3927         blend.SourceConstantAlpha = 128;
3928         blend.AlphaFormat = 0;
3929         dstBuffer[0] = 0x80808080;
3930         ret = pGdiAlphaBlend( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, blend );
3931         ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3932         ok(dstBuffer[0] == 0x60504844, "wrong color %x\n", dstBuffer[0]);
3933         blend.AlphaFormat = AC_SRC_ALPHA;
3934         dstBuffer[0] = 0x80808080;
3935         ret = pGdiAlphaBlend( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, blend );
3936         ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3937         ok(dstBuffer[0] == 0x90807874, "wrong color %x\n", dstBuffer[0]);
3938     }
3939
3940     data = (DWORD *)biDst->bmiColors;
3941     data[0] = 0x20304050;
3942     brush = CreateDIBPatternBrushPt( biDst, DIB_RGB_COLORS );
3943     ok( brush != 0, "brush creation failed\n" );
3944     SelectObject( hdcSrc, brush );
3945     PatBlt( hdcSrc, 0, 0, 1, 1, PATCOPY );
3946     BitBlt( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, SRCCOPY );
3947     ok(dstBuffer[0] == data[0], "Expected color=%x, received color=%x\n", data[0], dstBuffer[0]);
3948     SelectObject( hdcSrc, GetStockObject(BLACK_BRUSH) );
3949     DeleteObject( brush );
3950
3951     biDst->bmiHeader.biBitCount = 24;
3952     brush = CreateDIBPatternBrushPt( biDst, DIB_RGB_COLORS );
3953     ok( brush != 0, "brush creation failed\n" );
3954     SelectObject( hdcSrc, brush );
3955     PatBlt( hdcSrc, 0, 0, 1, 1, PATCOPY );
3956     BitBlt( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, SRCCOPY );
3957     ok(dstBuffer[0] == (data[0] & ~0xff000000),
3958        "Expected color=%x, received color=%x\n", data[0] & 0xff000000, dstBuffer[0]);
3959     SelectObject( hdcSrc, GetStockObject(BLACK_BRUSH) );
3960     DeleteObject( brush );
3961
3962     /* Tidy up */
3963     SelectObject(hdcDst, oldDst);
3964     DeleteObject(bmpDst);
3965     DeleteDC(hdcDst);
3966
3967     SelectObject(hdcSrc, oldSrc);
3968     DeleteObject(bmpSrc);
3969     DeleteDC(hdcSrc);
3970
3971     DeleteDC(hdcScreen);
3972 }
3973
3974 /*
3975  * Used by test_GetDIBits_top_down to create the bitmap to test against.
3976  */
3977 static void setup_picture(char *picture, int bpp)
3978 {
3979     int i;
3980
3981     switch(bpp)
3982     {
3983         case 16:
3984         case 32:
3985             /*Set the first byte in each pixel to the index of that pixel.*/
3986             for (i = 0; i < 4; i++)
3987                 picture[i * (bpp / 8)] = i;
3988             break;
3989         case 24:
3990             picture[0] = 0;
3991             picture[3] = 1;
3992             /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
3993             picture[8] = 2;
3994             picture[11] = 3;
3995             break;
3996     }
3997 }
3998
3999 static void test_GetDIBits_top_down(int bpp)
4000 {
4001     BITMAPINFO bi;
4002     HBITMAP bmptb, bmpbt;
4003     HDC hdc;
4004     int pictureOut[4];
4005     int *picture;
4006     int statusCode;
4007
4008     memset( &bi, 0, sizeof(bi) );
4009     bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
4010     bi.bmiHeader.biWidth=2;
4011     bi.bmiHeader.biHeight=2;
4012     bi.bmiHeader.biPlanes=1;
4013     bi.bmiHeader.biBitCount=bpp;
4014     bi.bmiHeader.biCompression=BI_RGB;
4015
4016     /*Get the device context for the screen.*/
4017     hdc = GetDC(NULL);
4018     ok(hdc != NULL, "Could not get a handle to a device context.\n");
4019
4020     /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
4021     bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
4022     ok(bmpbt != NULL, "Could not create a DIB section.\n");
4023     /*Now that we have a pointer to the pixels, we write to them.*/
4024     setup_picture((char*)picture, bpp);
4025     /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
4026     bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
4027     bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
4028     ok(bmptb != NULL, "Could not create a DIB section.\n");
4029     /*Write to this top to bottom bitmap.*/
4030     setup_picture((char*)picture, bpp);
4031
4032     bi.bmiHeader.biWidth = 1;
4033
4034     bi.bmiHeader.biHeight = 2;
4035     statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
4036     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4037     /*Check the first byte of the pixel.*/
4038     ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
4039     statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
4040     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4041     ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
4042     /*Check second scanline.*/
4043     statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
4044     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4045     ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
4046     statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
4047     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4048     ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
4049     /*Check both scanlines.*/
4050     statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
4051     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4052     ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
4053     ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
4054     statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
4055     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4056     ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
4057     ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
4058
4059     /*Make destination bitmap top-down.*/
4060     bi.bmiHeader.biHeight = -2;
4061     statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
4062     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4063     ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
4064     statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
4065     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4066     ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
4067     /*Check second scanline.*/
4068     statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
4069     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4070     ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
4071     statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
4072     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4073     ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
4074     /*Check both scanlines.*/
4075     statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
4076     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4077     ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
4078     ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
4079     statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
4080     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4081     ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
4082     ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
4083
4084     DeleteObject(bmpbt);
4085     DeleteObject(bmptb);
4086 }
4087
4088 static void test_GetSetDIBits_rtl(void)
4089 {
4090     HDC hdc, hdc_mem;
4091     HBITMAP bitmap, orig_bitmap;
4092     BITMAPINFO info;
4093     int ret;
4094     DWORD bits_1[8 * 8], bits_2[8 * 8];
4095
4096     if(!pSetLayout)
4097     {
4098         win_skip("Don't have SetLayout\n");
4099         return;
4100     }
4101
4102     hdc = GetDC( NULL );
4103     hdc_mem = CreateCompatibleDC( hdc );
4104     pSetLayout( hdc_mem, LAYOUT_LTR );
4105
4106     bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
4107     orig_bitmap = SelectObject( hdc_mem, bitmap );
4108     SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
4109     SelectObject( hdc_mem, orig_bitmap );
4110
4111     info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
4112     info.bmiHeader.biWidth = 8;
4113     info.bmiHeader.biHeight = 8;
4114     info.bmiHeader.biPlanes = 1;
4115     info.bmiHeader.biBitCount = 32;
4116     info.bmiHeader.biCompression = BI_RGB;
4117
4118     /* First show that GetDIBits ignores the layout mode. */
4119
4120     ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
4121     ok(ret == 8, "got %d\n", ret);
4122     ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
4123
4124     pSetLayout( hdc_mem, LAYOUT_RTL );
4125
4126     ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
4127     ok(ret == 8, "got %d\n", ret);
4128
4129     ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
4130
4131     /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
4132        followed by a GetDIBits and show that the bits remain unchanged. */
4133
4134     pSetLayout( hdc_mem, LAYOUT_LTR );
4135
4136     ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
4137     ok(ret == 8, "got %d\n", ret);
4138     ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
4139     ok(ret == 8, "got %d\n", ret);
4140     ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
4141
4142     pSetLayout( hdc_mem, LAYOUT_RTL );
4143
4144     ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
4145     ok(ret == 8, "got %d\n", ret);
4146     ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
4147     ok(ret == 8, "got %d\n", ret);
4148     ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
4149
4150     DeleteObject( bitmap );
4151     DeleteDC( hdc_mem );
4152     ReleaseDC( NULL, hdc );
4153 }
4154
4155 static void test_GetDIBits_scanlines(void)
4156 {
4157     BITMAPINFO *info;
4158     DWORD *dib_bits;
4159     HDC hdc = GetDC( NULL );
4160     HBITMAP dib;
4161     DWORD data[128], inverted_bits[64];
4162     int i, ret;
4163
4164     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4165
4166     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4167     info->bmiHeader.biWidth       = 8;
4168     info->bmiHeader.biHeight      = 8;
4169     info->bmiHeader.biPlanes      = 1;
4170     info->bmiHeader.biBitCount    = 32;
4171     info->bmiHeader.biCompression = BI_RGB;
4172
4173     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4174
4175     for (i = 0; i < 64; i++)
4176     {
4177         dib_bits[i] = i;
4178         inverted_bits[56 - (i & ~7) + (i & 7)] = i;
4179     }
4180
4181     /* b-u -> b-u */
4182
4183     memset( data, 0xaa, sizeof(data) );
4184
4185     ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4186     ok( ret == 8, "got %d\n", ret );
4187     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4188     memset( data, 0xaa, sizeof(data) );
4189
4190     ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4191     ok( ret == 5, "got %d\n", ret );
4192     ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
4193     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4194     memset( data, 0xaa, sizeof(data) );
4195
4196     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4197     ok( ret == 7, "got %d\n", ret );
4198     ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
4199     for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4200     memset( data, 0xaa, sizeof(data) );
4201
4202     ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4203     ok( ret == 1, "got %d\n", ret );
4204     for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4205     memset( data, 0xaa, sizeof(data) );
4206
4207     info->bmiHeader.biHeight = 16;
4208     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4209     ok( ret == 5, "got %d\n", ret );
4210     for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4211     ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
4212     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4213     memset( data, 0xaa, sizeof(data) );
4214
4215     ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
4216     ok( ret == 6, "got %d\n", ret );
4217     for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4218     ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
4219     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4220     memset( data, 0xaa, sizeof(data) );
4221
4222     ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
4223     ok( ret == 0, "got %d\n", ret );
4224     for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4225     for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4226     memset( data, 0xaa, sizeof(data) );
4227
4228     info->bmiHeader.biHeight = 5;
4229     ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4230     ok( ret == 2, "got %d\n", ret );
4231     ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
4232     for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4233     memset( data, 0xaa, sizeof(data) );
4234
4235     /* b-u -> t-d */
4236
4237     info->bmiHeader.biHeight = -8;
4238     ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4239     ok( ret == 8, "got %d\n", ret );
4240     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4241     memset( data, 0xaa, sizeof(data) );
4242
4243     ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4244     ok( ret == 5, "got %d\n", ret );
4245     ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
4246     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4247     memset( data, 0xaa, sizeof(data) );
4248
4249     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4250     ok( ret == 7, "got %d\n", ret );
4251     ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
4252     for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4253     memset( data, 0xaa, sizeof(data) );
4254
4255     ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4256     ok( ret == 4, "got %d\n", ret );
4257     ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
4258     for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4259     memset( data, 0xaa, sizeof(data) );
4260
4261     ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
4262     ok( ret == 5, "got %d\n", ret );
4263     ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
4264     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4265     memset( data, 0xaa, sizeof(data) );
4266
4267     ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
4268     ok( ret == 5, "got %d\n", ret );
4269     ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
4270     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4271     memset( data, 0xaa, sizeof(data) );
4272
4273     info->bmiHeader.biHeight = -16;
4274     ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
4275     ok( ret == 8, "got %d\n", ret );
4276     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4277     for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4278     memset( data, 0xaa, sizeof(data) );
4279
4280     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4281     ok( ret == 5, "got %d\n", ret );
4282     ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
4283     for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4284     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4285     memset( data, 0xaa, sizeof(data) );
4286
4287     ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4288     ok( ret == 8, "got %d\n", ret );
4289     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4290     for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4291     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4292     memset( data, 0xaa, sizeof(data) );
4293
4294     ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4295     ok( ret == 8, "got %d\n", ret );
4296     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4297     for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4298     for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4299     memset( data, 0xaa, sizeof(data) );
4300
4301     ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4302     ok( ret == 7, "got %d\n", ret );
4303     ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
4304     for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4305     memset( data, 0xaa, sizeof(data) );
4306
4307     ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
4308     ok( ret == 1, "got %d\n", ret );
4309     for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4310     memset( data, 0xaa, sizeof(data) );
4311
4312     info->bmiHeader.biHeight = -5;
4313     ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4314     ok( ret == 2, "got %d\n", ret );
4315     ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
4316     for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4317     memset( data, 0xaa, sizeof(data) );
4318
4319     DeleteObject( dib );
4320
4321     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4322     info->bmiHeader.biWidth       = 8;
4323     info->bmiHeader.biHeight      = -8;
4324     info->bmiHeader.biPlanes      = 1;
4325     info->bmiHeader.biBitCount    = 32;
4326     info->bmiHeader.biCompression = BI_RGB;
4327
4328     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4329
4330     for (i = 0; i < 64; i++) dib_bits[i] = i;
4331
4332     /* t-d -> t-d */
4333
4334     info->bmiHeader.biHeight = -8;
4335     ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4336     ok( ret == 8, "got %d\n", ret );
4337     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4338     memset( data, 0xaa, sizeof(data) );
4339
4340     ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4341     ok( ret == 5, "got %d\n", ret );
4342     ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
4343     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4344     memset( data, 0xaa, sizeof(data) );
4345
4346     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4347     ok( ret == 7, "got %d\n", ret );
4348     ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
4349     for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4350     memset( data, 0xaa, sizeof(data) );
4351
4352     ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4353     ok( ret == 4, "got %d\n", ret );
4354     ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
4355     for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4356     memset( data, 0xaa, sizeof(data) );
4357
4358     ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
4359     ok( ret == 5, "got %d\n", ret );
4360     ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
4361     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4362     memset( data, 0xaa, sizeof(data) );
4363
4364     ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
4365     ok( ret == 5, "got %d\n", ret );
4366     ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
4367     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4368     memset( data, 0xaa, sizeof(data) );
4369
4370     info->bmiHeader.biHeight = -16;
4371     ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
4372     ok( ret == 8, "got %d\n", ret );
4373     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4374     for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4375     memset( data, 0xaa, sizeof(data) );
4376
4377     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4378     ok( ret == 5, "got %d\n", ret );
4379     ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
4380     for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4381     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4382     memset( data, 0xaa, sizeof(data) );
4383
4384     ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4385     ok( ret == 8, "got %d\n", ret );
4386     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4387     for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4388     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4389     memset( data, 0xaa, sizeof(data) );
4390
4391     ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4392     ok( ret == 8, "got %d\n", ret );
4393     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4394     for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4395     for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4396     memset( data, 0xaa, sizeof(data) );
4397
4398     ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4399     ok( ret == 7, "got %d\n", ret );
4400     ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
4401     for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4402     memset( data, 0xaa, sizeof(data) );
4403
4404     info->bmiHeader.biHeight = -5;
4405     ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4406     ok( ret == 2, "got %d\n", ret );
4407     ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
4408     for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4409     memset( data, 0xaa, sizeof(data) );
4410
4411
4412     /* t-d -> b-u */
4413
4414     info->bmiHeader.biHeight = 8;
4415
4416     ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4417     ok( ret == 8, "got %d\n", ret );
4418     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4419     memset( data, 0xaa, sizeof(data) );
4420
4421     ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4422     ok( ret == 5, "got %d\n", ret );
4423     ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
4424     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4425     memset( data, 0xaa, sizeof(data) );
4426
4427     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4428     ok( ret == 7, "got %d\n", ret );
4429     ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
4430     for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4431     memset( data, 0xaa, sizeof(data) );
4432
4433     ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4434     ok( ret == 1, "got %d\n", ret );
4435     for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4436     memset( data, 0xaa, sizeof(data) );
4437
4438     info->bmiHeader.biHeight = 16;
4439     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4440     ok( ret == 5, "got %d\n", ret );
4441     for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4442     ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
4443     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4444     memset( data, 0xaa, sizeof(data) );
4445
4446     ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
4447     ok( ret == 6, "got %d\n", ret );
4448     for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4449     ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
4450     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4451     memset( data, 0xaa, sizeof(data) );
4452
4453     ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
4454     ok( ret == 0, "got %d\n", ret );
4455     for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4456     for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4457     memset( data, 0xaa, sizeof(data) );
4458
4459     info->bmiHeader.biHeight = 5;
4460     ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4461     ok( ret == 2, "got %d\n", ret );
4462     ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
4463     for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4464     memset( data, 0xaa, sizeof(data) );
4465
4466     DeleteObject( dib );
4467
4468     ReleaseDC( NULL, hdc );
4469     HeapFree( GetProcessHeap(), 0, info );
4470 }
4471
4472
4473 static void test_SetDIBits(void)
4474 {
4475     char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
4476     LOGPALETTE *pal = (LOGPALETTE *)palbuf;
4477     PALETTEENTRY *palent = pal->palPalEntry;
4478     HPALETTE palette;
4479     BITMAPINFO *info;
4480     DWORD *dib_bits;
4481     HDC hdc = GetDC( NULL );
4482     DWORD data[128], inverted_data[128];
4483     HBITMAP dib;
4484     int i, ret;
4485
4486     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4487
4488     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4489     info->bmiHeader.biWidth       = 8;
4490     info->bmiHeader.biHeight      = 8;
4491     info->bmiHeader.biPlanes      = 1;
4492     info->bmiHeader.biBitCount    = 32;
4493     info->bmiHeader.biCompression = BI_RGB;
4494
4495     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4496     memset( dib_bits, 0xaa, 64 * 4 );
4497
4498     for (i = 0; i < 128; i++)
4499     {
4500         data[i] = i;
4501         inverted_data[120 - (i & ~7) + (i & 7)] = i;
4502     }
4503
4504     /* b-u -> b-u */
4505
4506     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4507     ok( ret == 8, "got %d\n", ret );
4508     ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4509     memset( dib_bits, 0xaa, 64 * 4 );
4510
4511     ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4512     ok( ret == 5, "got %d\n", ret );
4513     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4514     ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
4515     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4516     memset( dib_bits, 0xaa, 64 * 4 );
4517
4518     /* top of dst is aligned with startscans down for the top of the src.
4519        Then starting from the bottom of src, lines rows are copied across. */
4520
4521     info->bmiHeader.biHeight = 16;
4522     ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4523     ok( ret == 12, "got %d\n", ret );
4524     ok( !memcmp( dib_bits, data + 56,  40 * 4 ), "bits differ\n");
4525     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4526     memset( dib_bits, 0xaa, 64 * 4 );
4527
4528     info->bmiHeader.biHeight = 5;
4529     ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4530     ok( ret == 2, "got %d\n", ret );
4531     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4532     ok( !memcmp( dib_bits + 32, data,  16 * 4 ), "bits differ\n");
4533     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4534     memset( dib_bits, 0xaa, 64 * 4 );
4535
4536     /* t-d -> b-u */
4537     info->bmiHeader.biHeight = -8;
4538     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4539     ok( ret == 8, "got %d\n", ret );
4540     ok( !memcmp( dib_bits, inverted_data + 64,  64 * 4 ), "bits differ\n");
4541     memset( dib_bits, 0xaa, 64 * 4 );
4542
4543     /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
4544        we copy lines rows from the top of the src */
4545
4546     ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4547     ok( ret == 5, "got %d\n", ret );
4548     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4549     ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
4550     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4551     memset( dib_bits, 0xaa, 64 * 4 );
4552
4553     info->bmiHeader.biHeight = -16;
4554     ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4555     ok( ret == 12, "got %d\n", ret );
4556     ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
4557     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4558     memset( dib_bits, 0xaa, 64 * 4 );
4559
4560     ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4561     ok( ret == 12, "got %d\n", ret );
4562     ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4563     memset( dib_bits, 0xaa, 64 * 4 );
4564
4565     ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4566     ok( ret == 12, "got %d\n", ret );
4567     ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
4568     memset( dib_bits, 0xaa, 64 * 4 );
4569
4570     info->bmiHeader.biHeight = -5;
4571     ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4572     ok( ret == 2, "got %d\n", ret );
4573     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4574     ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
4575     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4576     memset( dib_bits, 0xaa, 64 * 4 );
4577
4578     DeleteObject( dib );
4579
4580     info->bmiHeader.biHeight = -8;
4581
4582     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4583     memset( dib_bits, 0xaa, 16 * 16 * 4 );
4584
4585     /* t-d -> t-d */
4586
4587     /* like the t-d -> b-u case. */
4588
4589     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4590     ok( ret == 8, "got %d\n", ret );
4591     ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4592     memset( dib_bits, 0xaa, 64 * 4 );
4593
4594     ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4595     ok( ret == 5, "got %d\n", ret );
4596     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4597     ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
4598     for (i = 56; 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     info->bmiHeader.biHeight = -16;
4602     ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4603     ok( ret == 12, "got %d\n", ret );
4604     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4605     ok( !memcmp( dib_bits + 24, data,  40 * 4 ), "bits differ\n");
4606     memset( dib_bits, 0xaa, 64 * 4 );
4607
4608     info->bmiHeader.biHeight = -5;
4609     ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4610     ok( ret == 2, "got %d\n", ret );
4611     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4612     ok( !memcmp( dib_bits + 16, data,  16 * 4 ), "bits differ\n");
4613     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4614     memset( dib_bits, 0xaa, 64 * 4 );
4615
4616     /* b-u -> t-d */
4617     /* like the b-u -> b-u case */
4618
4619     info->bmiHeader.biHeight = 8;
4620     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4621     ok( ret == 8, "got %d\n", ret );
4622     ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4623     memset( dib_bits, 0xaa, 64 * 4 );
4624
4625     ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4626     ok( ret == 5, "got %d\n", ret );
4627     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4628     ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
4629     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4630     memset( dib_bits, 0xaa, 64 * 4 );
4631
4632     info->bmiHeader.biHeight = 16;
4633     ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4634     ok( ret == 12, "got %d\n", ret );
4635     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4636     ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
4637     memset( dib_bits, 0xaa, 64 * 4 );
4638
4639     info->bmiHeader.biHeight = 5;
4640     ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4641     ok( ret == 2, "got %d\n", ret );
4642     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4643     ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
4644     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4645     memset( dib_bits, 0xaa, 64 * 4 );
4646
4647     /* handling of partial color table */
4648
4649     info->bmiHeader.biHeight   = -8;
4650     info->bmiHeader.biBitCount = 8;
4651     info->bmiHeader.biClrUsed  = 137;
4652     for (i = 0; i < 256; i++)
4653     {
4654         info->bmiColors[i].rgbRed      = 255 - i;
4655         info->bmiColors[i].rgbGreen    = i * 2;
4656         info->bmiColors[i].rgbBlue     = i;
4657         info->bmiColors[i].rgbReserved = 0;
4658     }
4659     for (i = 0; i < 64; i++) ((BYTE *)data)[i] = i * 4 + 1;
4660     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4661     ok( ret == 8, "got %d\n", ret );
4662     for (i = 0; i < 64; i++)
4663     {
4664         int idx = i * 4 + 1;
4665         DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : (info->bmiColors[idx].rgbRed << 16 |
4666                                                                info->bmiColors[idx].rgbGreen << 8 |
4667                                                                info->bmiColors[idx].rgbBlue);
4668         ok( dib_bits[i] == expect, "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
4669     }
4670     memset( dib_bits, 0xaa, 64 * 4 );
4671
4672     /* handling of DIB_PAL_COLORS */
4673
4674     pal->palVersion = 0x300;
4675     pal->palNumEntries = 137;
4676     info->bmiHeader.biClrUsed = 221;
4677     for (i = 0; i < 256; i++)
4678     {
4679         palent[i].peRed   = i * 2;
4680         palent[i].peGreen = 255 - i;
4681         palent[i].peBlue  = i;
4682     }
4683     palette = CreatePalette( pal );
4684     ok( palette != 0, "palette creation failed\n" );
4685     SelectPalette( hdc, palette, FALSE );
4686     for (i = 0; i < 256; i++) ((WORD *)info->bmiColors)[i] = 255 - i;
4687     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_PAL_COLORS );
4688     ok( ret == 8, "got %d\n", ret );
4689     for (i = 0; i < 64; i++)
4690     {
4691         int idx = i * 4 + 1;
4692         int ent = (255 - idx) % pal->palNumEntries;
4693         DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 :
4694                         (palent[ent].peRed << 16 | palent[ent].peGreen << 8 | palent[ent].peBlue);
4695         ok( dib_bits[i] == expect || broken(dib_bits[i] == 0),  /* various Windows versions get some values wrong */
4696             "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
4697     }
4698     memset( dib_bits, 0xaa, 64 * 4 );
4699
4700     ReleaseDC( NULL, hdc );
4701     DeleteObject( dib );
4702     DeleteObject( palette );
4703     HeapFree( GetProcessHeap(), 0, info );
4704 }
4705
4706 static void test_SetDIBits_RLE4(void)
4707 {
4708     BITMAPINFO *info;
4709     DWORD *dib_bits;
4710     HDC hdc = GetDC( NULL );
4711     BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00,     /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
4712                            0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
4713                            0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00,     /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
4714                            0x00, 0x02, 0x01, 0x02, 0x05, 0x87,     /* dx=1, dy=2, 8, 7, 8, 7, 8 */
4715                            0x00, 0x01 };                           /* <eod> */
4716     HBITMAP dib;
4717     int i, ret;
4718     DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
4719                             0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
4720                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4721                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4722                             0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
4723                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4724                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4725                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4726
4727     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4728
4729     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4730     info->bmiHeader.biWidth       = 8;
4731     info->bmiHeader.biHeight      = 8;
4732     info->bmiHeader.biPlanes      = 1;
4733     info->bmiHeader.biBitCount    = 32;
4734     info->bmiHeader.biCompression = BI_RGB;
4735
4736     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4737     memset( dib_bits, 0xaa, 64 * 4 );
4738
4739     info->bmiHeader.biBitCount    = 4;
4740     info->bmiHeader.biCompression = BI_RLE4;
4741     info->bmiHeader.biSizeImage   = sizeof(rle4_data);
4742
4743     for (i = 0; i < 16; i++)
4744     {
4745         info->bmiColors[i].rgbRed      = i;
4746         info->bmiColors[i].rgbGreen    = i;
4747         info->bmiColors[i].rgbBlue     = i;
4748         info->bmiColors[i].rgbReserved = 0;
4749     }
4750
4751     ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
4752     ok( ret == 8, "got %d\n", ret );
4753     ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
4754     memset( dib_bits, 0xaa, 64 * 4 );
4755
4756     DeleteObject( dib );
4757     ReleaseDC( NULL, hdc );
4758     HeapFree( GetProcessHeap(), 0, info );
4759 }
4760
4761 static void test_SetDIBits_RLE8(void)
4762 {
4763     BITMAPINFO *info;
4764     DWORD *dib_bits;
4765     HDC hdc = GetDC( NULL );
4766     BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00,     /* 2, 2, 2, f0, f0, f0, f0, <eol> */
4767                            0x00, 0x03, 0x04, 0x05, 0x06, 0x00,     /* 4, 5, 6, <pad> */
4768                            0x00, 0x02, 0x01, 0x02, 0x05, 0x80,     /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4769                            0x00, 0x01 };                           /* <eod> */
4770     HBITMAP dib;
4771     int i, ret;
4772     DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4773                             0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4774                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4775                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4776                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4777                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4778                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4779                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4780     DWORD top_down[64]  = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4781                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4782                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4783                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4784                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4785                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4786                             0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4787                             0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4788
4789     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4790
4791     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4792     info->bmiHeader.biWidth       = 8;
4793     info->bmiHeader.biHeight      = 8;
4794     info->bmiHeader.biPlanes      = 1;
4795     info->bmiHeader.biBitCount    = 32;
4796     info->bmiHeader.biCompression = BI_RGB;
4797
4798     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4799     memset( dib_bits, 0xaa, 64 * 4 );
4800
4801     info->bmiHeader.biBitCount    = 8;
4802     info->bmiHeader.biCompression = BI_RLE8;
4803     info->bmiHeader.biSizeImage   = sizeof(rle8_data);
4804
4805     for (i = 0; i < 256; i++)
4806     {
4807         info->bmiColors[i].rgbRed      = i;
4808         info->bmiColors[i].rgbGreen    = i;
4809         info->bmiColors[i].rgbBlue     = i;
4810         info->bmiColors[i].rgbReserved = 0;
4811     }
4812
4813     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4814     ok( ret == 8, "got %d\n", ret );
4815     ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4816     memset( dib_bits, 0xaa, 64 * 4 );
4817
4818     /* startscan and lines are ignored, unless lines == 0 */
4819     ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4820     ok( ret == 8, "got %d\n", ret );
4821     ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4822     memset( dib_bits, 0xaa, 64 * 4 );
4823
4824     ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4825     ok( ret == 8, "got %d\n", ret );
4826     ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4827     memset( dib_bits, 0xaa, 64 * 4 );
4828
4829     ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4830     ok( ret == 0, "got %d\n", ret );
4831     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4832     memset( dib_bits, 0xaa, 64 * 4 );
4833
4834     /* reduce width to 4, left-hand side of dst is touched. */
4835     info->bmiHeader.biWidth = 4;
4836     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4837     ok( ret == 8, "got %d\n", ret );
4838     for (i = 0; i < 64; i++)
4839     {
4840         DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4841         ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4842     }
4843     memset( dib_bits, 0xaa, 64 * 4 );
4844
4845     /* Show that the top lines are aligned by adjusting the height of the src */
4846
4847     /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4848     info->bmiHeader.biWidth  = 8;
4849     info->bmiHeader.biHeight = 4;
4850     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4851     ok( ret == 4, "got %d\n", ret );
4852     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4853     ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4854     memset( dib_bits, 0xaa, 64 * 4 );
4855
4856     /* increase the height to 9 -> everything moves down one row. */
4857     info->bmiHeader.biHeight = 9;
4858     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4859     ok( ret == 9, "got %d\n", ret );
4860     ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4861     for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4862     memset( dib_bits, 0xaa, 64 * 4 );
4863
4864     /* top-down compressed dibs are invalid */
4865     info->bmiHeader.biHeight = -8;
4866     SetLastError( 0xdeadbeef );
4867     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4868     ok( ret == 0, "got %d\n", ret );
4869     ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4870     DeleteObject( dib );
4871
4872     /* top-down dst */
4873
4874     info->bmiHeader.biHeight      = -8;
4875     info->bmiHeader.biBitCount    = 32;
4876     info->bmiHeader.biCompression = BI_RGB;
4877     info->bmiHeader.biSizeImage   = 0;
4878
4879     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4880     memset( dib_bits, 0xaa, 16 * 16 * 4 );
4881
4882     info->bmiHeader.biHeight      = 8;
4883     info->bmiHeader.biBitCount    = 8;
4884     info->bmiHeader.biCompression = BI_RLE8;
4885     info->bmiHeader.biSizeImage   = sizeof(rle8_data);
4886
4887     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4888     ok( ret == 8, "got %d\n", ret );
4889     ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4890     memset( dib_bits, 0xaa, 64 * 4 );
4891
4892     info->bmiHeader.biHeight = 4;
4893     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4894     ok( ret == 4, "got %d\n", ret );
4895     ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4896     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4897     memset( dib_bits, 0xaa, 64 * 4 );
4898
4899     info->bmiHeader.biHeight = 9;
4900     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4901     ok( ret == 9, "got %d\n", ret );
4902     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4903     ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4904     memset( dib_bits, 0xaa, 64 * 4 );
4905
4906     DeleteObject( dib );
4907     ReleaseDC( NULL, hdc );
4908     HeapFree( GetProcessHeap(), 0, info );
4909 }
4910
4911 static void test_SetDIBitsToDevice(void)
4912 {
4913     char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
4914     LOGPALETTE *pal = (LOGPALETTE *)palbuf;
4915     PALETTEENTRY *palent = pal->palPalEntry;
4916     HPALETTE palette;
4917     BITMAPINFO *info;
4918     DWORD *dib_bits;
4919     HDC hdc = CreateCompatibleDC( 0 );
4920     DWORD data[128], inverted_data[128];
4921     HBITMAP dib;
4922     int i, ret;
4923
4924     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4925
4926     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4927     info->bmiHeader.biWidth       = 8;
4928     info->bmiHeader.biHeight      = 8;
4929     info->bmiHeader.biPlanes      = 1;
4930     info->bmiHeader.biBitCount    = 32;
4931     info->bmiHeader.biCompression = BI_RGB;
4932
4933     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4934     memset( dib_bits, 0xaa, 64 * 4 );
4935     SelectObject( hdc, dib );
4936
4937     for (i = 0; i < 128; i++)
4938     {
4939         data[i] = i;
4940         inverted_data[120 - (i & ~7) + (i & 7)] = i;
4941     }
4942
4943     /* b-u -> b-u */
4944
4945     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4946     ok( ret == 8, "got %d\n", ret );
4947     for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4948     memset( dib_bits, 0xaa, 64 * 4 );
4949
4950     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4951     ok( ret == 5, "got %d\n", ret );
4952     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4953     for (i = 8; i < 48; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4954     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4955     memset( dib_bits, 0xaa, 64 * 4 );
4956
4957     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 3, 1, 5, data, info, DIB_RGB_COLORS );
4958     ok( ret == 5, "got %d\n", ret );
4959     for (i = 0; i < 24; i++) ok( dib_bits[i] == data[i + 16], "%d: got %08x\n", i, dib_bits[i] );
4960     for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4961     memset( dib_bits, 0xaa, 64 * 4 );
4962
4963     info->bmiHeader.biHeight = 16;
4964     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4965     ok( ret == 7, "got %d\n", ret );
4966     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4967     for (i = 8; i < 64; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4968     memset( dib_bits, 0xaa, 64 * 4 );
4969
4970     ret = SetDIBitsToDevice( hdc, 0, 2, 8, 8, 0, 6, 1, 12, data, info, DIB_RGB_COLORS );
4971     ok( ret == 12, "got %d\n", ret );
4972     for (i = 0; i < 40; i++) ok( dib_bits[i] == data[i + 56], "%d: got %08x\n", i, dib_bits[i] );
4973     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4974     memset( dib_bits, 0xaa, 64 * 4 );
4975
4976     ret = SetDIBitsToDevice( hdc, 0, -4, 8, 8, 0, 3, 1, 12, data, info, DIB_RGB_COLORS );
4977     ok( ret == 10, "got %d\n", ret );
4978     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4979     for (i = 32; i < 64; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4980     memset( dib_bits, 0xaa, 64 * 4 );
4981
4982     ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, -3, 1, 12, data, info, DIB_RGB_COLORS );
4983     ok( ret == 4, "got %d\n", ret );
4984     for (i = 0; i < 32; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4985     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4986     memset( dib_bits, 0xaa, 64 * 4 );
4987
4988     ret = SetDIBitsToDevice( hdc, 0, 2, 8, 5, 0, -2, 1, 12, data, info, DIB_RGB_COLORS );
4989     ok( ret == 2, "got %d\n", ret );
4990     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4991     for (i = 32; i < 48; i++) ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4992     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4993     memset( dib_bits, 0xaa, 64 * 4 );
4994
4995     info->bmiHeader.biHeight = 5;
4996     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 2, 2, data, info, DIB_RGB_COLORS );
4997     ok( ret == 2, "got %d\n", ret );
4998     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4999     for (i = 16; i < 32; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
5000     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5001     memset( dib_bits, 0xaa, 64 * 4 );
5002
5003     ret = SetDIBitsToDevice( hdc, 3, 3, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
5004     ok( ret == 3, "got %d\n", ret );
5005     for (i = 0; i < 64; i++)
5006         if (i == 27 || i == 28 || i == 35 || i == 36)
5007             ok( dib_bits[i] == data[i - 18], "%d: got %08x\n", i, dib_bits[i] );
5008         else
5009             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5010     memset( dib_bits, 0xaa, 64 * 4 );
5011
5012     ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5013     ok( ret == 5, "got %d\n", ret );
5014     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5015     memset( dib_bits, 0xaa, 64 * 4 );
5016
5017     ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
5018     ok( ret == 0, "got %d\n", ret );
5019     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5020     memset( dib_bits, 0xaa, 64 * 4 );
5021
5022     SetMapMode( hdc, MM_ANISOTROPIC );
5023     SetWindowExtEx( hdc, 3, 3, NULL );
5024     ret = SetDIBitsToDevice( hdc, 2, 2, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
5025     ok( ret == 3, "got %d\n", ret );
5026     for (i = 0; i < 64; i++)
5027         if (i == 41 || i == 42 || i == 49 || i == 50)
5028             ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
5029         else
5030             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5031     memset( dib_bits, 0xaa, 64 * 4 );
5032
5033     SetWindowExtEx( hdc, -1, -1, NULL );
5034     ret = SetDIBitsToDevice( hdc, 2, 2, 4, 4, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
5035     ok( ret == 4, "got %d\n", ret );
5036     for (i = 0; i < 64; i++)
5037         if (i == 48 || i == 49 || i == 56 || i == 57)
5038             ok( dib_bits[i] == data[i - 37], "%d: got %08x\n", i, dib_bits[i] );
5039         else
5040             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5041     memset( dib_bits, 0xaa, 64 * 4 );
5042     SetMapMode( hdc, MM_TEXT );
5043
5044     if (pSetLayout)
5045     {
5046         pSetLayout( hdc, LAYOUT_RTL );
5047         ret = SetDIBitsToDevice( hdc, 1, 2, 3, 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 == 36 || i == 37 || i == 38 || i == 44 || i == 45 || i == 46)
5051                 ok( dib_bits[i] == data[i - 27], "%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         pSetLayout( hdc, LAYOUT_LTR );
5056     }
5057
5058     /* t-d -> b-u */
5059     info->bmiHeader.biHeight = -8;
5060     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5061     ok( ret == 8, "got %d\n", ret );
5062     for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
5063     memset( dib_bits, 0xaa, 64 * 4 );
5064
5065     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
5066     ok( ret == 5, "got %d\n", ret );
5067     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5068     for (i = 8; i < 48; i++) ok( dib_bits[i] == inverted_data[i + 80], "%d: got %08x\n", i, dib_bits[i] );
5069     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5070     memset( dib_bits, 0xaa, 64 * 4 );
5071
5072     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 4, 1, 5, data, info, DIB_RGB_COLORS );
5073     ok( ret == 5, "got %d\n", ret );
5074     for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
5075     for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5076     memset( dib_bits, 0xaa, 64 * 4 );
5077
5078     info->bmiHeader.biHeight = -16;
5079     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
5080     ok( ret == 12, "got %d\n", ret );
5081     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5082     for (i = 8; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 24], "%d: got %08x\n", i, dib_bits[i] );
5083     memset( dib_bits, 0xaa, 64 * 4 );
5084
5085     ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, 7, 1, 12, data, info, DIB_RGB_COLORS );
5086     ok( ret == 12, "got %d\n", ret );
5087     for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
5088     for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5089     memset( dib_bits, 0xaa, 64 * 4 );
5090
5091     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 4, 12, data, info, DIB_RGB_COLORS );
5092     ok( ret == 12, "got %d\n", ret );
5093     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5094     for (i = 32; i < 64; i++) ok( dib_bits[i] == inverted_data[i], "%d: got %08x\n", i, dib_bits[i] );
5095     memset( dib_bits, 0xaa, 64 * 4 );
5096
5097     ret = SetDIBitsToDevice( hdc, 0, -3, 8, 8, 0, 2, 4, 12, data, info, DIB_RGB_COLORS );
5098     ok( ret == 12, "got %d\n", ret );
5099     for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5100     for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5101     memset( dib_bits, 0xaa, 64 * 4 );
5102
5103     ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, -2, 4, 12, data, info, DIB_RGB_COLORS );
5104     ok( ret == 12, "got %d\n", ret );
5105     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5106     for (i = 24; i < 40; i++) ok( dib_bits[i] == inverted_data[i + 8], "%d: got %08x\n", i, dib_bits[i] );
5107     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5108     memset( dib_bits, 0xaa, 64 * 4 );
5109
5110     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 5, 12, data, info, DIB_RGB_COLORS );
5111     ok( ret == 12, "got %d\n", ret );
5112     for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5113     for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5114     memset( dib_bits, 0xaa, 64 * 4 );
5115
5116     ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
5117     ok( ret == 12, "got %d\n", ret );
5118     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5119     memset( dib_bits, 0xaa, 64 * 4 );
5120
5121     ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -2, -4, 0, 12, data, info, DIB_RGB_COLORS );
5122     ok( ret == 12, "got %d\n", ret );
5123     for (i = 0; i < 64; i++)
5124         if (i == 31 || i == 39 || i == 47 || i == 55 || i == 63)
5125             ok( dib_bits[i] == inverted_data[i + 1], "%d: got %08x\n", i, dib_bits[i] );
5126         else
5127             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5128     memset( dib_bits, 0xaa, 64 * 4 );
5129
5130     info->bmiHeader.biHeight = -5;
5131     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
5132     ok( ret == 2, "got %d\n", ret );
5133     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5134     for (i = 8; i < 24; i++) ok( dib_bits[i] == inverted_data[i + 104], "%d: got %08x\n", i, dib_bits[i] );
5135     for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5136     memset( dib_bits, 0xaa, 64 * 4 );
5137
5138     ret = SetDIBitsToDevice( hdc, 5, 4, 2, 2, 6, 3, 1, 5, data, info, DIB_RGB_COLORS );
5139     ok( ret == 5, "got %d\n", ret );
5140     for (i = 0; i < 64; i++)
5141         if (i == 21 || i == 22 || i == 29 || i == 30)
5142             ok( dib_bits[i] == inverted_data[i + 89], "%d: got %08x\n", i, dib_bits[i] );
5143         else
5144             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5145     memset( dib_bits, 0xaa, 64 * 4 );
5146
5147     ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5148     ok( ret == 5, "got %d\n", ret );
5149     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5150     memset( dib_bits, 0xaa, 64 * 4 );
5151
5152     info->bmiHeader.biHeight = -8;
5153
5154     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5155     DeleteObject( SelectObject( hdc, dib ));
5156     memset( dib_bits, 0xaa, 16 * 16 * 4 );
5157
5158     /* t-d -> t-d */
5159
5160     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5161     ok( ret == 8, "got %d\n", ret );
5162     for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
5163     memset( dib_bits, 0xaa, 64 * 4 );
5164
5165     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
5166     ok( ret == 5, "got %d\n", ret );
5167     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5168     for (i = 16; i < 56; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
5169     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5170     memset( dib_bits, 0xaa, 64 * 4 );
5171
5172     ret = SetDIBitsToDevice( hdc, 0, 3, 8, 3, 0, 2, 1, 5, data, info, DIB_RGB_COLORS );
5173     ok( ret == 5, "got %d\n", ret );
5174     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5175     for (i = 24; i < 48; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
5176     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5177     memset( dib_bits, 0xaa, 64 * 4 );
5178
5179     info->bmiHeader.biHeight = -16;
5180     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
5181     ok( ret == 12, "got %d\n", ret );
5182     for (i = 0; i < 56; i++) ok( dib_bits[i] == data[i + 40], "%d: got %08x\n", i, dib_bits[i] );
5183     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5184     memset( dib_bits, 0xaa, 64 * 4 );
5185
5186     ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -1, -8, 0, 12, data, info, DIB_RGB_COLORS );
5187     ok( ret == 12, "got %d\n", ret );
5188     for (i = 0; i < 64; i++)
5189         if (i == 6 || i == 7)
5190             ok( dib_bits[i] == data[i + 82], "%d: got %08x\n", i, dib_bits[i] );
5191         else
5192             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5193     memset( dib_bits, 0xaa, 64 * 4 );
5194
5195     info->bmiHeader.biHeight = -5;
5196     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
5197     ok( ret == 2, "got %d\n", ret );
5198     for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5199     for (i = 40; i < 56; i++) ok( dib_bits[i] == data[i - 40], "%d: got %08x\n", i, dib_bits[i] );
5200     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5201     memset( dib_bits, 0xaa, 64 * 4 );
5202
5203     ret = SetDIBitsToDevice( hdc, 7, 2, 8, 8, 1, 0, 0, 5, data, info, DIB_RGB_COLORS );
5204     ok( ret == 5, "got %d\n", ret );
5205     for (i = 0; i < 64; i++)
5206         if (i == 47 || i == 55 || i == 63)
5207             ok( dib_bits[i] == data[i - 46], "%d: got %08x\n", i, dib_bits[i] );
5208         else
5209             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5210     memset( dib_bits, 0xaa, 64 * 4 );
5211
5212     ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5213     ok( ret == 5, "got %d\n", ret );
5214     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5215     memset( dib_bits, 0xaa, 64 * 4 );
5216
5217     /* b-u -> t-d */
5218
5219     info->bmiHeader.biHeight = 8;
5220     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5221     ok( ret == 8, "got %d\n", ret );
5222     for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
5223     memset( dib_bits, 0xaa, 64 * 4 );
5224
5225     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
5226     ok( ret == 5, "got %d\n", ret );
5227     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5228     for (i = 16; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
5229     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5230     memset( dib_bits, 0xaa, 64 * 4 );
5231
5232     info->bmiHeader.biHeight = 16;
5233     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
5234     ok( ret == 7, "got %d\n", ret );
5235     for (i = 0; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
5236     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5237     memset( dib_bits, 0xaa, 64 * 4 );
5238
5239     ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, 0, -4, 1, 12, data, info, DIB_RGB_COLORS );
5240     ok( ret == 3, "got %d\n", ret );
5241     for (i = 0; i < 64; i++)
5242         if ((i >= 36 && i <= 39) || (i >= 44 && i <= 47) || (i >= 52 && i <= 55))
5243             ok( dib_bits[i] == inverted_data[i + 68], "%d: got %08x\n", i, dib_bits[i] );
5244         else
5245             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5246     memset( dib_bits, 0xaa, 64 * 4 );
5247
5248     ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, -30, -30, 1, 12, data, info, DIB_RGB_COLORS );
5249     ok( ret == 0, "got %d\n", ret );
5250     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5251     memset( dib_bits, 0xaa, 64 * 4 );
5252
5253     ret = SetDIBitsToDevice( hdc, 5, -5, 8, 16, -2, -4, 4, 12, data, info, DIB_RGB_COLORS );
5254     ok( ret == 8, "got %d\n", ret );
5255     for (i = 0; i < 64; i++)
5256         if (i == 7 || i == 15 || i == 23)
5257             ok( dib_bits[i] == inverted_data[i + 97], "%d: got %08x\n", i, dib_bits[i] );
5258         else
5259             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5260     memset( dib_bits, 0xaa, 64 * 4 );
5261
5262     info->bmiHeader.biHeight = 5;
5263     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
5264     ok( ret == 2, "got %d\n", ret );
5265     for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5266     for (i = 40; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
5267     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5268     memset( dib_bits, 0xaa, 64 * 4 );
5269
5270     ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5271     ok( ret == 5, "got %d\n", ret );
5272     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5273     memset( dib_bits, 0xaa, 64 * 4 );
5274
5275     /* handling of partial color table */
5276
5277     info->bmiHeader.biHeight   = -8;
5278     info->bmiHeader.biBitCount = 8;
5279     info->bmiHeader.biClrUsed  = 137;
5280     for (i = 0; i < 256; i++)
5281     {
5282         info->bmiColors[i].rgbRed      = 255 - i;
5283         info->bmiColors[i].rgbGreen    = i * 2;
5284         info->bmiColors[i].rgbBlue     = i;
5285         info->bmiColors[i].rgbReserved = 0;
5286     }
5287     for (i = 0; i < 64; i++) ((BYTE *)data)[i] = i * 4 + 1;
5288     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5289     ok( ret == 8, "got %d\n", ret );
5290     for (i = 0; i < 64; i++)
5291     {
5292         int idx = i * 4 + 1;
5293         DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : (info->bmiColors[idx].rgbRed << 16 |
5294                                                                info->bmiColors[idx].rgbGreen << 8 |
5295                                                                info->bmiColors[idx].rgbBlue);
5296         ok( dib_bits[i] == expect, "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
5297     }
5298     memset( dib_bits, 0xaa, 64 * 4 );
5299
5300     /* handling of DIB_PAL_COLORS */
5301
5302     pal->palVersion = 0x300;
5303     pal->palNumEntries = 137;
5304     info->bmiHeader.biClrUsed = 221;
5305     for (i = 0; i < 256; i++)
5306     {
5307         palent[i].peRed   = i * 2;
5308         palent[i].peGreen = 255 - i;
5309         palent[i].peBlue  = i;
5310     }
5311     palette = CreatePalette( pal );
5312     ok( palette != 0, "palette creation failed\n" );
5313     SelectPalette( hdc, palette, FALSE );
5314     for (i = 0; i < 256; i++) ((WORD *)info->bmiColors)[i] = 255 - i;
5315     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_PAL_COLORS );
5316     ok( ret == 8, "got %d\n", ret );
5317     for (i = 0; i < 64; i++)
5318     {
5319         int idx = i * 4 + 1;
5320         int ent = (255 - idx) % pal->palNumEntries;
5321         DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 :
5322                         (palent[ent].peRed << 16 | palent[ent].peGreen << 8 | palent[ent].peBlue);
5323         ok( dib_bits[i] == expect || broken(dib_bits[i] == 0),
5324             "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
5325     }
5326     memset( dib_bits, 0xaa, 64 * 4 );
5327
5328     DeleteDC( hdc );
5329     DeleteObject( dib );
5330     DeleteObject( palette );
5331     HeapFree( GetProcessHeap(), 0, info );
5332 }
5333
5334 static void test_SetDIBitsToDevice_RLE8(void)
5335 {
5336     BITMAPINFO *info;
5337     DWORD *dib_bits;
5338     HDC hdc = CreateCompatibleDC( 0 );
5339     BYTE rle8_data[20] = { 0x04, 0x02, 0x03, 0xf0, 0x00, 0x00,     /* 2, 2, 2, 2, f0, f0, f0, <eol> */
5340                            0x00, 0x03, 0x04, 0x05, 0x06, 0x00,     /* 4, 5, 6, <pad> */
5341                            0x00, 0x02, 0x01, 0x02, 0x05, 0x80,     /* dx=1, dy=2, 80, 80, 80, 80, (80) */
5342                            0x00, 0x01 };                           /* <eod> */
5343     HBITMAP dib;
5344     int i, ret;
5345     DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
5346                             0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5347                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5348                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
5349                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5350                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5351                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5352                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
5353     DWORD top_down[64]  = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5354                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5355                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5356                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5357                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
5358                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5359                             0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5360                             0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
5361
5362     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
5363
5364     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
5365     info->bmiHeader.biWidth       = 8;
5366     info->bmiHeader.biHeight      = 8;
5367     info->bmiHeader.biPlanes      = 1;
5368     info->bmiHeader.biBitCount    = 32;
5369     info->bmiHeader.biCompression = BI_RGB;
5370
5371     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5372     memset( dib_bits, 0xaa, 64 * 4 );
5373     SelectObject( hdc, dib );
5374
5375     info->bmiHeader.biBitCount    = 8;
5376     info->bmiHeader.biCompression = BI_RLE8;
5377     info->bmiHeader.biSizeImage   = sizeof(rle8_data);
5378
5379     for (i = 0; i < 256; i++)
5380     {
5381         info->bmiColors[i].rgbRed      = i;
5382         info->bmiColors[i].rgbGreen    = i;
5383         info->bmiColors[i].rgbBlue     = i;
5384         info->bmiColors[i].rgbReserved = 0;
5385     }
5386
5387     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5388     ok( ret == 8, "got %d\n", ret );
5389     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5390     memset( dib_bits, 0xaa, 64 * 4 );
5391
5392     /* startscan and lines are ignored, unless lines == 0 */
5393     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 8, rle8_data, info, DIB_RGB_COLORS );
5394     ok( ret == 8, "got %d\n", ret );
5395     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5396     memset( dib_bits, 0xaa, 64 * 4 );
5397
5398     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 1, rle8_data, info, DIB_RGB_COLORS );
5399     ok( ret == 8, "got %d\n", ret );
5400     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5401     memset( dib_bits, 0xaa, 64 * 4 );
5402
5403     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 0, rle8_data, info, DIB_RGB_COLORS );
5404     ok( ret == 0, "got %d\n", ret );
5405     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5406     memset( dib_bits, 0xaa, 64 * 4 );
5407
5408     info->bmiHeader.biWidth = 2;
5409     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5410     ok( ret == 8, "got %d\n", ret );
5411     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5412     memset( dib_bits, 0xaa, 64 * 4 );
5413
5414     info->bmiHeader.biWidth  = 8;
5415     info->bmiHeader.biHeight = 2;
5416     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5417     ok( ret == 2, "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     info->bmiHeader.biHeight = 9;
5422     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5423     ok( ret == 9, "got %d\n", ret );
5424     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5425     memset( dib_bits, 0xaa, 64 * 4 );
5426
5427     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5428     ok( ret == 9, "got %d\n", ret );
5429     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5430     memset( dib_bits, 0xaa, 64 * 4 );
5431
5432     info->bmiHeader.biHeight = 8;
5433     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 9, rle8_data, info, DIB_RGB_COLORS );
5434     ok( ret == 8, "got %d\n", ret );
5435     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5436     memset( dib_bits, 0xaa, 64 * 4 );
5437
5438     ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5439     ok( ret == 8, "got %d\n", ret );
5440     for (i = 0; i < 40; i++) ok( dib_bits[i] == bottom_up[i + 24], "%d: got %08x\n", i, dib_bits[i] );
5441     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5442     memset( dib_bits, 0xaa, 64 * 4 );
5443
5444     ret = SetDIBitsToDevice( hdc, 0, 3, 4, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5445     ok( ret == 8, "got %d\n", ret );
5446     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5447     for (i = 8; i < 40; i++)
5448         if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5449         else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5450     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5451     memset( dib_bits, 0xaa, 64 * 4 );
5452
5453     ret = SetDIBitsToDevice( hdc, 3, 3, 8, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5454     ok( ret == 8, "got %d\n", ret );
5455     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5456     for (i = 8; i < 40; i++)
5457         if ((i & 7) < 3) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5458         else ok( dib_bits[i] == bottom_up[i - 11], "%d: got %08x\n", i, dib_bits[i] );
5459     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5460     memset( dib_bits, 0xaa, 64 * 4 );
5461
5462     ret = SetDIBitsToDevice( hdc, 2, 3, 8, 4, 2, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5463     ok( ret == 8, "got %d\n", ret );
5464     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5465     for (i = 8; i < 40; i++)
5466         if ((i & 7) < 2) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5467         else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5468     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5469     memset( dib_bits, 0xaa, 64 * 4 );
5470
5471     info->bmiHeader.biWidth = 37;
5472     info->bmiHeader.biHeight = 37;
5473     ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
5474     ok( ret == 37, "got %d\n", ret );
5475     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5476     for (i = 24; i < 64; i++)
5477         if (i == 52) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
5478         else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5479         else ok( dib_bits[i] == bottom_up[i - 20], "%d: got %08x\n", i, dib_bits[i] );
5480     memset( dib_bits, 0xaa, 64 * 4 );
5481
5482     /* top-down compressed dibs are invalid */
5483     info->bmiHeader.biWidth = 8;
5484     info->bmiHeader.biHeight = -8;
5485     SetLastError( 0xdeadbeef );
5486     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5487     ok( ret == 0, "got %d\n", ret );
5488     ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
5489
5490     /* top-down dst */
5491
5492     info->bmiHeader.biHeight      = -8;
5493     info->bmiHeader.biBitCount    = 32;
5494     info->bmiHeader.biCompression = BI_RGB;
5495     info->bmiHeader.biSizeImage   = 0;
5496
5497     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5498     memset( dib_bits, 0xaa, 16 * 16 * 4 );
5499     DeleteObject( SelectObject( hdc, dib ));
5500
5501     info->bmiHeader.biHeight      = 8;
5502     info->bmiHeader.biBitCount    = 8;
5503     info->bmiHeader.biCompression = BI_RLE8;
5504     info->bmiHeader.biSizeImage   = sizeof(rle8_data);
5505
5506     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5507     ok( ret == 8, "got %d\n", ret );
5508     for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5509     memset( dib_bits, 0xaa, 64 * 4 );
5510
5511     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5512     ok( ret == 8, "got %d\n", ret );
5513     for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5514     memset( dib_bits, 0xaa, 64 * 4 );
5515
5516     info->bmiHeader.biHeight = 4;
5517     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5518     ok( ret == 4, "got %d\n", ret );
5519     for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5520     memset( dib_bits, 0xaa, 64 * 4 );
5521
5522     info->bmiHeader.biHeight = 9;
5523     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5524     ok( ret == 9, "got %d\n", ret );
5525     for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5526     memset( dib_bits, 0xaa, 64 * 4 );
5527
5528     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5529     ok( ret == 9, "got %d\n", ret );
5530     for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5531     memset( dib_bits, 0xaa, 64 * 4 );
5532
5533     ret = SetDIBitsToDevice( hdc, 2, 3, 8, 6, 2, 2, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5534     ok( ret == 9, "got %d\n", ret );
5535     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5536     for (i = 24; i < 64; i++) ok( dib_bits[i] == top_down[i - 24], "%d: got %08x\n", i, dib_bits[i] );
5537     memset( dib_bits, 0xaa, 64 * 4 );
5538
5539     info->bmiHeader.biWidth = 37;
5540     info->bmiHeader.biHeight = 37;
5541     ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
5542     ok( ret == 37, "got %d\n", ret );
5543     for (i = 0; i < 40; i++)
5544         if (i == 12) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
5545         else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5546         else ok( dib_bits[i] == top_down[i + 28], "%d: got %08x\n", i, dib_bits[i] );
5547     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5548     memset( dib_bits, 0xaa, 64 * 4 );
5549
5550     DeleteDC( hdc );
5551     DeleteObject( dib );
5552     HeapFree( GetProcessHeap(), 0, info );
5553 }
5554
5555 START_TEST(bitmap)
5556 {
5557     HMODULE hdll;
5558
5559     hdll = GetModuleHandle("gdi32.dll");
5560     pGdiAlphaBlend   = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
5561     pGdiGradientFill = (void*)GetProcAddress(hdll, "GdiGradientFill");
5562     pSetLayout       = (void*)GetProcAddress(hdll, "SetLayout");
5563
5564     test_createdibitmap();
5565     test_dibsections();
5566     test_dib_formats();
5567     test_mono_dibsection();
5568     test_bitmap();
5569     test_mono_bitmap();
5570     test_bmBits();
5571     test_GetDIBits_selected_DIB(1);
5572     test_GetDIBits_selected_DIB(4);
5573     test_GetDIBits_selected_DIB(8);
5574     test_GetDIBits_selected_DDB(TRUE);
5575     test_GetDIBits_selected_DDB(FALSE);
5576     test_GetDIBits();
5577     test_GetDIBits_BI_BITFIELDS();
5578     test_select_object();
5579     test_CreateBitmap();
5580     test_BitBlt();
5581     test_StretchBlt();
5582     test_StretchDIBits();
5583     test_GdiAlphaBlend();
5584     test_GdiGradientFill();
5585     test_32bit_ddb();
5586     test_bitmapinfoheadersize();
5587     test_get16dibits();
5588     test_clipping();
5589     test_GetDIBits_top_down(16);
5590     test_GetDIBits_top_down(24);
5591     test_GetDIBits_top_down(32);
5592     test_GetSetDIBits_rtl();
5593     test_GetDIBits_scanlines();
5594     test_SetDIBits();
5595     test_SetDIBits_RLE4();
5596     test_SetDIBits_RLE8();
5597     test_SetDIBitsToDevice();
5598     test_SetDIBitsToDevice_RLE8();
5599 }