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