2409bd3f89823d6cc9ba54ba12eb554ac3f9d96d
[reactos.git] / modules / rostests / winetests / gdi32 / bitmap.c
1 /*
2 * Unit test suite for bitmaps
3 *
4 * Copyright 2004 Huw Davies
5 * Copyright 2006 Dmitry Timoshkov
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 #include <stdarg.h>
23 #include <assert.h>
24 #include <string.h>
25
26 #include "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
48 static inline int get_bitmap_stride( int width, int bpp )
49 {
50 return ((width * bpp + 15) >> 3) & ~1;
51 }
52
53 static inline int get_dib_stride( int width, int bpp )
54 {
55 return ((width * bpp + 31) >> 3) & ~3;
56 }
57
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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);