gdiplus: Test also lf.lfEscapement and lf.lfOrientation returned by GdipGetLogFont.
[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
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 }
3858
3859 static void test_clipping(void)
3860 {
3861     HBITMAP bmpDst;
3862     HBITMAP bmpSrc;
3863     HRGN hRgn;
3864     LPVOID bits;
3865     BOOL result;
3866
3867     HDC hdcDst = CreateCompatibleDC( NULL );
3868     HDC hdcSrc = CreateCompatibleDC( NULL );
3869
3870     BITMAPINFO bmpinfo={{0}};
3871     bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3872     bmpinfo.bmiHeader.biWidth = 100;
3873     bmpinfo.bmiHeader.biHeight = 100;
3874     bmpinfo.bmiHeader.biPlanes = 1;
3875     bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3876     bmpinfo.bmiHeader.biCompression = BI_RGB;
3877
3878     bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3879     ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3880     SelectObject( hdcDst, bmpDst );
3881
3882     bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3883     ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3884     SelectObject( hdcSrc, bmpSrc );
3885
3886     result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3887     ok(result, "BitBlt failed\n");
3888
3889     hRgn = CreateRectRgn( 0,0,0,0 );
3890     SelectClipRgn( hdcDst, hRgn );
3891
3892     result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3893     ok(result, "BitBlt failed\n");
3894
3895     DeleteObject( bmpDst );
3896     DeleteObject( bmpSrc );
3897     DeleteObject( hRgn );
3898     DeleteDC( hdcDst );
3899     DeleteDC( hdcSrc );
3900 }
3901
3902 static void test_32bit_ddb(void)
3903 {
3904     char buffer[sizeof(BITMAPINFOHEADER) + sizeof(DWORD)];
3905     BITMAPINFO *biDst = (BITMAPINFO *)buffer;
3906     HBITMAP bmpSrc, bmpDst;
3907     HBITMAP oldSrc, oldDst;
3908     HDC hdcSrc, hdcDst, hdcScreen;
3909     HBRUSH brush;
3910     DWORD *dstBuffer, *data;
3911     DWORD colorSrc = 0x40201008;
3912
3913     memset(biDst, 0, sizeof(BITMAPINFOHEADER));
3914     biDst->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3915     biDst->bmiHeader.biWidth = 1;
3916     biDst->bmiHeader.biHeight = -1;
3917     biDst->bmiHeader.biPlanes = 1;
3918     biDst->bmiHeader.biBitCount = 32;
3919     biDst->bmiHeader.biCompression = BI_RGB;
3920
3921     hdcScreen = CreateCompatibleDC(0);
3922     if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3923     {
3924         DeleteDC(hdcScreen);
3925         trace("Skipping 32-bit DDB test\n");
3926         return;
3927     }
3928
3929     hdcSrc = CreateCompatibleDC(hdcScreen);
3930     bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3931     oldSrc = SelectObject(hdcSrc, bmpSrc);
3932
3933     hdcDst = CreateCompatibleDC(hdcScreen);
3934     bmpDst = CreateDIBSection(hdcDst, biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3935     oldDst = SelectObject(hdcDst, bmpDst);
3936
3937     StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3938     ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3939
3940     if (pGdiAlphaBlend)
3941     {
3942         BLENDFUNCTION blend;
3943         BOOL ret;
3944
3945         blend.BlendOp = AC_SRC_OVER;
3946         blend.BlendFlags = 0;
3947         blend.SourceConstantAlpha = 128;
3948         blend.AlphaFormat = 0;
3949         dstBuffer[0] = 0x80808080;
3950         ret = pGdiAlphaBlend( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, blend );
3951         ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3952         ok(dstBuffer[0] == 0x60504844, "wrong color %x\n", dstBuffer[0]);
3953         blend.AlphaFormat = AC_SRC_ALPHA;
3954         dstBuffer[0] = 0x80808080;
3955         ret = pGdiAlphaBlend( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, blend );
3956         ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3957         ok(dstBuffer[0] == 0x90807874, "wrong color %x\n", dstBuffer[0]);
3958     }
3959
3960     data = (DWORD *)biDst->bmiColors;
3961     data[0] = 0x20304050;
3962     brush = CreateDIBPatternBrushPt( biDst, DIB_RGB_COLORS );
3963     ok( brush != 0, "brush creation failed\n" );
3964     SelectObject( hdcSrc, brush );
3965     PatBlt( hdcSrc, 0, 0, 1, 1, PATCOPY );
3966     BitBlt( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, SRCCOPY );
3967     ok(dstBuffer[0] == data[0], "Expected color=%x, received color=%x\n", data[0], dstBuffer[0]);
3968     SelectObject( hdcSrc, GetStockObject(BLACK_BRUSH) );
3969     DeleteObject( brush );
3970
3971     biDst->bmiHeader.biBitCount = 24;
3972     brush = CreateDIBPatternBrushPt( biDst, DIB_RGB_COLORS );
3973     ok( brush != 0, "brush creation failed\n" );
3974     SelectObject( hdcSrc, brush );
3975     PatBlt( hdcSrc, 0, 0, 1, 1, PATCOPY );
3976     BitBlt( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, SRCCOPY );
3977     ok(dstBuffer[0] == (data[0] & ~0xff000000),
3978        "Expected color=%x, received color=%x\n", data[0] & 0xff000000, dstBuffer[0]);
3979     SelectObject( hdcSrc, GetStockObject(BLACK_BRUSH) );
3980     DeleteObject( brush );
3981
3982     /* Tidy up */
3983     SelectObject(hdcDst, oldDst);
3984     DeleteObject(bmpDst);
3985     DeleteDC(hdcDst);
3986
3987     SelectObject(hdcSrc, oldSrc);
3988     DeleteObject(bmpSrc);
3989     DeleteDC(hdcSrc);
3990
3991     DeleteDC(hdcScreen);
3992 }
3993
3994 /*
3995  * Used by test_GetDIBits_top_down to create the bitmap to test against.
3996  */
3997 static void setup_picture(char *picture, int bpp)
3998 {
3999     int i;
4000
4001     switch(bpp)
4002     {
4003         case 16:
4004         case 32:
4005             /*Set the first byte in each pixel to the index of that pixel.*/
4006             for (i = 0; i < 4; i++)
4007                 picture[i * (bpp / 8)] = i;
4008             break;
4009         case 24:
4010             picture[0] = 0;
4011             picture[3] = 1;
4012             /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
4013             picture[8] = 2;
4014             picture[11] = 3;
4015             break;
4016     }
4017 }
4018
4019 static void test_GetDIBits_top_down(int bpp)
4020 {
4021     BITMAPINFO bi;
4022     HBITMAP bmptb, bmpbt;
4023     HDC hdc;
4024     int pictureOut[4];
4025     int *picture;
4026     int statusCode;
4027
4028     memset( &bi, 0, sizeof(bi) );
4029     bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
4030     bi.bmiHeader.biWidth=2;
4031     bi.bmiHeader.biHeight=2;
4032     bi.bmiHeader.biPlanes=1;
4033     bi.bmiHeader.biBitCount=bpp;
4034     bi.bmiHeader.biCompression=BI_RGB;
4035
4036     /*Get the device context for the screen.*/
4037     hdc = GetDC(NULL);
4038     ok(hdc != NULL, "Could not get a handle to a device context.\n");
4039
4040     /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
4041     bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
4042     ok(bmpbt != NULL, "Could not create a DIB section.\n");
4043     /*Now that we have a pointer to the pixels, we write to them.*/
4044     setup_picture((char*)picture, bpp);
4045     /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
4046     bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
4047     bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
4048     ok(bmptb != NULL, "Could not create a DIB section.\n");
4049     /*Write to this top to bottom bitmap.*/
4050     setup_picture((char*)picture, bpp);
4051
4052     bi.bmiHeader.biWidth = 1;
4053
4054     bi.bmiHeader.biHeight = 2;
4055     statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
4056     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4057     /*Check the first byte of the pixel.*/
4058     ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
4059     statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
4060     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4061     ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
4062     /*Check second scanline.*/
4063     statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
4064     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4065     ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
4066     statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
4067     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4068     ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
4069     /*Check both scanlines.*/
4070     statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
4071     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4072     ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
4073     ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
4074     statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
4075     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4076     ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
4077     ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
4078
4079     /*Make destination bitmap top-down.*/
4080     bi.bmiHeader.biHeight = -2;
4081     statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
4082     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4083     ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
4084     statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
4085     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4086     ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
4087     /*Check second scanline.*/
4088     statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
4089     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4090     ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
4091     statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
4092     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4093     ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
4094     /*Check both scanlines.*/
4095     statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
4096     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4097     ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
4098     ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
4099     statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
4100     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
4101     ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
4102     ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
4103
4104     DeleteObject(bmpbt);
4105     DeleteObject(bmptb);
4106 }
4107
4108 static void test_GetSetDIBits_rtl(void)
4109 {
4110     HDC hdc, hdc_mem;
4111     HBITMAP bitmap, orig_bitmap;
4112     BITMAPINFO info;
4113     int ret;
4114     DWORD bits_1[8 * 8], bits_2[8 * 8];
4115
4116     if(!pSetLayout)
4117     {
4118         win_skip("Don't have SetLayout\n");
4119         return;
4120     }
4121
4122     hdc = GetDC( NULL );
4123     hdc_mem = CreateCompatibleDC( hdc );
4124     pSetLayout( hdc_mem, LAYOUT_LTR );
4125
4126     bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
4127     orig_bitmap = SelectObject( hdc_mem, bitmap );
4128     SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
4129     SelectObject( hdc_mem, orig_bitmap );
4130
4131     info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
4132     info.bmiHeader.biWidth = 8;
4133     info.bmiHeader.biHeight = 8;
4134     info.bmiHeader.biPlanes = 1;
4135     info.bmiHeader.biBitCount = 32;
4136     info.bmiHeader.biCompression = BI_RGB;
4137
4138     /* First show that GetDIBits ignores the layout mode. */
4139
4140     ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
4141     ok(ret == 8, "got %d\n", ret);
4142     ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
4143
4144     pSetLayout( hdc_mem, LAYOUT_RTL );
4145
4146     ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
4147     ok(ret == 8, "got %d\n", ret);
4148
4149     ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
4150
4151     /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
4152        followed by a GetDIBits and show that the bits remain unchanged. */
4153
4154     pSetLayout( hdc_mem, LAYOUT_LTR );
4155
4156     ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
4157     ok(ret == 8, "got %d\n", ret);
4158     ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
4159     ok(ret == 8, "got %d\n", ret);
4160     ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
4161
4162     pSetLayout( hdc_mem, LAYOUT_RTL );
4163
4164     ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
4165     ok(ret == 8, "got %d\n", ret);
4166     ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
4167     ok(ret == 8, "got %d\n", ret);
4168     ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
4169
4170     DeleteObject( bitmap );
4171     DeleteDC( hdc_mem );
4172     ReleaseDC( NULL, hdc );
4173 }
4174
4175 static void test_GetDIBits_scanlines(void)
4176 {
4177     BITMAPINFO *info;
4178     DWORD *dib_bits;
4179     HDC hdc = GetDC( NULL );
4180     HBITMAP dib;
4181     DWORD data[128], inverted_bits[64];
4182     int i, ret;
4183
4184     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4185
4186     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4187     info->bmiHeader.biWidth       = 8;
4188     info->bmiHeader.biHeight      = 8;
4189     info->bmiHeader.biPlanes      = 1;
4190     info->bmiHeader.biBitCount    = 32;
4191     info->bmiHeader.biCompression = BI_RGB;
4192
4193     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4194
4195     for (i = 0; i < 64; i++)
4196     {
4197         dib_bits[i] = i;
4198         inverted_bits[56 - (i & ~7) + (i & 7)] = i;
4199     }
4200
4201     /* b-u -> b-u */
4202
4203     memset( data, 0xaa, sizeof(data) );
4204
4205     ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4206     ok( ret == 8, "got %d\n", ret );
4207     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4208     memset( data, 0xaa, sizeof(data) );
4209
4210     ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4211     ok( ret == 5, "got %d\n", ret );
4212     ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
4213     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4214     memset( data, 0xaa, sizeof(data) );
4215
4216     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4217     ok( ret == 7, "got %d\n", ret );
4218     ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
4219     for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4220     memset( data, 0xaa, sizeof(data) );
4221
4222     ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4223     ok( ret == 1, "got %d\n", ret );
4224     for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4225     memset( data, 0xaa, sizeof(data) );
4226
4227     info->bmiHeader.biHeight = 16;
4228     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4229     ok( ret == 5, "got %d\n", ret );
4230     for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4231     ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
4232     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4233     memset( data, 0xaa, sizeof(data) );
4234
4235     ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
4236     ok( ret == 6, "got %d\n", ret );
4237     for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4238     ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
4239     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4240     memset( data, 0xaa, sizeof(data) );
4241
4242     ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
4243     ok( ret == 0, "got %d\n", ret );
4244     for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4245     for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4246     memset( data, 0xaa, sizeof(data) );
4247
4248     info->bmiHeader.biHeight = 5;
4249     ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4250     ok( ret == 2, "got %d\n", ret );
4251     ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
4252     for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4253     memset( data, 0xaa, sizeof(data) );
4254
4255     /* b-u -> t-d */
4256
4257     info->bmiHeader.biHeight = -8;
4258     ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4259     ok( ret == 8, "got %d\n", ret );
4260     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4261     memset( data, 0xaa, sizeof(data) );
4262
4263     ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4264     ok( ret == 5, "got %d\n", ret );
4265     ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
4266     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4267     memset( data, 0xaa, sizeof(data) );
4268
4269     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4270     ok( ret == 7, "got %d\n", ret );
4271     ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
4272     for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4273     memset( data, 0xaa, sizeof(data) );
4274
4275     ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4276     ok( ret == 4, "got %d\n", ret );
4277     ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
4278     for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4279     memset( data, 0xaa, sizeof(data) );
4280
4281     ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
4282     ok( ret == 5, "got %d\n", ret );
4283     ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
4284     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4285     memset( data, 0xaa, sizeof(data) );
4286
4287     ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
4288     ok( ret == 5, "got %d\n", ret );
4289     ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
4290     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4291     memset( data, 0xaa, sizeof(data) );
4292
4293     info->bmiHeader.biHeight = -16;
4294     ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
4295     ok( ret == 8, "got %d\n", ret );
4296     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4297     for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4298     memset( data, 0xaa, sizeof(data) );
4299
4300     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4301     ok( ret == 5, "got %d\n", ret );
4302     ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
4303     for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4304     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4305     memset( data, 0xaa, sizeof(data) );
4306
4307     ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4308     ok( ret == 8, "got %d\n", ret );
4309     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4310     for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4311     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4312     memset( data, 0xaa, sizeof(data) );
4313
4314     ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4315     ok( ret == 8, "got %d\n", ret );
4316     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4317     for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4318     for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4319     memset( data, 0xaa, sizeof(data) );
4320
4321     ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4322     ok( ret == 7, "got %d\n", ret );
4323     ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
4324     for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4325     memset( data, 0xaa, sizeof(data) );
4326
4327     ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
4328     ok( ret == 1, "got %d\n", ret );
4329     for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4330     memset( data, 0xaa, sizeof(data) );
4331
4332     info->bmiHeader.biHeight = -5;
4333     ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4334     ok( ret == 2, "got %d\n", ret );
4335     ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
4336     for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4337     memset( data, 0xaa, sizeof(data) );
4338
4339     DeleteObject( dib );
4340
4341     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4342     info->bmiHeader.biWidth       = 8;
4343     info->bmiHeader.biHeight      = -8;
4344     info->bmiHeader.biPlanes      = 1;
4345     info->bmiHeader.biBitCount    = 32;
4346     info->bmiHeader.biCompression = BI_RGB;
4347
4348     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4349
4350     for (i = 0; i < 64; i++) dib_bits[i] = i;
4351
4352     /* t-d -> t-d */
4353
4354     info->bmiHeader.biHeight = -8;
4355     ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4356     ok( ret == 8, "got %d\n", ret );
4357     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4358     memset( data, 0xaa, sizeof(data) );
4359
4360     ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4361     ok( ret == 5, "got %d\n", ret );
4362     ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
4363     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4364     memset( data, 0xaa, sizeof(data) );
4365
4366     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4367     ok( ret == 7, "got %d\n", ret );
4368     ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
4369     for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4370     memset( data, 0xaa, sizeof(data) );
4371
4372     ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4373     ok( ret == 4, "got %d\n", ret );
4374     ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
4375     for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4376     memset( data, 0xaa, sizeof(data) );
4377
4378     ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
4379     ok( ret == 5, "got %d\n", ret );
4380     ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
4381     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4382     memset( data, 0xaa, sizeof(data) );
4383
4384     ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
4385     ok( ret == 5, "got %d\n", ret );
4386     ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
4387     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4388     memset( data, 0xaa, sizeof(data) );
4389
4390     info->bmiHeader.biHeight = -16;
4391     ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
4392     ok( ret == 8, "got %d\n", ret );
4393     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4394     for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4395     memset( data, 0xaa, sizeof(data) );
4396
4397     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4398     ok( ret == 5, "got %d\n", ret );
4399     ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
4400     for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4401     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4402     memset( data, 0xaa, sizeof(data) );
4403
4404     ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4405     ok( ret == 8, "got %d\n", ret );
4406     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4407     for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4408     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4409     memset( data, 0xaa, sizeof(data) );
4410
4411     ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4412     ok( ret == 8, "got %d\n", ret );
4413     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
4414     for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4415     for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4416     memset( data, 0xaa, sizeof(data) );
4417
4418     ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4419     ok( ret == 7, "got %d\n", ret );
4420     ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
4421     for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4422     memset( data, 0xaa, sizeof(data) );
4423
4424     info->bmiHeader.biHeight = -5;
4425     ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4426     ok( ret == 2, "got %d\n", ret );
4427     ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
4428     for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4429     memset( data, 0xaa, sizeof(data) );
4430
4431
4432     /* t-d -> b-u */
4433
4434     info->bmiHeader.biHeight = 8;
4435
4436     ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4437     ok( ret == 8, "got %d\n", ret );
4438     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
4439     memset( data, 0xaa, sizeof(data) );
4440
4441     ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4442     ok( ret == 5, "got %d\n", ret );
4443     ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
4444     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4445     memset( data, 0xaa, sizeof(data) );
4446
4447     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4448     ok( ret == 7, "got %d\n", ret );
4449     ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
4450     for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4451     memset( data, 0xaa, sizeof(data) );
4452
4453     ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
4454     ok( ret == 1, "got %d\n", ret );
4455     for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4456     memset( data, 0xaa, sizeof(data) );
4457
4458     info->bmiHeader.biHeight = 16;
4459     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4460     ok( ret == 5, "got %d\n", ret );
4461     for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4462     ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
4463     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4464     memset( data, 0xaa, sizeof(data) );
4465
4466     ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
4467     ok( ret == 6, "got %d\n", ret );
4468     for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4469     ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
4470     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4471     memset( data, 0xaa, sizeof(data) );
4472
4473     ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
4474     ok( ret == 0, "got %d\n", ret );
4475     for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4476     for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4477     memset( data, 0xaa, sizeof(data) );
4478
4479     info->bmiHeader.biHeight = 5;
4480     ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4481     ok( ret == 2, "got %d\n", ret );
4482     ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
4483     for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4484     memset( data, 0xaa, sizeof(data) );
4485
4486     DeleteObject( dib );
4487
4488     ReleaseDC( NULL, hdc );
4489     HeapFree( GetProcessHeap(), 0, info );
4490 }
4491
4492
4493 static void test_SetDIBits(void)
4494 {
4495     char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
4496     LOGPALETTE *pal = (LOGPALETTE *)palbuf;
4497     PALETTEENTRY *palent = pal->palPalEntry;
4498     HPALETTE palette;
4499     BITMAPINFO *info;
4500     DWORD *dib_bits;
4501     HDC hdc = GetDC( NULL );
4502     DWORD data[128], inverted_data[128];
4503     HBITMAP dib;
4504     int i, ret;
4505
4506     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4507
4508     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4509     info->bmiHeader.biWidth       = 8;
4510     info->bmiHeader.biHeight      = 8;
4511     info->bmiHeader.biPlanes      = 1;
4512     info->bmiHeader.biBitCount    = 32;
4513     info->bmiHeader.biCompression = BI_RGB;
4514
4515     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4516     memset( dib_bits, 0xaa, 64 * 4 );
4517
4518     for (i = 0; i < 128; i++)
4519     {
4520         data[i] = i;
4521         inverted_data[120 - (i & ~7) + (i & 7)] = i;
4522     }
4523
4524     /* b-u -> b-u */
4525
4526     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4527     ok( ret == 8, "got %d\n", ret );
4528     ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4529     memset( dib_bits, 0xaa, 64 * 4 );
4530
4531     ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4532     ok( ret == 5, "got %d\n", ret );
4533     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4534     ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
4535     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4536     memset( dib_bits, 0xaa, 64 * 4 );
4537
4538     /* top of dst is aligned with startscans down for the top of the src.
4539        Then starting from the bottom of src, lines rows are copied across. */
4540
4541     info->bmiHeader.biHeight = 16;
4542     ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4543     ok( ret == 12, "got %d\n", ret );
4544     ok( !memcmp( dib_bits, data + 56,  40 * 4 ), "bits differ\n");
4545     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4546     memset( dib_bits, 0xaa, 64 * 4 );
4547
4548     info->bmiHeader.biHeight = 5;
4549     ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4550     ok( ret == 2, "got %d\n", ret );
4551     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4552     ok( !memcmp( dib_bits + 32, data,  16 * 4 ), "bits differ\n");
4553     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4554     memset( dib_bits, 0xaa, 64 * 4 );
4555
4556     /* t-d -> b-u */
4557     info->bmiHeader.biHeight = -8;
4558     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4559     ok( ret == 8, "got %d\n", ret );
4560     ok( !memcmp( dib_bits, inverted_data + 64,  64 * 4 ), "bits differ\n");
4561     memset( dib_bits, 0xaa, 64 * 4 );
4562
4563     /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
4564        we copy lines rows from the top of the src */
4565
4566     ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4567     ok( ret == 5, "got %d\n", ret );
4568     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4569     ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
4570     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4571     memset( dib_bits, 0xaa, 64 * 4 );
4572
4573     info->bmiHeader.biHeight = -16;
4574     ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4575     ok( ret == 12, "got %d\n", ret );
4576     ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
4577     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4578     memset( dib_bits, 0xaa, 64 * 4 );
4579
4580     ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4581     ok( ret == 12, "got %d\n", ret );
4582     ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4583     memset( dib_bits, 0xaa, 64 * 4 );
4584
4585     ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4586     ok( ret == 12, "got %d\n", ret );
4587     ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
4588     memset( dib_bits, 0xaa, 64 * 4 );
4589
4590     info->bmiHeader.biHeight = -5;
4591     ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4592     ok( ret == 2, "got %d\n", ret );
4593     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4594     ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
4595     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4596     memset( dib_bits, 0xaa, 64 * 4 );
4597
4598     DeleteObject( dib );
4599
4600     info->bmiHeader.biHeight = -8;
4601
4602     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4603     memset( dib_bits, 0xaa, 16 * 16 * 4 );
4604
4605     /* t-d -> t-d */
4606
4607     /* like the t-d -> b-u case. */
4608
4609     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4610     ok( ret == 8, "got %d\n", ret );
4611     ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4612     memset( dib_bits, 0xaa, 64 * 4 );
4613
4614     ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4615     ok( ret == 5, "got %d\n", ret );
4616     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4617     ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
4618     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4619     memset( dib_bits, 0xaa, 64 * 4 );
4620
4621     info->bmiHeader.biHeight = -16;
4622     ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4623     ok( ret == 12, "got %d\n", ret );
4624     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4625     ok( !memcmp( dib_bits + 24, data,  40 * 4 ), "bits differ\n");
4626     memset( dib_bits, 0xaa, 64 * 4 );
4627
4628     info->bmiHeader.biHeight = -5;
4629     ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4630     ok( ret == 2, "got %d\n", ret );
4631     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4632     ok( !memcmp( dib_bits + 16, data,  16 * 4 ), "bits differ\n");
4633     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4634     memset( dib_bits, 0xaa, 64 * 4 );
4635
4636     /* b-u -> t-d */
4637     /* like the b-u -> b-u case */
4638
4639     info->bmiHeader.biHeight = 8;
4640     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4641     ok( ret == 8, "got %d\n", ret );
4642     ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4643     memset( dib_bits, 0xaa, 64 * 4 );
4644
4645     ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4646     ok( ret == 5, "got %d\n", ret );
4647     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4648     ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
4649     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4650     memset( dib_bits, 0xaa, 64 * 4 );
4651
4652     info->bmiHeader.biHeight = 16;
4653     ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4654     ok( ret == 12, "got %d\n", ret );
4655     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4656     ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
4657     memset( dib_bits, 0xaa, 64 * 4 );
4658
4659     info->bmiHeader.biHeight = 5;
4660     ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4661     ok( ret == 2, "got %d\n", ret );
4662     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4663     ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
4664     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4665     memset( dib_bits, 0xaa, 64 * 4 );
4666
4667     /* handling of partial color table */
4668
4669     info->bmiHeader.biHeight   = -8;
4670     info->bmiHeader.biBitCount = 8;
4671     info->bmiHeader.biClrUsed  = 137;
4672     for (i = 0; i < 256; i++)
4673     {
4674         info->bmiColors[i].rgbRed      = 255 - i;
4675         info->bmiColors[i].rgbGreen    = i * 2;
4676         info->bmiColors[i].rgbBlue     = i;
4677         info->bmiColors[i].rgbReserved = 0;
4678     }
4679     for (i = 0; i < 64; i++) ((BYTE *)data)[i] = i * 4 + 1;
4680     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4681     ok( ret == 8, "got %d\n", ret );
4682     for (i = 0; i < 64; i++)
4683     {
4684         int idx = i * 4 + 1;
4685         DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : (info->bmiColors[idx].rgbRed << 16 |
4686                                                                info->bmiColors[idx].rgbGreen << 8 |
4687                                                                info->bmiColors[idx].rgbBlue);
4688         ok( dib_bits[i] == expect, "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
4689     }
4690     memset( dib_bits, 0xaa, 64 * 4 );
4691
4692     /* handling of DIB_PAL_COLORS */
4693
4694     pal->palVersion = 0x300;
4695     pal->palNumEntries = 137;
4696     info->bmiHeader.biClrUsed = 221;
4697     for (i = 0; i < 256; i++)
4698     {
4699         palent[i].peRed   = i * 2;
4700         palent[i].peGreen = 255 - i;
4701         palent[i].peBlue  = i;
4702     }
4703     palette = CreatePalette( pal );
4704     ok( palette != 0, "palette creation failed\n" );
4705     SelectPalette( hdc, palette, FALSE );
4706     for (i = 0; i < 256; i++) ((WORD *)info->bmiColors)[i] = 255 - i;
4707     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_PAL_COLORS );
4708     ok( ret == 8, "got %d\n", ret );
4709     for (i = 0; i < 64; i++)
4710     {
4711         int idx = i * 4 + 1;
4712         int ent = (255 - idx) % pal->palNumEntries;
4713         DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 :
4714                         (palent[ent].peRed << 16 | palent[ent].peGreen << 8 | palent[ent].peBlue);
4715         ok( dib_bits[i] == expect || broken(dib_bits[i] == 0),  /* various Windows versions get some values wrong */
4716             "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
4717     }
4718     memset( dib_bits, 0xaa, 64 * 4 );
4719
4720     ReleaseDC( NULL, hdc );
4721     DeleteObject( dib );
4722     DeleteObject( palette );
4723     HeapFree( GetProcessHeap(), 0, info );
4724 }
4725
4726 static void test_SetDIBits_RLE4(void)
4727 {
4728     BITMAPINFO *info;
4729     DWORD *dib_bits;
4730     HDC hdc = GetDC( NULL );
4731     BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00,     /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
4732                            0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
4733                            0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00,     /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
4734                            0x00, 0x02, 0x01, 0x02, 0x05, 0x87,     /* dx=1, dy=2, 8, 7, 8, 7, 8 */
4735                            0x00, 0x01 };                           /* <eod> */
4736     HBITMAP dib;
4737     int i, ret;
4738     DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
4739                             0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
4740                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4741                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4742                             0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
4743                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4744                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4745                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4746
4747     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4748
4749     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4750     info->bmiHeader.biWidth       = 8;
4751     info->bmiHeader.biHeight      = 8;
4752     info->bmiHeader.biPlanes      = 1;
4753     info->bmiHeader.biBitCount    = 32;
4754     info->bmiHeader.biCompression = BI_RGB;
4755
4756     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4757     memset( dib_bits, 0xaa, 64 * 4 );
4758
4759     info->bmiHeader.biBitCount    = 4;
4760     info->bmiHeader.biCompression = BI_RLE4;
4761     info->bmiHeader.biSizeImage   = sizeof(rle4_data);
4762
4763     for (i = 0; i < 16; i++)
4764     {
4765         info->bmiColors[i].rgbRed      = i;
4766         info->bmiColors[i].rgbGreen    = i;
4767         info->bmiColors[i].rgbBlue     = i;
4768         info->bmiColors[i].rgbReserved = 0;
4769     }
4770
4771     ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
4772     ok( ret == 8, "got %d\n", ret );
4773     ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
4774     memset( dib_bits, 0xaa, 64 * 4 );
4775
4776     DeleteObject( dib );
4777     ReleaseDC( NULL, hdc );
4778     HeapFree( GetProcessHeap(), 0, info );
4779 }
4780
4781 static void test_SetDIBits_RLE8(void)
4782 {
4783     BITMAPINFO *info;
4784     DWORD *dib_bits;
4785     HDC hdc = GetDC( NULL );
4786     BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00,     /* 2, 2, 2, f0, f0, f0, f0, <eol> */
4787                            0x00, 0x03, 0x04, 0x05, 0x06, 0x00,     /* 4, 5, 6, <pad> */
4788                            0x00, 0x02, 0x01, 0x02, 0x05, 0x80,     /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4789                            0x00, 0x01 };                           /* <eod> */
4790     HBITMAP dib;
4791     int i, ret;
4792     DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4793                             0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4794                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4795                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4796                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
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     DWORD top_down[64]  = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4801                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4802                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4803                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4804                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4805                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4806                             0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4807                             0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4808
4809     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4810
4811     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4812     info->bmiHeader.biWidth       = 8;
4813     info->bmiHeader.biHeight      = 8;
4814     info->bmiHeader.biPlanes      = 1;
4815     info->bmiHeader.biBitCount    = 32;
4816     info->bmiHeader.biCompression = BI_RGB;
4817
4818     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4819     memset( dib_bits, 0xaa, 64 * 4 );
4820
4821     info->bmiHeader.biBitCount    = 8;
4822     info->bmiHeader.biCompression = BI_RLE8;
4823     info->bmiHeader.biSizeImage   = sizeof(rle8_data);
4824
4825     for (i = 0; i < 256; i++)
4826     {
4827         info->bmiColors[i].rgbRed      = i;
4828         info->bmiColors[i].rgbGreen    = i;
4829         info->bmiColors[i].rgbBlue     = i;
4830         info->bmiColors[i].rgbReserved = 0;
4831     }
4832
4833     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4834     ok( ret == 8, "got %d\n", ret );
4835     ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4836     memset( dib_bits, 0xaa, 64 * 4 );
4837
4838     /* startscan and lines are ignored, unless lines == 0 */
4839     ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4840     ok( ret == 8, "got %d\n", ret );
4841     ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4842     memset( dib_bits, 0xaa, 64 * 4 );
4843
4844     ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4845     ok( ret == 8, "got %d\n", ret );
4846     ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4847     memset( dib_bits, 0xaa, 64 * 4 );
4848
4849     ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4850     ok( ret == 0, "got %d\n", ret );
4851     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4852     memset( dib_bits, 0xaa, 64 * 4 );
4853
4854     /* reduce width to 4, left-hand side of dst is touched. */
4855     info->bmiHeader.biWidth = 4;
4856     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4857     ok( ret == 8, "got %d\n", ret );
4858     for (i = 0; i < 64; i++)
4859     {
4860         DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4861         ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4862     }
4863     memset( dib_bits, 0xaa, 64 * 4 );
4864
4865     /* Show that the top lines are aligned by adjusting the height of the src */
4866
4867     /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4868     info->bmiHeader.biWidth  = 8;
4869     info->bmiHeader.biHeight = 4;
4870     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4871     ok( ret == 4, "got %d\n", ret );
4872     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4873     ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4874     memset( dib_bits, 0xaa, 64 * 4 );
4875
4876     /* increase the height to 9 -> everything moves down one row. */
4877     info->bmiHeader.biHeight = 9;
4878     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4879     ok( ret == 9, "got %d\n", ret );
4880     ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4881     for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4882     memset( dib_bits, 0xaa, 64 * 4 );
4883
4884     /* top-down compressed dibs are invalid */
4885     info->bmiHeader.biHeight = -8;
4886     SetLastError( 0xdeadbeef );
4887     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4888     ok( ret == 0, "got %d\n", ret );
4889     ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4890     DeleteObject( dib );
4891
4892     /* top-down dst */
4893
4894     info->bmiHeader.biHeight      = -8;
4895     info->bmiHeader.biBitCount    = 32;
4896     info->bmiHeader.biCompression = BI_RGB;
4897     info->bmiHeader.biSizeImage   = 0;
4898
4899     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4900     memset( dib_bits, 0xaa, 16 * 16 * 4 );
4901
4902     info->bmiHeader.biHeight      = 8;
4903     info->bmiHeader.biBitCount    = 8;
4904     info->bmiHeader.biCompression = BI_RLE8;
4905     info->bmiHeader.biSizeImage   = sizeof(rle8_data);
4906
4907     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4908     ok( ret == 8, "got %d\n", ret );
4909     ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4910     memset( dib_bits, 0xaa, 64 * 4 );
4911
4912     info->bmiHeader.biHeight = 4;
4913     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4914     ok( ret == 4, "got %d\n", ret );
4915     ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4916     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4917     memset( dib_bits, 0xaa, 64 * 4 );
4918
4919     info->bmiHeader.biHeight = 9;
4920     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4921     ok( ret == 9, "got %d\n", ret );
4922     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4923     ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4924     memset( dib_bits, 0xaa, 64 * 4 );
4925
4926     DeleteObject( dib );
4927     ReleaseDC( NULL, hdc );
4928     HeapFree( GetProcessHeap(), 0, info );
4929 }
4930
4931 static void test_SetDIBitsToDevice(void)
4932 {
4933     char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
4934     LOGPALETTE *pal = (LOGPALETTE *)palbuf;
4935     PALETTEENTRY *palent = pal->palPalEntry;
4936     HPALETTE palette;
4937     BITMAPINFO *info;
4938     DWORD *dib_bits;
4939     HDC hdc = CreateCompatibleDC( 0 );
4940     DWORD data[128], inverted_data[128];
4941     HBITMAP dib;
4942     int i, ret;
4943
4944     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4945
4946     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4947     info->bmiHeader.biWidth       = 8;
4948     info->bmiHeader.biHeight      = 8;
4949     info->bmiHeader.biPlanes      = 1;
4950     info->bmiHeader.biBitCount    = 32;
4951     info->bmiHeader.biCompression = BI_RGB;
4952
4953     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4954     memset( dib_bits, 0xaa, 64 * 4 );
4955     SelectObject( hdc, dib );
4956
4957     for (i = 0; i < 128; i++)
4958     {
4959         data[i] = i;
4960         inverted_data[120 - (i & ~7) + (i & 7)] = i;
4961     }
4962
4963     /* b-u -> b-u */
4964
4965     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4966     ok( ret == 8, "got %d\n", ret );
4967     for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4968     memset( dib_bits, 0xaa, 64 * 4 );
4969
4970     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4971     ok( ret == 5, "got %d\n", ret );
4972     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4973     for (i = 8; i < 48; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4974     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4975     memset( dib_bits, 0xaa, 64 * 4 );
4976
4977     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 3, 1, 5, data, info, DIB_RGB_COLORS );
4978     ok( ret == 5, "got %d\n", ret );
4979     for (i = 0; i < 24; i++) ok( dib_bits[i] == data[i + 16], "%d: got %08x\n", i, dib_bits[i] );
4980     for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4981     memset( dib_bits, 0xaa, 64 * 4 );
4982
4983     info->bmiHeader.biHeight = 16;
4984     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4985     ok( ret == 7, "got %d\n", ret );
4986     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4987     for (i = 8; i < 64; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4988     memset( dib_bits, 0xaa, 64 * 4 );
4989
4990     ret = SetDIBitsToDevice( hdc, 0, 2, 8, 8, 0, 6, 1, 12, data, info, DIB_RGB_COLORS );
4991     ok( ret == 12, "got %d\n", ret );
4992     for (i = 0; i < 40; i++) ok( dib_bits[i] == data[i + 56], "%d: got %08x\n", i, dib_bits[i] );
4993     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4994     memset( dib_bits, 0xaa, 64 * 4 );
4995
4996     ret = SetDIBitsToDevice( hdc, 0, -4, 8, 8, 0, 3, 1, 12, data, info, DIB_RGB_COLORS );
4997     ok( ret == 10, "got %d\n", ret );
4998     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4999     for (i = 32; i < 64; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
5000     memset( dib_bits, 0xaa, 64 * 4 );
5001
5002     ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, -3, 1, 12, data, info, DIB_RGB_COLORS );
5003     ok( ret == 4, "got %d\n", ret );
5004     for (i = 0; i < 32; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
5005     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5006     memset( dib_bits, 0xaa, 64 * 4 );
5007
5008     ret = SetDIBitsToDevice( hdc, 0, 2, 8, 5, 0, -2, 1, 12, data, info, DIB_RGB_COLORS );
5009     ok( ret == 2, "got %d\n", ret );
5010     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5011     for (i = 32; i < 48; i++) ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
5012     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5013     memset( dib_bits, 0xaa, 64 * 4 );
5014
5015     info->bmiHeader.biHeight = 5;
5016     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 2, 2, data, info, DIB_RGB_COLORS );
5017     ok( ret == 2, "got %d\n", ret );
5018     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5019     for (i = 16; i < 32; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
5020     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5021     memset( dib_bits, 0xaa, 64 * 4 );
5022
5023     ret = SetDIBitsToDevice( hdc, 3, 3, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
5024     ok( ret == 3, "got %d\n", ret );
5025     for (i = 0; i < 64; i++)
5026         if (i == 27 || i == 28 || i == 35 || i == 36)
5027             ok( dib_bits[i] == data[i - 18], "%d: got %08x\n", i, dib_bits[i] );
5028         else
5029             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5030     memset( dib_bits, 0xaa, 64 * 4 );
5031
5032     ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5033     ok( ret == 5, "got %d\n", ret );
5034     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5035     memset( dib_bits, 0xaa, 64 * 4 );
5036
5037     ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
5038     ok( ret == 0, "got %d\n", ret );
5039     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5040     memset( dib_bits, 0xaa, 64 * 4 );
5041
5042     SetMapMode( hdc, MM_ANISOTROPIC );
5043     SetWindowExtEx( hdc, 3, 3, NULL );
5044     ret = SetDIBitsToDevice( hdc, 2, 2, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
5045     ok( ret == 3, "got %d\n", ret );
5046     for (i = 0; i < 64; i++)
5047         if (i == 41 || i == 42 || i == 49 || i == 50)
5048             ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
5049         else
5050             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5051     memset( dib_bits, 0xaa, 64 * 4 );
5052
5053     SetWindowExtEx( hdc, -1, -1, NULL );
5054     ret = SetDIBitsToDevice( hdc, 2, 2, 4, 4, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
5055     ok( ret == 4, "got %d\n", ret );
5056     for (i = 0; i < 64; i++)
5057         if (i == 48 || i == 49 || i == 56 || i == 57)
5058             ok( dib_bits[i] == data[i - 37], "%d: got %08x\n", i, dib_bits[i] );
5059         else
5060             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5061     memset( dib_bits, 0xaa, 64 * 4 );
5062     SetMapMode( hdc, MM_TEXT );
5063
5064     if (pSetLayout)
5065     {
5066         pSetLayout( hdc, LAYOUT_RTL );
5067         ret = SetDIBitsToDevice( hdc, 1, 2, 3, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
5068         ok( ret == 3, "got %d\n", ret );
5069         for (i = 0; i < 64; i++)
5070             if (i == 36 || i == 37 || i == 38 || i == 44 || i == 45 || i == 46)
5071                 ok( dib_bits[i] == data[i - 27], "%d: got %08x\n", i, dib_bits[i] );
5072             else
5073                 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5074         memset( dib_bits, 0xaa, 64 * 4 );
5075         pSetLayout( hdc, LAYOUT_LTR );
5076     }
5077
5078     /* t-d -> b-u */
5079     info->bmiHeader.biHeight = -8;
5080     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5081     ok( ret == 8, "got %d\n", ret );
5082     for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
5083     memset( dib_bits, 0xaa, 64 * 4 );
5084
5085     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
5086     ok( ret == 5, "got %d\n", ret );
5087     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5088     for (i = 8; i < 48; i++) ok( dib_bits[i] == inverted_data[i + 80], "%d: got %08x\n", i, dib_bits[i] );
5089     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5090     memset( dib_bits, 0xaa, 64 * 4 );
5091
5092     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 4, 1, 5, data, info, DIB_RGB_COLORS );
5093     ok( ret == 5, "got %d\n", ret );
5094     for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
5095     for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5096     memset( dib_bits, 0xaa, 64 * 4 );
5097
5098     info->bmiHeader.biHeight = -16;
5099     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
5100     ok( ret == 12, "got %d\n", ret );
5101     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5102     for (i = 8; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 24], "%d: got %08x\n", i, dib_bits[i] );
5103     memset( dib_bits, 0xaa, 64 * 4 );
5104
5105     ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, 7, 1, 12, data, info, DIB_RGB_COLORS );
5106     ok( ret == 12, "got %d\n", ret );
5107     for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
5108     for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5109     memset( dib_bits, 0xaa, 64 * 4 );
5110
5111     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 4, 12, data, info, DIB_RGB_COLORS );
5112     ok( ret == 12, "got %d\n", ret );
5113     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5114     for (i = 32; i < 64; i++) ok( dib_bits[i] == inverted_data[i], "%d: got %08x\n", i, dib_bits[i] );
5115     memset( dib_bits, 0xaa, 64 * 4 );
5116
5117     ret = SetDIBitsToDevice( hdc, 0, -3, 8, 8, 0, 2, 4, 12, data, info, DIB_RGB_COLORS );
5118     ok( ret == 12, "got %d\n", ret );
5119     for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5120     for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5121     memset( dib_bits, 0xaa, 64 * 4 );
5122
5123     ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, -2, 4, 12, data, info, DIB_RGB_COLORS );
5124     ok( ret == 12, "got %d\n", ret );
5125     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5126     for (i = 24; i < 40; i++) ok( dib_bits[i] == inverted_data[i + 8], "%d: got %08x\n", i, dib_bits[i] );
5127     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5128     memset( dib_bits, 0xaa, 64 * 4 );
5129
5130     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 5, 12, data, info, DIB_RGB_COLORS );
5131     ok( ret == 12, "got %d\n", ret );
5132     for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5133     for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5134     memset( dib_bits, 0xaa, 64 * 4 );
5135
5136     ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
5137     ok( ret == 12, "got %d\n", ret );
5138     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5139     memset( dib_bits, 0xaa, 64 * 4 );
5140
5141     ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -2, -4, 0, 12, data, info, DIB_RGB_COLORS );
5142     ok( ret == 12, "got %d\n", ret );
5143     for (i = 0; i < 64; i++)
5144         if (i == 31 || i == 39 || i == 47 || i == 55 || i == 63)
5145             ok( dib_bits[i] == inverted_data[i + 1], "%d: got %08x\n", i, dib_bits[i] );
5146         else
5147             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5148     memset( dib_bits, 0xaa, 64 * 4 );
5149
5150     info->bmiHeader.biHeight = -5;
5151     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
5152     ok( ret == 2, "got %d\n", ret );
5153     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5154     for (i = 8; i < 24; i++) ok( dib_bits[i] == inverted_data[i + 104], "%d: got %08x\n", i, dib_bits[i] );
5155     for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5156     memset( dib_bits, 0xaa, 64 * 4 );
5157
5158     ret = SetDIBitsToDevice( hdc, 5, 4, 2, 2, 6, 3, 1, 5, data, info, DIB_RGB_COLORS );
5159     ok( ret == 5, "got %d\n", ret );
5160     for (i = 0; i < 64; i++)
5161         if (i == 21 || i == 22 || i == 29 || i == 30)
5162             ok( dib_bits[i] == inverted_data[i + 89], "%d: got %08x\n", i, dib_bits[i] );
5163         else
5164             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5165     memset( dib_bits, 0xaa, 64 * 4 );
5166
5167     ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5168     ok( ret == 5, "got %d\n", ret );
5169     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5170     memset( dib_bits, 0xaa, 64 * 4 );
5171
5172     info->bmiHeader.biHeight = -8;
5173
5174     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5175     DeleteObject( SelectObject( hdc, dib ));
5176     memset( dib_bits, 0xaa, 16 * 16 * 4 );
5177
5178     /* t-d -> t-d */
5179
5180     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5181     ok( ret == 8, "got %d\n", ret );
5182     for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
5183     memset( dib_bits, 0xaa, 64 * 4 );
5184
5185     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
5186     ok( ret == 5, "got %d\n", ret );
5187     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5188     for (i = 16; i < 56; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
5189     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5190     memset( dib_bits, 0xaa, 64 * 4 );
5191
5192     ret = SetDIBitsToDevice( hdc, 0, 3, 8, 3, 0, 2, 1, 5, data, info, DIB_RGB_COLORS );
5193     ok( ret == 5, "got %d\n", ret );
5194     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5195     for (i = 24; i < 48; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
5196     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5197     memset( dib_bits, 0xaa, 64 * 4 );
5198
5199     info->bmiHeader.biHeight = -16;
5200     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
5201     ok( ret == 12, "got %d\n", ret );
5202     for (i = 0; i < 56; i++) ok( dib_bits[i] == data[i + 40], "%d: got %08x\n", i, dib_bits[i] );
5203     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5204     memset( dib_bits, 0xaa, 64 * 4 );
5205
5206     ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -1, -8, 0, 12, data, info, DIB_RGB_COLORS );
5207     ok( ret == 12, "got %d\n", ret );
5208     for (i = 0; i < 64; i++)
5209         if (i == 6 || i == 7)
5210             ok( dib_bits[i] == data[i + 82], "%d: got %08x\n", i, dib_bits[i] );
5211         else
5212             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5213     memset( dib_bits, 0xaa, 64 * 4 );
5214
5215     info->bmiHeader.biHeight = -5;
5216     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
5217     ok( ret == 2, "got %d\n", ret );
5218     for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5219     for (i = 40; i < 56; i++) ok( dib_bits[i] == data[i - 40], "%d: got %08x\n", i, dib_bits[i] );
5220     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5221     memset( dib_bits, 0xaa, 64 * 4 );
5222
5223     ret = SetDIBitsToDevice( hdc, 7, 2, 8, 8, 1, 0, 0, 5, data, info, DIB_RGB_COLORS );
5224     ok( ret == 5, "got %d\n", ret );
5225     for (i = 0; i < 64; i++)
5226         if (i == 47 || i == 55 || i == 63)
5227             ok( dib_bits[i] == data[i - 46], "%d: got %08x\n", i, dib_bits[i] );
5228         else
5229             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5230     memset( dib_bits, 0xaa, 64 * 4 );
5231
5232     ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5233     ok( ret == 5, "got %d\n", ret );
5234     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5235     memset( dib_bits, 0xaa, 64 * 4 );
5236
5237     /* b-u -> t-d */
5238
5239     info->bmiHeader.biHeight = 8;
5240     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5241     ok( ret == 8, "got %d\n", ret );
5242     for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
5243     memset( dib_bits, 0xaa, 64 * 4 );
5244
5245     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
5246     ok( ret == 5, "got %d\n", ret );
5247     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5248     for (i = 16; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
5249     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5250     memset( dib_bits, 0xaa, 64 * 4 );
5251
5252     info->bmiHeader.biHeight = 16;
5253     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
5254     ok( ret == 7, "got %d\n", ret );
5255     for (i = 0; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
5256     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5257     memset( dib_bits, 0xaa, 64 * 4 );
5258
5259     ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, 0, -4, 1, 12, data, info, DIB_RGB_COLORS );
5260     ok( ret == 3, "got %d\n", ret );
5261     for (i = 0; i < 64; i++)
5262         if ((i >= 36 && i <= 39) || (i >= 44 && i <= 47) || (i >= 52 && i <= 55))
5263             ok( dib_bits[i] == inverted_data[i + 68], "%d: got %08x\n", i, dib_bits[i] );
5264         else
5265             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5266     memset( dib_bits, 0xaa, 64 * 4 );
5267
5268     ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, -30, -30, 1, 12, data, info, DIB_RGB_COLORS );
5269     ok( ret == 0, "got %d\n", ret );
5270     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5271     memset( dib_bits, 0xaa, 64 * 4 );
5272
5273     ret = SetDIBitsToDevice( hdc, 5, -5, 8, 16, -2, -4, 4, 12, data, info, DIB_RGB_COLORS );
5274     ok( ret == 8, "got %d\n", ret );
5275     for (i = 0; i < 64; i++)
5276         if (i == 7 || i == 15 || i == 23)
5277             ok( dib_bits[i] == inverted_data[i + 97], "%d: got %08x\n", i, dib_bits[i] );
5278         else
5279             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5280     memset( dib_bits, 0xaa, 64 * 4 );
5281
5282     info->bmiHeader.biHeight = 5;
5283     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
5284     ok( ret == 2, "got %d\n", ret );
5285     for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5286     for (i = 40; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
5287     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5288     memset( dib_bits, 0xaa, 64 * 4 );
5289
5290     ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
5291     ok( ret == 5, "got %d\n", ret );
5292     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5293     memset( dib_bits, 0xaa, 64 * 4 );
5294
5295     /* handling of partial color table */
5296
5297     info->bmiHeader.biHeight   = -8;
5298     info->bmiHeader.biBitCount = 8;
5299     info->bmiHeader.biClrUsed  = 137;
5300     for (i = 0; i < 256; i++)
5301     {
5302         info->bmiColors[i].rgbRed      = 255 - i;
5303         info->bmiColors[i].rgbGreen    = i * 2;
5304         info->bmiColors[i].rgbBlue     = i;
5305         info->bmiColors[i].rgbReserved = 0;
5306     }
5307     for (i = 0; i < 64; i++) ((BYTE *)data)[i] = i * 4 + 1;
5308     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
5309     ok( ret == 8, "got %d\n", ret );
5310     for (i = 0; i < 64; i++)
5311     {
5312         int idx = i * 4 + 1;
5313         DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : (info->bmiColors[idx].rgbRed << 16 |
5314                                                                info->bmiColors[idx].rgbGreen << 8 |
5315                                                                info->bmiColors[idx].rgbBlue);
5316         ok( dib_bits[i] == expect, "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
5317     }
5318     memset( dib_bits, 0xaa, 64 * 4 );
5319
5320     /* handling of DIB_PAL_COLORS */
5321
5322     pal->palVersion = 0x300;
5323     pal->palNumEntries = 137;
5324     info->bmiHeader.biClrUsed = 221;
5325     for (i = 0; i < 256; i++)
5326     {
5327         palent[i].peRed   = i * 2;
5328         palent[i].peGreen = 255 - i;
5329         palent[i].peBlue  = i;
5330     }
5331     palette = CreatePalette( pal );
5332     ok( palette != 0, "palette creation failed\n" );
5333     SelectPalette( hdc, palette, FALSE );
5334     for (i = 0; i < 256; i++) ((WORD *)info->bmiColors)[i] = 255 - i;
5335     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_PAL_COLORS );
5336     ok( ret == 8, "got %d\n", ret );
5337     for (i = 0; i < 64; i++)
5338     {
5339         int idx = i * 4 + 1;
5340         int ent = (255 - idx) % pal->palNumEntries;
5341         DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 :
5342                         (palent[ent].peRed << 16 | palent[ent].peGreen << 8 | palent[ent].peBlue);
5343         ok( dib_bits[i] == expect || broken(dib_bits[i] == 0),
5344             "%d: got %08x instead of %08x\n", i, dib_bits[i], expect );
5345     }
5346     memset( dib_bits, 0xaa, 64 * 4 );
5347
5348     DeleteDC( hdc );
5349     DeleteObject( dib );
5350     DeleteObject( palette );
5351     HeapFree( GetProcessHeap(), 0, info );
5352 }
5353
5354 static void test_SetDIBitsToDevice_RLE8(void)
5355 {
5356     BITMAPINFO *info;
5357     DWORD *dib_bits;
5358     HDC hdc = CreateCompatibleDC( 0 );
5359     BYTE rle8_data[20] = { 0x04, 0x02, 0x03, 0xf0, 0x00, 0x00,     /* 2, 2, 2, 2, f0, f0, f0, <eol> */
5360                            0x00, 0x03, 0x04, 0x05, 0x06, 0x00,     /* 4, 5, 6, <pad> */
5361                            0x00, 0x02, 0x01, 0x02, 0x05, 0x80,     /* dx=1, dy=2, 80, 80, 80, 80, (80) */
5362                            0x00, 0x01 };                           /* <eod> */
5363     HBITMAP dib;
5364     int i, ret;
5365     DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
5366                             0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5367                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5368                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
5369                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
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     DWORD top_down[64]  = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5374                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5375                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5376                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5377                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
5378                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5379                             0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
5380                             0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
5381
5382     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
5383
5384     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
5385     info->bmiHeader.biWidth       = 8;
5386     info->bmiHeader.biHeight      = 8;
5387     info->bmiHeader.biPlanes      = 1;
5388     info->bmiHeader.biBitCount    = 32;
5389     info->bmiHeader.biCompression = BI_RGB;
5390
5391     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5392     memset( dib_bits, 0xaa, 64 * 4 );
5393     SelectObject( hdc, dib );
5394
5395     info->bmiHeader.biBitCount    = 8;
5396     info->bmiHeader.biCompression = BI_RLE8;
5397     info->bmiHeader.biSizeImage   = sizeof(rle8_data);
5398
5399     for (i = 0; i < 256; i++)
5400     {
5401         info->bmiColors[i].rgbRed      = i;
5402         info->bmiColors[i].rgbGreen    = i;
5403         info->bmiColors[i].rgbBlue     = i;
5404         info->bmiColors[i].rgbReserved = 0;
5405     }
5406
5407     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5408     ok( ret == 8, "got %d\n", ret );
5409     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5410     memset( dib_bits, 0xaa, 64 * 4 );
5411
5412     /* startscan and lines are ignored, unless lines == 0 */
5413     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 8, rle8_data, info, DIB_RGB_COLORS );
5414     ok( ret == 8, "got %d\n", ret );
5415     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5416     memset( dib_bits, 0xaa, 64 * 4 );
5417
5418     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 1, rle8_data, info, DIB_RGB_COLORS );
5419     ok( ret == 8, "got %d\n", ret );
5420     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5421     memset( dib_bits, 0xaa, 64 * 4 );
5422
5423     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 0, rle8_data, info, DIB_RGB_COLORS );
5424     ok( ret == 0, "got %d\n", ret );
5425     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5426     memset( dib_bits, 0xaa, 64 * 4 );
5427
5428     info->bmiHeader.biWidth = 2;
5429     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5430     ok( ret == 8, "got %d\n", ret );
5431     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5432     memset( dib_bits, 0xaa, 64 * 4 );
5433
5434     info->bmiHeader.biWidth  = 8;
5435     info->bmiHeader.biHeight = 2;
5436     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5437     ok( ret == 2, "got %d\n", ret );
5438     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5439     memset( dib_bits, 0xaa, 64 * 4 );
5440
5441     info->bmiHeader.biHeight = 9;
5442     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5443     ok( ret == 9, "got %d\n", ret );
5444     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5445     memset( dib_bits, 0xaa, 64 * 4 );
5446
5447     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5448     ok( ret == 9, "got %d\n", ret );
5449     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5450     memset( dib_bits, 0xaa, 64 * 4 );
5451
5452     info->bmiHeader.biHeight = 8;
5453     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 9, rle8_data, info, DIB_RGB_COLORS );
5454     ok( ret == 8, "got %d\n", ret );
5455     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
5456     memset( dib_bits, 0xaa, 64 * 4 );
5457
5458     ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5459     ok( ret == 8, "got %d\n", ret );
5460     for (i = 0; i < 40; i++) ok( dib_bits[i] == bottom_up[i + 24], "%d: got %08x\n", i, dib_bits[i] );
5461     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5462     memset( dib_bits, 0xaa, 64 * 4 );
5463
5464     ret = SetDIBitsToDevice( hdc, 0, 3, 4, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5465     ok( ret == 8, "got %d\n", ret );
5466     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5467     for (i = 8; i < 40; i++)
5468         if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5469         else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5470     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5471     memset( dib_bits, 0xaa, 64 * 4 );
5472
5473     ret = SetDIBitsToDevice( hdc, 3, 3, 8, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5474     ok( ret == 8, "got %d\n", ret );
5475     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5476     for (i = 8; i < 40; i++)
5477         if ((i & 7) < 3) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5478         else ok( dib_bits[i] == bottom_up[i - 11], "%d: got %08x\n", i, dib_bits[i] );
5479     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5480     memset( dib_bits, 0xaa, 64 * 4 );
5481
5482     ret = SetDIBitsToDevice( hdc, 2, 3, 8, 4, 2, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5483     ok( ret == 8, "got %d\n", ret );
5484     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5485     for (i = 8; i < 40; i++)
5486         if ((i & 7) < 2) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5487         else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
5488     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5489     memset( dib_bits, 0xaa, 64 * 4 );
5490
5491     info->bmiHeader.biWidth = 37;
5492     info->bmiHeader.biHeight = 37;
5493     ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
5494     ok( ret == 37, "got %d\n", ret );
5495     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5496     for (i = 24; i < 64; i++)
5497         if (i == 52) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
5498         else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5499         else ok( dib_bits[i] == bottom_up[i - 20], "%d: got %08x\n", i, dib_bits[i] );
5500     memset( dib_bits, 0xaa, 64 * 4 );
5501
5502     /* top-down compressed dibs are invalid */
5503     info->bmiHeader.biWidth = 8;
5504     info->bmiHeader.biHeight = -8;
5505     SetLastError( 0xdeadbeef );
5506     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5507     ok( ret == 0, "got %d\n", ret );
5508     ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
5509
5510     /* top-down dst */
5511
5512     info->bmiHeader.biHeight      = -8;
5513     info->bmiHeader.biBitCount    = 32;
5514     info->bmiHeader.biCompression = BI_RGB;
5515     info->bmiHeader.biSizeImage   = 0;
5516
5517     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
5518     memset( dib_bits, 0xaa, 16 * 16 * 4 );
5519     DeleteObject( SelectObject( hdc, dib ));
5520
5521     info->bmiHeader.biHeight      = 8;
5522     info->bmiHeader.biBitCount    = 8;
5523     info->bmiHeader.biCompression = BI_RLE8;
5524     info->bmiHeader.biSizeImage   = sizeof(rle8_data);
5525
5526     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5527     ok( ret == 8, "got %d\n", ret );
5528     for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5529     memset( dib_bits, 0xaa, 64 * 4 );
5530
5531     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5532     ok( ret == 8, "got %d\n", ret );
5533     for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5534     memset( dib_bits, 0xaa, 64 * 4 );
5535
5536     info->bmiHeader.biHeight = 4;
5537     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5538     ok( ret == 4, "got %d\n", ret );
5539     for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5540     memset( dib_bits, 0xaa, 64 * 4 );
5541
5542     info->bmiHeader.biHeight = 9;
5543     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5544     ok( ret == 9, "got %d\n", ret );
5545     for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5546     memset( dib_bits, 0xaa, 64 * 4 );
5547
5548     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
5549     ok( ret == 9, "got %d\n", ret );
5550     for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
5551     memset( dib_bits, 0xaa, 64 * 4 );
5552
5553     ret = SetDIBitsToDevice( hdc, 2, 3, 8, 6, 2, 2, 0, 8, rle8_data, info, DIB_RGB_COLORS );
5554     ok( ret == 9, "got %d\n", ret );
5555     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5556     for (i = 24; i < 64; i++) ok( dib_bits[i] == top_down[i - 24], "%d: got %08x\n", i, dib_bits[i] );
5557     memset( dib_bits, 0xaa, 64 * 4 );
5558
5559     info->bmiHeader.biWidth = 37;
5560     info->bmiHeader.biHeight = 37;
5561     ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
5562     ok( ret == 37, "got %d\n", ret );
5563     for (i = 0; i < 40; i++)
5564         if (i == 12) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
5565         else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5566         else ok( dib_bits[i] == top_down[i + 28], "%d: got %08x\n", i, dib_bits[i] );
5567     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
5568     memset( dib_bits, 0xaa, 64 * 4 );
5569
5570     DeleteDC( hdc );
5571     DeleteObject( dib );
5572     HeapFree( GetProcessHeap(), 0, info );
5573 }
5574
5575 START_TEST(bitmap)
5576 {
5577     HMODULE hdll;
5578
5579     hdll = GetModuleHandle("gdi32.dll");
5580     pGdiAlphaBlend   = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
5581     pGdiGradientFill = (void*)GetProcAddress(hdll, "GdiGradientFill");
5582     pSetLayout       = (void*)GetProcAddress(hdll, "SetLayout");
5583
5584     test_createdibitmap();
5585     test_dibsections();
5586     test_dib_formats();
5587     test_mono_dibsection();
5588     test_bitmap();
5589     test_mono_bitmap();
5590     test_bmBits();
5591     test_GetDIBits_selected_DIB(1);
5592     test_GetDIBits_selected_DIB(4);
5593     test_GetDIBits_selected_DIB(8);
5594     test_GetDIBits_selected_DDB(TRUE);
5595     test_GetDIBits_selected_DDB(FALSE);
5596     test_GetDIBits();
5597     test_GetDIBits_BI_BITFIELDS();
5598     test_select_object();
5599     test_CreateBitmap();
5600     test_BitBlt();
5601     test_StretchBlt();
5602     test_StretchDIBits();
5603     test_GdiAlphaBlend();
5604     test_GdiGradientFill();
5605     test_32bit_ddb();
5606     test_bitmapinfoheadersize();
5607     test_get16dibits();
5608     test_clipping();
5609     test_GetDIBits_top_down(16);
5610     test_GetDIBits_top_down(24);
5611     test_GetDIBits_top_down(32);
5612     test_GetSetDIBits_rtl();
5613     test_GetDIBits_scanlines();
5614     test_SetDIBits();
5615     test_SetDIBits_RLE4();
5616     test_SetDIBits_RLE8();
5617     test_SetDIBitsToDevice();
5618     test_SetDIBitsToDevice_RLE8();
5619 }