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