49460506f5f6484ac07241ba7bf5acecdb94b5ff
[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 "precomp.h"
23
24 #ifndef __REACTOS__ /* CORE-11331 */
25 #include "wine/ddk/d3dkmthk.h"
26 #endif
27
28 #ifndef __REACTOS__ /* CORE-11331 */
29 static NTSTATUS (WINAPI *pD3DKMTCreateDCFromMemory)( D3DKMT_CREATEDCFROMMEMORY *desc );
30 static NTSTATUS (WINAPI *pD3DKMTDestroyDCFromMemory)( const D3DKMT_DESTROYDCFROMMEMORY *desc );
31 #endif
32 static BOOL (WINAPI *pGdiAlphaBlend)(HDC,int,int,int,int,HDC,int,int,int,int,BLENDFUNCTION);
33 static BOOL (WINAPI *pGdiGradientFill)(HDC,TRIVERTEX*,ULONG,void*,ULONG,ULONG);
34 static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
35
36 static inline int get_bitmap_stride( int width, int bpp )
37 {
38 return ((width * bpp + 15) >> 3) & ~1;
39 }
40
41 static inline int get_dib_stride( int width, int bpp )
42 {
43 return ((width * bpp + 31) >> 3) & ~3;
44 }
45
46 static inline int get_dib_image_size( const BITMAPINFO *info )
47 {
48 return get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount )
49 * abs( info->bmiHeader.biHeight );
50 }
51
52 static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHEADER *bmih)
53 {
54 BITMAP bm;
55 BITMAP bma[2];
56 INT ret, width_bytes, i;
57 BYTE buf[512], buf_cmp[512];
58 INT test_size[] = {0 /*first value will be changed */, 0, -1, -1000, ~0, sizeof(buf)};
59
60 ret = GetObjectW(hbm, sizeof(bm), &bm);
61 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
62
63 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
64 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
65 ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
66 width_bytes = get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel);
67 ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
68 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
69 ok(bm.bmBitsPixel == expected_depth, "wrong bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, expected_depth);
70 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
71
72 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
73 assert(sizeof(buf) == sizeof(buf_cmp));
74
75 SetLastError(0xdeadbeef);
76 test_size[0] = bm.bmWidthBytes * bm.bmHeight;
77 /* NULL output buffer with different count values */
78 for (i = 0; i < sizeof(test_size) / sizeof(test_size[0]); i++)
79 {
80 ret = GetBitmapBits(hbm, test_size[i], NULL);
81 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
82 }
83
84 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
85 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
86
87 /* Correct output buffer with different count values */
88 for (i = 0; i < sizeof(test_size) / sizeof(test_size[0]); i++)
89 {
90 int expect = i == 1 ? 0 : bm.bmWidthBytes * bm.bmHeight;
91 memset(buf, 0xAA, sizeof(buf));
92 ret = GetBitmapBits(hbm, test_size[i], buf);
93 ok(ret == expect, "Test[%d]: %d != %d\n", i, ret, expect);
94 if (expect)
95 ok(!memcmp(buf, buf_cmp, sizeof(buf)),
96 "Test[%d]: buffers do not match, depth %d\n", i, bmih->biBitCount);
97 }
98
99 /* test various buffer sizes for GetObject */
100 ret = GetObjectW(hbm, sizeof(*bma) * 2, bma);
101 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
102
103 ret = GetObjectW(hbm, sizeof(bm) / 2, &bm);
104 ok(ret == 0, "%d != 0\n", ret);
105
106 ret = GetObjectW(hbm, 0, &bm);
107 ok(ret == 0, "%d != 0\n", ret);
108
109 ret = GetObjectW(hbm, 1, &bm);
110 ok(ret == 0, "%d != 0\n", ret);
111
112 ret = GetObjectW(hbm, 0, NULL);
113 ok(ret == sizeof(bm), "wrong size %d\n", ret);
114 }
115
116 static void test_createdibitmap(void)
117 {
118 HDC hdc, hdcmem;
119 BITMAPINFOHEADER bmih;
120 BITMAPINFO bm;
121 HBITMAP hbm, hbm_colour, hbm_old;
122 INT screen_depth;
123 DWORD pixel;
124
125 hdc = GetDC(0);
126 screen_depth = GetDeviceCaps(hdc, BITSPIXEL);
127 memset(&bmih, 0, sizeof(bmih));
128 bmih.biSize = sizeof(bmih);
129 bmih.biWidth = 10;
130 bmih.biHeight = 10;
131 bmih.biPlanes = 1;
132 bmih.biBitCount = 32;
133 bmih.biCompression = BI_RGB;
134
135 hbm = CreateDIBitmap(hdc, NULL, CBM_INIT, NULL, NULL, 0);
136 ok(hbm == NULL, "CreateDIBitmap should fail\n");
137 hbm = CreateDIBitmap(hdc, NULL, 0, NULL, NULL, 0);
138 ok(hbm == NULL, "CreateDIBitmap should fail\n");
139
140 /* First create an un-initialised bitmap. The depth of the bitmap
141 should match that of the hdc and not that supplied in bmih.
142 */
143
144 /* First try 32 bits */
145 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
146 ok(hbm != NULL, "CreateDIBitmap failed\n");
147 test_bitmap_info(hbm, screen_depth, &bmih);
148 DeleteObject(hbm);
149
150 /* Then 16 */
151 bmih.biBitCount = 16;
152 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
153 ok(hbm != NULL, "CreateDIBitmap failed\n");
154 test_bitmap_info(hbm, screen_depth, &bmih);
155 DeleteObject(hbm);
156
157 /* Then 1 */
158 bmih.biBitCount = 1;
159 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
160 ok(hbm != NULL, "CreateDIBitmap failed\n");
161 test_bitmap_info(hbm, screen_depth, &bmih);
162 DeleteObject(hbm);
163
164 /* Now with a monochrome dc we expect a monochrome bitmap */
165 hdcmem = CreateCompatibleDC(hdc);
166
167 /* First try 32 bits */
168 bmih.biBitCount = 32;
169 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
170 ok(hbm != NULL, "CreateDIBitmap failed\n");
171 test_bitmap_info(hbm, 1, &bmih);
172 DeleteObject(hbm);
173
174 /* Then 16 */
175 bmih.biBitCount = 16;
176 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
177 ok(hbm != NULL, "CreateDIBitmap failed\n");
178 test_bitmap_info(hbm, 1, &bmih);
179 DeleteObject(hbm);
180
181 /* Then 1 */
182 bmih.biBitCount = 1;
183 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
184 ok(hbm != NULL, "CreateDIBitmap failed\n");
185 test_bitmap_info(hbm, 1, &bmih);
186 DeleteObject(hbm);
187
188 /* Now select a polychrome bitmap into the dc and we expect
189 screen_depth bitmaps again */
190 hbm_colour = CreateCompatibleBitmap(hdc, bmih.biWidth, bmih.biHeight);
191 test_bitmap_info(hbm_colour, screen_depth, &bmih);
192 hbm_old = SelectObject(hdcmem, hbm_colour);
193
194 /* First try 32 bits */
195 bmih.biBitCount = 32;
196 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
197 ok(hbm != NULL, "CreateDIBitmap failed\n");
198 test_bitmap_info(hbm, screen_depth, &bmih);
199 DeleteObject(hbm);
200
201 /* Then 16 */
202 bmih.biBitCount = 16;
203 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
204 ok(hbm != NULL, "CreateDIBitmap failed\n");
205 test_bitmap_info(hbm, screen_depth, &bmih);
206 DeleteObject(hbm);
207
208 /* Then 1 */
209 bmih.biBitCount = 1;
210 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
211 ok(hbm != NULL, "CreateDIBitmap failed\n");
212 test_bitmap_info(hbm, screen_depth, &bmih);
213 DeleteObject(hbm);
214
215 SelectObject(hdcmem, hbm_old);
216 DeleteObject(hbm_colour);
217 DeleteDC(hdcmem);
218
219 bmih.biBitCount = 32;
220 hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0);
221 ok(hbm != NULL, "CreateDIBitmap failed\n");
222 test_bitmap_info(hbm, 1, &bmih);
223 DeleteObject(hbm);
224
225 /* Test how formats are converted */
226 pixel = 0xffffffff;
227 bmih.biBitCount = 1;
228 bmih.biWidth = 1;
229 bmih.biHeight = 1;
230
231 memset(&bm, 0, sizeof(bm));
232 bm.bmiHeader.biSize = sizeof(bm.bmiHeader);
233 bm.bmiHeader.biWidth = 1;
234 bm.bmiHeader.biHeight = 1;
235 bm.bmiHeader.biPlanes = 1;
236 bm.bmiHeader.biBitCount= 24;
237 bm.bmiHeader.biCompression= BI_RGB;
238 bm.bmiHeader.biSizeImage = 0;
239 hbm = CreateDIBitmap(hdc, &bmih, CBM_INIT, &pixel, &bm, DIB_RGB_COLORS);
240 ok(hbm != NULL, "CreateDIBitmap failed\n");
241
242 pixel = 0xdeadbeef;
243 bm.bmiHeader.biBitCount= 32;
244 GetDIBits(hdc, hbm, 0, 1, &pixel, &bm, DIB_RGB_COLORS);
245 ok(pixel == 0x00ffffff, "Reading a 32 bit pixel from a DDB returned %08x\n", pixel);
246 DeleteObject(hbm);
247
248 ReleaseDC(0, hdc);
249 }
250
251 static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
252 {
253 BITMAP bm;
254 BITMAP bma[2];
255 DIBSECTION ds;
256 DIBSECTION dsa[2];
257 INT ret, bm_width_bytes, dib_width_bytes;
258 BYTE *buf;
259
260 ret = GetObjectW(hbm, sizeof(bm), &bm);
261 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
262
263 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
264 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
265 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
266 dib_width_bytes = get_dib_stride(bm.bmWidth, bm.bmBitsPixel);
267 bm_width_bytes = get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel);
268 if (bm.bmWidthBytes != dib_width_bytes) /* Win2k bug */
269 ok(bm.bmWidthBytes == bm_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, bm_width_bytes);
270 else
271 ok(bm.bmWidthBytes == dib_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, dib_width_bytes);
272 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
273 ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount);
274 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
275
276 buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);
277
278 /* GetBitmapBits returns not 32-bit aligned data */
279 SetLastError(0xdeadbeef);
280 ret = GetBitmapBits(hbm, 0, NULL);
281 ok(ret == bm_width_bytes * bm.bmHeight,
282 "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
283
284 memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
285 ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
286 ok(ret == bm_width_bytes * bm.bmHeight, "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
287
288 HeapFree(GetProcessHeap(), 0, buf);
289
290 /* test various buffer sizes for GetObject */
291 memset(&ds, 0xAA, sizeof(ds));
292 ret = GetObjectW(hbm, sizeof(*bma) * 2, bma);
293 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
294 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
295 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
296 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
297
298 ret = GetObjectW(hbm, sizeof(bm) / 2, &bm);
299 ok(ret == 0, "%d != 0\n", ret);
300
301 ret = GetObjectW(hbm, 0, &bm);
302 ok(ret == 0, "%d != 0\n", ret);
303
304 ret = GetObjectW(hbm, 1, &bm);
305 ok(ret == 0, "%d != 0\n", ret);
306
307 /* test various buffer sizes for GetObject */
308 ret = GetObjectW(hbm, 0, NULL);
309 ok(ret == sizeof(bm), "wrong size %d\n", ret);
310
311 ret = GetObjectW(hbm, sizeof(*dsa) * 2, dsa);
312 ok(ret == sizeof(*dsa), "wrong size %d\n", ret);
313
314 memset(&ds, 0xAA, sizeof(ds));
315 ret = GetObjectW(hbm, sizeof(ds), &ds);
316 ok(ret == sizeof(ds), "wrong size %d\n", ret);
317
318 ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
319 if (ds.dsBm.bmWidthBytes != bm_width_bytes) /* Win2k bug */
320 ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%u != %u\n",
321 ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
322 ok(bmih->biSizeImage == 0, "%u != 0\n", bmih->biSizeImage);
323 ds.dsBmih.biSizeImage = 0;
324
325 ok(ds.dsBmih.biSize == bmih->biSize, "%u != %u\n", ds.dsBmih.biSize, bmih->biSize);
326 ok(ds.dsBmih.biWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
327 ok(ds.dsBmih.biHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
328 ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes);
329 ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount);
330 ok(ds.dsBmih.biCompression == bmih->biCompression ||
331 ((bmih->biBitCount == 32) && broken(ds.dsBmih.biCompression == BI_BITFIELDS)), /* nt4 sp1 and 2 */
332 "%u != %u\n", ds.dsBmih.biCompression, bmih->biCompression);
333 ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%u != %u\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
334 ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%d != %d\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
335 ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%d != %d\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);
336
337 memset(&ds, 0xAA, sizeof(ds));
338 ret = GetObjectW(hbm, sizeof(ds) - 4, &ds);
339 ok(ret == sizeof(ds.dsBm), "wrong size %d\n", ret);
340 ok(ds.dsBm.bmWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
341 ok(ds.dsBm.bmHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
342 ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);
343
344 ret = GetObjectW(hbm, 0, &ds);
345 ok(ret == 0, "%d != 0\n", ret);
346
347 ret = GetObjectW(hbm, 1, &ds);
348 ok(ret == 0, "%d != 0\n", ret);
349 }
350
351 static void _test_color( int line, HDC hdc, COLORREF color, COLORREF exp )
352 {
353 COLORREF c;
354 c = SetPixel(hdc, 0, 0, color);
355 ok_(__FILE__, line)(c == exp, "SetPixel failed: got 0x%06x expected 0x%06x\n", c, exp);
356 c = GetPixel(hdc, 0, 0);
357 ok_(__FILE__, line)(c == exp, "GetPixel failed: got 0x%06x expected 0x%06x\n", c, exp);
358 c = GetNearestColor(hdc, color);
359 ok_(__FILE__, line)(c == exp, "GetNearestColor failed: got 0x%06x expected 0x%06x\n", c, exp);
360 }
361 #define test_color(hdc, color, exp) _test_color( __LINE__, hdc, color, exp )
362
363
364 static void test_dib_bits_access( HBITMAP hdib, void *bits )
365 {
366 MEMORY_BASIC_INFORMATION info;
367 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
368 DWORD data[256];
369 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
370 HDC hdc;
371 char filename[MAX_PATH];
372 HANDLE file;
373 DWORD written;
374 INT ret;
375
376 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
377 "VirtualQuery failed\n");
378 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
379 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
380 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
381 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
382 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
383 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
384
385 memset( pbmi, 0, sizeof(bmibuf) );
386 memset( data, 0xcc, sizeof(data) );
387 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
388 pbmi->bmiHeader.biHeight = 16;
389 pbmi->bmiHeader.biWidth = 16;
390 pbmi->bmiHeader.biBitCount = 32;
391 pbmi->bmiHeader.biPlanes = 1;
392 pbmi->bmiHeader.biCompression = BI_RGB;
393
394 hdc = GetDC(0);
395
396 ret = SetDIBits( hdc, hdib, 0, 16, data, pbmi, DIB_RGB_COLORS );
397 ok(ret == 16, "SetDIBits failed: expected 16 got %d\n", ret);
398
399 ReleaseDC(0, hdc);
400
401 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
402 "VirtualQuery failed\n");
403 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
404 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
405 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
406 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
407 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
408 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
409
410 /* try writing protected bits to a file */
411
412 GetTempFileNameA( ".", "dib", 0, filename );
413 file = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
414 CREATE_ALWAYS, 0, 0 );
415 ok( file != INVALID_HANDLE_VALUE, "failed to open %s error %u\n", filename, GetLastError() );
416 ret = WriteFile( file, bits, 8192, &written, NULL );
417 ok( ret, "WriteFile failed error %u\n", GetLastError() );
418 if (ret) ok( written == 8192, "only wrote %u bytes\n", written );
419 CloseHandle( file );
420 DeleteFileA( filename );
421 }
422
423 static void test_dibsections(void)
424 {
425 HDC hdc, hdcmem, hdcmem2;
426 HBITMAP hdib, oldbm, hdib2, oldbm2;
427 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
428 char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
429 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
430 BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
431 RGBQUAD *colors = pbmi->bmiColors;
432 RGBTRIPLE *ccolors = pbci->bmciColors;
433 HBITMAP hcoredib;
434 char coreBits[256];
435 BYTE *bits;
436 RGBQUAD rgb[256];
437 int ret;
438 char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
439 LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
440 PALETTEENTRY *palent = plogpal->palPalEntry;
441 WORD *index;
442 DWORD *bits32;
443 HPALETTE hpal, oldpal;
444 DIBSECTION dibsec;
445 COLORREF c0, c1;
446 int i;
447 MEMORY_BASIC_INFORMATION info;
448
449 hdc = GetDC(0);
450
451 memset(pbmi, 0, sizeof(bmibuf));
452 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
453 pbmi->bmiHeader.biHeight = 100;
454 pbmi->bmiHeader.biWidth = 512;
455 pbmi->bmiHeader.biBitCount = 24;
456 pbmi->bmiHeader.biPlanes = 1;
457 pbmi->bmiHeader.biCompression = BI_RGB;
458
459 SetLastError(0xdeadbeef);
460
461 /* invalid pointer for BITMAPINFO
462 (*bits should be NULL on error) */
463 bits = (BYTE*)0xdeadbeef;
464 hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
465 ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n");
466
467 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
468 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
469 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
470 ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
471
472 /* test the DIB memory */
473 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
474 "VirtualQuery failed\n");
475 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
476 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
477 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
478 ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
479 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
480 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
481 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
482
483 test_dib_bits_access( hdib, bits );
484
485 test_dib_info(hdib, bits, &pbmi->bmiHeader);
486 DeleteObject(hdib);
487
488 /* Test a top-down DIB. */
489 pbmi->bmiHeader.biHeight = -100;
490 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
491 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
492 test_dib_info(hdib, bits, &pbmi->bmiHeader);
493 DeleteObject(hdib);
494
495 pbmi->bmiHeader.biHeight = 100;
496 pbmi->bmiHeader.biBitCount = 8;
497 pbmi->bmiHeader.biCompression = BI_RLE8;
498 SetLastError(0xdeadbeef);
499 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
500 ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
501 ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
502
503 pbmi->bmiHeader.biBitCount = 16;
504 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
505 ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
506 ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
507 ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
508 SetLastError(0xdeadbeef);
509 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
510 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
511
512 /* test the DIB memory */
513 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
514 "VirtualQuery failed\n");
515 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
516 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
517 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
518 ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
519 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
520 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
521 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
522
523 test_dib_info(hdib, bits, &pbmi->bmiHeader);
524 DeleteObject(hdib);
525
526 memset(pbmi, 0, sizeof(bmibuf));
527 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
528 pbmi->bmiHeader.biHeight = 16;
529 pbmi->bmiHeader.biWidth = 16;
530 pbmi->bmiHeader.biBitCount = 1;
531 pbmi->bmiHeader.biPlanes = 1;
532 pbmi->bmiHeader.biCompression = BI_RGB;
533 colors[0].rgbRed = 0xff;
534 colors[0].rgbGreen = 0;
535 colors[0].rgbBlue = 0;
536 colors[1].rgbRed = 0;
537 colors[1].rgbGreen = 0;
538 colors[1].rgbBlue = 0xff;
539
540 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
541 ok(hdib != NULL, "CreateDIBSection failed\n");
542 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
543 ok(dibsec.dsBmih.biClrUsed == 2,
544 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
545
546 /* Test if the old BITMAPCOREINFO structure is supported */
547
548 pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
549 pbci->bmciHeader.bcBitCount = 0;
550
551 ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
552 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
553 ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
554 && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
555 "GetDIBits didn't fill in the BITMAPCOREHEADER structure properly\n");
556
557 ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
558 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
559 ok((ccolors[0].rgbtRed == 0xff) && (ccolors[0].rgbtGreen == 0) &&
560 (ccolors[0].rgbtBlue == 0) && (ccolors[1].rgbtRed == 0) &&
561 (ccolors[1].rgbtGreen == 0) && (ccolors[1].rgbtBlue == 0xff),
562 "The color table has not been translated to the old BITMAPCOREINFO format\n");
563
564 hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
565 ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
566
567 ZeroMemory(ccolors, 256 * sizeof(RGBTRIPLE));
568 ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
569 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
570 ok((ccolors[0].rgbtRed == 0xff) && (ccolors[0].rgbtGreen == 0) &&
571 (ccolors[0].rgbtBlue == 0) && (ccolors[1].rgbtRed == 0) &&
572 (ccolors[1].rgbtGreen == 0) && (ccolors[1].rgbtBlue == 0xff),
573 "The color table has not been translated to the old BITMAPCOREINFO format\n");
574
575 DeleteObject(hcoredib);
576
577 hdcmem = CreateCompatibleDC(hdc);
578 oldbm = SelectObject(hdcmem, hdib);
579
580 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
581 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
582 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
583 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
584 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
585 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
586
587 c0 = RGB(colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue);
588 c1 = RGB(colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue);
589
590 test_color(hdcmem, DIBINDEX(0), c0);
591 test_color(hdcmem, DIBINDEX(1), c1);
592 test_color(hdcmem, DIBINDEX(2), c0);
593 test_color(hdcmem, PALETTEINDEX(0), c0);
594 test_color(hdcmem, PALETTEINDEX(1), c0);
595 test_color(hdcmem, PALETTEINDEX(2), c0);
596 test_color(hdcmem, PALETTERGB(colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue), c0);
597 test_color(hdcmem, PALETTERGB(colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue), c1);
598 test_color(hdcmem, PALETTERGB(0, 0, 0), c0);
599 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0);
600 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1);
601
602 SelectObject(hdcmem, oldbm);
603 DeleteObject(hdib);
604
605 colors[0].rgbRed = 0xff;
606 colors[0].rgbGreen = 0xff;
607 colors[0].rgbBlue = 0xff;
608 colors[1].rgbRed = 0;
609 colors[1].rgbGreen = 0;
610 colors[1].rgbBlue = 0;
611
612 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
613 ok(hdib != NULL, "CreateDIBSection failed\n");
614
615 test_dib_info(hdib, bits, &pbmi->bmiHeader);
616
617 oldbm = SelectObject(hdcmem, hdib);
618
619 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
620 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
621 ok(!memcmp(rgb, colors, 2 * sizeof(RGBQUAD)),
622 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
623 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
624 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
625
626 SelectObject(hdcmem, oldbm);
627 test_dib_info(hdib, bits, &pbmi->bmiHeader);
628 DeleteObject(hdib);
629
630 pbmi->bmiHeader.biBitCount = 4;
631 for (i = 0; i < 16; i++) {
632 colors[i].rgbRed = i;
633 colors[i].rgbGreen = 16-i;
634 colors[i].rgbBlue = 0;
635 }
636 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
637 ok(hdib != NULL, "CreateDIBSection failed\n");
638 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
639 ok(dibsec.dsBmih.biClrUsed == 16,
640 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
641 test_dib_info(hdib, bits, &pbmi->bmiHeader);
642 DeleteObject(hdib);
643
644 pbmi->bmiHeader.biBitCount = 8;
645
646 for (i = 0; i < 128; i++) {
647 colors[i].rgbRed = 255 - i * 2;
648 colors[i].rgbGreen = i * 2;
649 colors[i].rgbBlue = 0;
650 colors[255 - i].rgbRed = 0;
651 colors[255 - i].rgbGreen = i * 2;
652 colors[255 - i].rgbBlue = 255 - i * 2;
653 }
654 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
655 ok(hdib != NULL, "CreateDIBSection failed\n");
656 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
657 ok(dibsec.dsBmih.biClrUsed == 256,
658 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
659
660 oldbm = SelectObject(hdcmem, hdib);
661
662 for (i = 0; i < 256; i++) {
663 test_color(hdcmem, DIBINDEX(i), RGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue));
664 test_color(hdcmem, PALETTERGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue),
665 RGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue));
666 }
667
668 SelectObject(hdcmem, oldbm);
669 test_dib_info(hdib, bits, &pbmi->bmiHeader);
670 DeleteObject(hdib);
671
672 pbmi->bmiHeader.biBitCount = 1;
673
674 /* Now create a palette and a palette indexed dib section */
675 memset(plogpal, 0, sizeof(logpalbuf));
676 plogpal->palVersion = 0x300;
677 plogpal->palNumEntries = 2;
678 palent[0].peRed = 0xff;
679 palent[0].peBlue = 0xff;
680 palent[1].peGreen = 0xff;
681
682 index = (WORD*)pbmi->bmiColors;
683 *index++ = 0;
684 *index = 1;
685 hpal = CreatePalette(plogpal);
686 ok(hpal != NULL, "CreatePalette failed\n");
687 oldpal = SelectPalette(hdc, hpal, TRUE);
688 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
689 ok(hdib != NULL, "CreateDIBSection failed\n");
690 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
691 ok(dibsec.dsBmih.biClrUsed == 2, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
692
693 /* The colour table has already been grabbed from the dc, so we select back the
694 old palette */
695
696 SelectPalette(hdc, oldpal, TRUE);
697 oldbm = SelectObject(hdcmem, hdib);
698 oldpal = SelectPalette(hdcmem, hpal, TRUE);
699
700 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
701 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
702 ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
703 rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
704 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
705 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
706 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
707
708 c0 = RGB(palent[0].peRed, palent[0].peGreen, palent[0].peBlue);
709 c1 = RGB(palent[1].peRed, palent[1].peGreen, palent[1].peBlue);
710
711 test_color(hdcmem, DIBINDEX(0), c0);
712 test_color(hdcmem, DIBINDEX(1), c1);
713 test_color(hdcmem, DIBINDEX(2), c0);
714 test_color(hdcmem, PALETTEINDEX(0), c0);
715 test_color(hdcmem, PALETTEINDEX(1), c1);
716 test_color(hdcmem, PALETTEINDEX(2), c0);
717 test_color(hdcmem, PALETTERGB(palent[0].peRed, palent[0].peGreen, palent[0].peBlue), c0);
718 test_color(hdcmem, PALETTERGB(palent[1].peRed, palent[1].peGreen, palent[1].peBlue), c1);
719 test_color(hdcmem, PALETTERGB(0, 0, 0), c1);
720 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0);
721 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0);
722 test_color(hdcmem, PALETTERGB(0, 1, 0), c1);
723 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1);
724 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0);
725
726 /* Bottom and 2nd row from top green, everything else magenta */
727 bits[0] = bits[1] = 0xff;
728 bits[13 * 4] = bits[13*4 + 1] = 0xff;
729
730 test_dib_info(hdib, bits, &pbmi->bmiHeader);
731
732 pbmi->bmiHeader.biBitCount = 32;
733
734 hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
735 ok(hdib2 != NULL, "CreateDIBSection failed\n");
736 hdcmem2 = CreateCompatibleDC(hdc);
737 oldbm2 = SelectObject(hdcmem2, hdib2);
738
739 BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
740
741 ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
742 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
743
744 SelectObject(hdcmem2, oldbm2);
745 test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
746 DeleteObject(hdib2);
747
748 SelectObject(hdcmem, oldbm);
749 SelectPalette(hdcmem, oldpal, TRUE);
750 DeleteObject(hdib);
751 DeleteObject(hpal);
752
753
754 pbmi->bmiHeader.biBitCount = 8;
755
756 memset(plogpal, 0, sizeof(logpalbuf));
757 plogpal->palVersion = 0x300;
758 plogpal->palNumEntries = 256;
759
760 for (i = 0; i < 128; i++) {
761 palent[i].peRed = 255 - i * 2;
762 palent[i].peBlue = i * 2;
763 palent[i].peGreen = 0;
764 palent[255 - i].peRed = 0;
765 palent[255 - i].peGreen = i * 2;
766 palent[255 - i].peBlue = 255 - i * 2;
767 }
768
769 index = (WORD*)pbmi->bmiColors;
770 for (i = 0; i < 256; i++) {
771 *index++ = i;
772 }
773
774 hpal = CreatePalette(plogpal);
775 ok(hpal != NULL, "CreatePalette failed\n");
776 oldpal = SelectPalette(hdc, hpal, TRUE);
777 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
778 ok(hdib != NULL, "CreateDIBSection failed\n");
779 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
780 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
781
782 test_dib_info(hdib, bits, &pbmi->bmiHeader);
783
784 SelectPalette(hdc, oldpal, TRUE);
785 oldbm = SelectObject(hdcmem, hdib);
786 oldpal = SelectPalette(hdcmem, hpal, TRUE);
787
788 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
789 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
790 for (i = 0; i < 256; i++) {
791 ok(rgb[i].rgbRed == palent[i].peRed &&
792 rgb[i].rgbBlue == palent[i].peBlue &&
793 rgb[i].rgbGreen == palent[i].peGreen,
794 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
795 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
796 }
797
798 for (i = 0; i < 256; i++) {
799 test_color(hdcmem, DIBINDEX(i), RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
800 test_color(hdcmem, PALETTEINDEX(i), RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
801 test_color(hdcmem, PALETTERGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue),
802 RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
803 }
804
805 SelectPalette(hdcmem, oldpal, TRUE);
806 SelectObject(hdcmem, oldbm);
807 DeleteObject(hdib);
808 DeleteObject(hpal);
809
810 plogpal->palNumEntries = 37;
811 hpal = CreatePalette(plogpal);
812 ok(hpal != NULL, "CreatePalette failed\n");
813 oldpal = SelectPalette(hdc, hpal, TRUE);
814 pbmi->bmiHeader.biClrUsed = 142;
815 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
816 ok(hdib != NULL, "CreateDIBSection failed\n");
817 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
818 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
819
820 test_dib_info(hdib, bits, &pbmi->bmiHeader);
821
822 SelectPalette(hdc, oldpal, TRUE);
823 oldbm = SelectObject(hdcmem, hdib);
824
825 memset( rgb, 0xcc, sizeof(rgb) );
826 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
827 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
828 for (i = 0; i < 256; i++)
829 {
830 if (i < pbmi->bmiHeader.biClrUsed)
831 {
832 ok(rgb[i].rgbRed == palent[i % 37].peRed &&
833 rgb[i].rgbBlue == palent[i % 37].peBlue &&
834 rgb[i].rgbGreen == palent[i % 37].peGreen,
835 "GetDIBColorTable returns table %d: r %02x g %02x b %02x res%02x\n",
836 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
837 test_color(hdcmem, DIBINDEX(i),
838 RGB(palent[i % 37].peRed, palent[i % 37].peGreen, palent[i % 37].peBlue));
839 }
840 else
841 {
842 ok(rgb[i].rgbRed == 0 && rgb[i].rgbBlue == 0 && rgb[i].rgbGreen == 0,
843 "GetDIBColorTable returns table %d: r %02x g %02x b %02x res%02x\n",
844 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
845 test_color(hdcmem, DIBINDEX(i), 0 );
846 }
847 }
848 pbmi->bmiHeader.biClrUsed = 173;
849 memset( pbmi->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
850 GetDIBits( hdc, hdib, 0, 1, NULL, pbmi, DIB_RGB_COLORS );
851 ok( pbmi->bmiHeader.biClrUsed == 0, "wrong colors %u\n", pbmi->bmiHeader.biClrUsed );
852 for (i = 0; i < 256; i++)
853 {
854 if (i < 142)
855 ok(colors[i].rgbRed == palent[i % 37].peRed &&
856 colors[i].rgbBlue == palent[i % 37].peBlue &&
857 colors[i].rgbGreen == palent[i % 37].peGreen,
858 "GetDIBits returns table %d: r %02x g %02x b %02x res%02x\n",
859 i, colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
860 else
861 ok(colors[i].rgbRed == 0 && colors[i].rgbBlue == 0 && colors[i].rgbGreen == 0,
862 "GetDIBits returns table %d: r %02x g %02x b %02x res%02x\n",
863 i, colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
864 }
865
866 rgb[0].rgbRed = 1;
867 rgb[0].rgbGreen = 2;
868 rgb[0].rgbBlue = 3;
869 rgb[0].rgbReserved = 123;
870 ret = SetDIBColorTable( hdcmem, 0, 1, rgb );
871 ok( ret == 1, "SetDIBColorTable returned unexpected result %u\n", ret );
872 ok( rgb[0].rgbReserved == 123, "Expected rgbReserved = 123, got %u\n", rgb[0].rgbReserved );
873
874 rgb[0].rgbRed = rgb[0].rgbGreen = rgb[0].rgbBlue = rgb[0].rgbReserved = -1;
875 ret = GetDIBColorTable( hdcmem, 0, 1, rgb );
876 ok( ret == 1, "GetDIBColorTable returned unexpected result %u\n", ret );
877 ok( rgb[0].rgbRed == 1, "Expected rgbRed = 1, got %u\n", rgb[0].rgbRed );
878 ok( rgb[0].rgbGreen == 2, "Expected rgbGreen = 2, got %u\n", rgb[0].rgbGreen );
879 ok( rgb[0].rgbBlue == 3, "Expected rgbBlue = 3, got %u\n", rgb[0].rgbBlue );
880 ok( rgb[0].rgbReserved == 0, "Expected rgbReserved = 0, got %u\n", rgb[0].rgbReserved );
881
882 SelectObject(hdcmem, oldbm);
883 DeleteObject(hdib);
884 DeleteObject(hpal);
885
886 /* ClrUsed ignored on > 8bpp */
887 pbmi->bmiHeader.biBitCount = 16;
888 pbmi->bmiHeader.biClrUsed = 37;
889 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
890 ok(hdib != NULL, "CreateDIBSection failed\n");
891 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
892 ok(dibsec.dsBmih.biClrUsed == 0, "created DIBSection: wrong biClrUsed field: %u\n", dibsec.dsBmih.biClrUsed);
893 oldbm = SelectObject(hdcmem, hdib);
894 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
895 ok(ret == 0, "GetDIBColorTable returned %d\n", ret);
896 SelectObject(hdcmem, oldbm);
897 DeleteObject(hdib);
898
899 DeleteDC(hdcmem);
900 DeleteDC(hdcmem2);
901 ReleaseDC(0, hdc);
902 }
903
904 static void test_dib_formats(void)
905 {
906 BITMAPINFO *bi;
907 char data[256];
908 void *bits;
909 int planes, bpp, compr, format;
910 HBITMAP hdib, hbmp;
911 HDC hdc, memdc;
912 UINT ret;
913 BOOL format_ok, expect_ok;
914
915 bi = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
916 hdc = GetDC( 0 );
917 memdc = CreateCompatibleDC( 0 );
918 hbmp = CreateCompatibleBitmap( hdc, 10, 10 );
919
920 memset( data, 0xaa, sizeof(data) );
921
922 if (!winetest_interactive)
923 skip("ROSTESTS-152: Skipping loop in test_dib_formats because it's too big and causes too many failures\n");
924 else
925 for (bpp = 0; bpp <= 64; bpp++)
926 {
927 for (planes = 0; planes <= 64; planes++)
928 {
929 for (compr = 0; compr < 8; compr++)
930 {
931 for (format = DIB_RGB_COLORS; format <= DIB_PAL_COLORS; format++)
932 {
933 switch (bpp)
934 {
935 case 1:
936 case 4:
937 case 8:
938 case 24: expect_ok = (compr == BI_RGB); break;
939 case 16:
940 case 32: expect_ok = (compr == BI_RGB || compr == BI_BITFIELDS); break;
941 default: expect_ok = FALSE; break;
942 }
943
944 memset( bi, 0, sizeof(bi->bmiHeader) );
945 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
946 bi->bmiHeader.biWidth = 2;
947 bi->bmiHeader.biHeight = 2;
948 bi->bmiHeader.biPlanes = planes;
949 bi->bmiHeader.biBitCount = bpp;
950 bi->bmiHeader.biCompression = compr;
951 bi->bmiHeader.biSizeImage = 0;
952 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
953 ret = GetDIBits(hdc, hbmp, 0, 0, data, bi, format);
954 if (expect_ok || (!bpp && compr != BI_JPEG && compr != BI_PNG) ||
955 (bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8))
956 ok( ret, "GetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
957 else
958 ok( !ret || broken(!bpp && (compr == BI_JPEG || compr == BI_PNG)), /* nt4 */
959 "GetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
960
961 /* all functions check planes except GetDIBits with 0 lines */
962 format_ok = expect_ok;
963 if (!planes) expect_ok = FALSE;
964 memset( bi, 0, sizeof(bi->bmiHeader) );
965 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
966 bi->bmiHeader.biWidth = 2;
967 bi->bmiHeader.biHeight = 2;
968 bi->bmiHeader.biPlanes = planes;
969 bi->bmiHeader.biBitCount = bpp;
970 bi->bmiHeader.biCompression = compr;
971 bi->bmiHeader.biSizeImage = 0;
972 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
973
974 hdib = CreateDIBSection(hdc, bi, format, &bits, NULL, 0);
975 if (expect_ok && (planes == 1 || planes * bpp <= 16) &&
976 (compr != BI_BITFIELDS || format != DIB_PAL_COLORS))
977 ok( hdib != NULL, "CreateDIBSection failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
978 else
979 ok( hdib == NULL, "CreateDIBSection succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
980 if (hdib) DeleteObject( hdib );
981
982 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, data, bi, format );
983 /* no sanity checks in CreateDIBitmap except compression */
984 if (compr == BI_JPEG || compr == BI_PNG)
985 ok( hdib == NULL || broken(hdib != NULL), /* nt4 */
986 "CreateDIBitmap succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
987 else
988 ok( hdib != NULL, "CreateDIBitmap failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
989 if (hdib) DeleteObject( hdib );
990
991 /* RLE needs a size */
992 bi->bmiHeader.biSizeImage = 0;
993 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, format);
994 if (expect_ok)
995 ok( ret, "SetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
996 else
997 ok( !ret ||
998 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
999 "SetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1000 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, format );
1001 if (expect_ok)
1002 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1003 else
1004 ok( !ret ||
1005 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
1006 "SetDIBitsToDevice succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1007 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, format, SRCCOPY );
1008 if (expect_ok)
1009 ok( ret, "StretchDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1010 else
1011 ok( !ret ||
1012 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
1013 "StretchDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1014
1015 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, format);
1016 if (expect_ok)
1017 ok( ret, "GetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1018 else
1019 ok( !ret, "GetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1020 ok( bi->bmiHeader.biBitCount == bpp, "GetDIBits modified bpp %u/%u\n",
1021 bpp, bi->bmiHeader.biBitCount );
1022
1023 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1024 bi->bmiHeader.biWidth = 2;
1025 bi->bmiHeader.biHeight = 2;
1026 bi->bmiHeader.biPlanes = planes;
1027 bi->bmiHeader.biBitCount = bpp;
1028 bi->bmiHeader.biCompression = compr;
1029 bi->bmiHeader.biSizeImage = 1;
1030 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
1031 /* RLE allowed with valid biSizeImage */
1032 if ((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)) expect_ok = TRUE;
1033
1034 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, format);
1035 if (expect_ok)
1036 ok( ret, "SetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1037 else
1038 ok( !ret, "SetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1039 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, format );
1040 if (expect_ok)
1041 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1042 else
1043 ok( !ret, "SetDIBitsToDevice succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1044 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, format, SRCCOPY );
1045 if (expect_ok)
1046 ok( ret, "StretchDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1047 else
1048 ok( !ret, "StretchDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1049
1050 bi->bmiHeader.biSizeImage = 0;
1051 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, format);
1052 if (expect_ok || !bpp)
1053 ok( ret, "GetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1054 else
1055 ok( !ret || broken(format_ok && !planes), /* nt4 */
1056 "GetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1057 }
1058 }
1059 }
1060 }
1061
1062 memset( bi, 0, sizeof(bi->bmiHeader) );
1063 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1064 bi->bmiHeader.biWidth = 2;
1065 bi->bmiHeader.biHeight = 2;
1066 bi->bmiHeader.biPlanes = 1;
1067 bi->bmiHeader.biBitCount = 16;
1068 bi->bmiHeader.biCompression = BI_BITFIELDS;
1069 bi->bmiHeader.biSizeImage = 0;
1070 *(DWORD *)&bi->bmiColors[0] = 0;
1071 *(DWORD *)&bi->bmiColors[1] = 0;
1072 *(DWORD *)&bi->bmiColors[2] = 0;
1073
1074 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1075 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1076 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1077 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1078 /* other functions don't check */
1079 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1080 ok( hdib != NULL, "CreateDIBitmap failed with null bitfields\n" );
1081 DeleteObject( hdib );
1082 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1083 ok( ret, "SetDIBitsToDevice failed with null bitfields\n" );
1084 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1085 ok( ret, "StretchDIBits failed with null bitfields\n" );
1086 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1087 ok( ret, "GetDIBits failed with null bitfields\n" );
1088 bi->bmiHeader.biPlanes = 1;
1089 bi->bmiHeader.biBitCount = 16;
1090 bi->bmiHeader.biCompression = BI_BITFIELDS;
1091 bi->bmiHeader.biSizeImage = 0;
1092 *(DWORD *)&bi->bmiColors[0] = 0;
1093 *(DWORD *)&bi->bmiColors[1] = 0;
1094 *(DWORD *)&bi->bmiColors[2] = 0;
1095 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1096 ok( ret, "GetDIBits failed with null bitfields\n" );
1097
1098 /* all fields must be non-zero */
1099 *(DWORD *)&bi->bmiColors[0] = 3;
1100 *(DWORD *)&bi->bmiColors[1] = 0;
1101 *(DWORD *)&bi->bmiColors[2] = 7;
1102 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1103 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1104 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1105 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1106
1107 /* garbage is ok though */
1108 *(DWORD *)&bi->bmiColors[0] = 0x55;
1109 *(DWORD *)&bi->bmiColors[1] = 0x44;
1110 *(DWORD *)&bi->bmiColors[2] = 0x33;
1111 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1112 ok( hdib != NULL, "CreateDIBSection failed with bad bitfields\n" );
1113 if (hdib) DeleteObject( hdib );
1114 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1115 ok( ret, "SetDIBits failed with bad bitfields\n" );
1116
1117 bi->bmiHeader.biWidth = -2;
1118 bi->bmiHeader.biHeight = 2;
1119 bi->bmiHeader.biBitCount = 32;
1120 bi->bmiHeader.biCompression = BI_RGB;
1121 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1122 ok( hdib == NULL, "CreateDIBSection succeeded with negative width\n" );
1123 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1124 ok( hdib == NULL, "CreateDIBitmap succeeded with negative width\n" );
1125 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1126 ok( !ret, "SetDIBits succeeded with negative width\n" );
1127 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1128 ok( !ret, "SetDIBitsToDevice succeeded with negative width\n" );
1129 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1130 ok( !ret, "StretchDIBits succeeded with negative width\n" );
1131 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1132 ok( !ret, "GetDIBits succeeded with negative width\n" );
1133 bi->bmiHeader.biWidth = -2;
1134 bi->bmiHeader.biHeight = 2;
1135 bi->bmiHeader.biBitCount = 32;
1136 bi->bmiHeader.biCompression = BI_RGB;
1137 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1138 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with negative width\n" );
1139
1140 bi->bmiHeader.biWidth = 0;
1141 bi->bmiHeader.biHeight = 2;
1142 bi->bmiHeader.biBitCount = 32;
1143 bi->bmiHeader.biCompression = BI_RGB;
1144 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1145 ok( hdib == NULL, "CreateDIBSection succeeded with zero width\n" );
1146 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1147 ok( hdib != NULL, "CreateDIBitmap failed with zero width\n" );
1148 DeleteObject( hdib );
1149 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1150 ok( !ret || broken(ret), /* nt4 */ "SetDIBits succeeded with zero width\n" );
1151 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1152 ok( !ret || broken(ret), /* nt4 */ "SetDIBitsToDevice succeeded with zero width\n" );
1153 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1154 ok( !ret || broken(ret), /* nt4 */ "StretchDIBits succeeded with zero width\n" );
1155 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1156 ok( !ret, "GetDIBits succeeded with zero width\n" );
1157 bi->bmiHeader.biWidth = 0;
1158 bi->bmiHeader.biHeight = 2;
1159 bi->bmiHeader.biBitCount = 32;
1160 bi->bmiHeader.biCompression = BI_RGB;
1161 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1162 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero width\n" );
1163
1164 bi->bmiHeader.biWidth = 2;
1165 bi->bmiHeader.biHeight = 0;
1166 bi->bmiHeader.biBitCount = 32;
1167 bi->bmiHeader.biCompression = BI_RGB;
1168 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1169 ok( hdib == NULL, "CreateDIBSection succeeded with zero height\n" );
1170 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1171 ok( hdib != NULL, "CreateDIBitmap failed with zero height\n" );
1172 DeleteObject( hdib );
1173 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1174 ok( !ret, "SetDIBits succeeded with zero height\n" );
1175 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1176 ok( !ret, "SetDIBitsToDevice succeeded with zero height\n" );
1177 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1178 ok( !ret, "StretchDIBits succeeded with zero height\n" );
1179 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1180 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1181 bi->bmiHeader.biWidth = 2;
1182 bi->bmiHeader.biHeight = 0;
1183 bi->bmiHeader.biBitCount = 32;
1184 bi->bmiHeader.biCompression = BI_RGB;
1185 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1186 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1187
1188 /* some functions accept DIB_PAL_COLORS+1, but not beyond */
1189
1190 bi->bmiHeader.biWidth = 2;
1191 bi->bmiHeader.biHeight = 2;
1192 bi->bmiHeader.biBitCount = 1;
1193 bi->bmiHeader.biCompression = BI_RGB;
1194 hdib = CreateDIBSection(hdc, bi, DIB_PAL_COLORS+1, &bits, NULL, 0);
1195 ok( hdib == NULL, "CreateDIBSection succeeded with DIB_PAL_COLORS+1\n" );
1196 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_PAL_COLORS+1 );
1197 ok( hdib != NULL, "CreateDIBitmap failed with DIB_PAL_COLORS+1\n" );
1198 DeleteObject( hdib );
1199 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_PAL_COLORS+1);
1200 ok( !ret, "SetDIBits succeeded with DIB_PAL_COLORS+1\n" );
1201 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_PAL_COLORS+1 );
1202 ok( ret, "SetDIBitsToDevice failed with DIB_PAL_COLORS+1\n" );
1203 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_PAL_COLORS+1, SRCCOPY );
1204 ok( ret, "StretchDIBits failed with DIB_PAL_COLORS+1\n" );
1205 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_PAL_COLORS+1);
1206 ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+1\n" );
1207 bi->bmiHeader.biWidth = 2;
1208 bi->bmiHeader.biHeight = 2;
1209 bi->bmiHeader.biBitCount = 1;
1210 bi->bmiHeader.biCompression = BI_RGB;
1211 ret = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS+1);
1212 ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+1\n" );
1213
1214 bi->bmiHeader.biWidth = 2;
1215 bi->bmiHeader.biHeight = 2;
1216 bi->bmiHeader.biBitCount = 1;
1217 bi->bmiHeader.biCompression = BI_RGB;
1218 hdib = CreateDIBSection(hdc, bi, DIB_PAL_COLORS+2, &bits, NULL, 0);
1219 ok( hdib == NULL, "CreateDIBSection succeeded with DIB_PAL_COLORS+2\n" );
1220 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_PAL_COLORS+2 );
1221 ok( hdib == NULL, "CreateDIBitmap succeeded with DIB_PAL_COLORS+2\n" );
1222 DeleteObject( hdib );
1223 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_PAL_COLORS+2);
1224 ok( !ret, "SetDIBits succeeded with DIB_PAL_COLORS+2\n" );
1225 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_PAL_COLORS+2 );
1226 ok( !ret, "SetDIBitsToDevice succeeded with DIB_PAL_COLORS+2\n" );
1227 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_PAL_COLORS+2, SRCCOPY );
1228 ok( !ret, "StretchDIBits succeeded with DIB_PAL_COLORS+2\n" );
1229 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_PAL_COLORS+2);
1230 ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+2\n" );
1231 bi->bmiHeader.biWidth = 2;
1232 bi->bmiHeader.biHeight = 2;
1233 bi->bmiHeader.biBitCount = 1;
1234 bi->bmiHeader.biCompression = BI_RGB;
1235 ret = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS+2);
1236 ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+2\n" );
1237
1238 bi->bmiHeader.biWidth = 0x4000;
1239 bi->bmiHeader.biHeight = 0x4000;
1240 bi->bmiHeader.biBitCount = 1;
1241 bi->bmiHeader.biCompression = BI_RGB;
1242 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1243 ok( hdib != NULL, "CreateDIBSection failed with large size\n" );
1244 DeleteObject( hdib );
1245
1246 bi->bmiHeader.biWidth = 0x8001;
1247 bi->bmiHeader.biHeight = 0x8001;
1248 bi->bmiHeader.biBitCount = 32;
1249 bi->bmiHeader.biCompression = BI_RGB;
1250 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1251 ok( hdib == NULL, "CreateDIBSection succeeded with size overflow\n" );
1252
1253 bi->bmiHeader.biWidth = 1;
1254 bi->bmiHeader.biHeight = 0x40000001;
1255 bi->bmiHeader.biBitCount = 32;
1256 bi->bmiHeader.biCompression = BI_RGB;
1257 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1258 ok( hdib == NULL, "CreateDIBSection succeeded with size overflow\n" );
1259
1260 bi->bmiHeader.biWidth = 2;
1261 bi->bmiHeader.biHeight = 0x40000001;
1262 bi->bmiHeader.biBitCount = 16;
1263 bi->bmiHeader.biCompression = BI_RGB;
1264 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1265 ok( hdib == NULL, "CreateDIBSection succeeded with size overflow\n" );
1266
1267 bi->bmiHeader.biWidth = 0x40000001;
1268 bi->bmiHeader.biHeight = 1;
1269 bi->bmiHeader.biBitCount = 32;
1270 bi->bmiHeader.biCompression = BI_RGB;
1271 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1272 ok( hdib == NULL, "CreateDIBSection succeeded with size overflow\n" );
1273
1274 bi->bmiHeader.biWidth = 0x40000001;
1275 bi->bmiHeader.biHeight = 4;
1276 bi->bmiHeader.biBitCount = 8;
1277 bi->bmiHeader.biCompression = BI_RGB;
1278 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1279 ok( hdib == NULL, "CreateDIBSection succeeded with size overflow\n" );
1280
1281 DeleteDC( memdc );
1282 DeleteObject( hbmp );
1283 ReleaseDC( 0, hdc );
1284 HeapFree( GetProcessHeap(), 0, bi );
1285 }
1286
1287 static void test_mono_dibsection(void)
1288 {
1289 HDC hdc, memdc;
1290 HBITMAP old_bm, mono_ds;
1291 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
1292 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
1293 RGBQUAD *colors = pbmi->bmiColors;
1294 BYTE bits[10 * 4];
1295 BYTE *ds_bits;
1296 int num;
1297
1298 hdc = GetDC(0);
1299
1300 memdc = CreateCompatibleDC(hdc);
1301
1302 memset(pbmi, 0, sizeof(bmibuf));
1303 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
1304 pbmi->bmiHeader.biHeight = 10;
1305 pbmi->bmiHeader.biWidth = 10;
1306 pbmi->bmiHeader.biBitCount = 1;
1307 pbmi->bmiHeader.biPlanes = 1;
1308 pbmi->bmiHeader.biCompression = BI_RGB;
1309 colors[0].rgbRed = 0xff;
1310 colors[0].rgbGreen = 0xff;
1311 colors[0].rgbBlue = 0xff;
1312 colors[1].rgbRed = 0x0;
1313 colors[1].rgbGreen = 0x0;
1314 colors[1].rgbBlue = 0x0;
1315
1316 /*
1317 * First dib section is 'inverted' ie color[0] is white, color[1] is black
1318 */
1319
1320 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1321 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1322 old_bm = SelectObject(memdc, mono_ds);
1323
1324 /* black border, white interior */
1325 Rectangle(memdc, 0, 0, 10, 10);
1326 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1327 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1328
1329 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1330
1331 memset(bits, 0, sizeof(bits));
1332 bits[0] = 0xaa;
1333
1334 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1335 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1336
1337 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1338
1339 colors[0].rgbRed = 0x0;
1340 colors[0].rgbGreen = 0x0;
1341 colors[0].rgbBlue = 0x0;
1342 colors[1].rgbRed = 0xff;
1343 colors[1].rgbGreen = 0xff;
1344 colors[1].rgbBlue = 0xff;
1345
1346 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1347 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1348
1349 SelectObject(memdc, old_bm);
1350 DeleteObject(mono_ds);
1351
1352 /*
1353 * Next dib section is 'normal' ie color[0] is black, color[1] is white
1354 */
1355
1356 colors[0].rgbRed = 0x0;
1357 colors[0].rgbGreen = 0x0;
1358 colors[0].rgbBlue = 0x0;
1359 colors[1].rgbRed = 0xff;
1360 colors[1].rgbGreen = 0xff;
1361 colors[1].rgbBlue = 0xff;
1362
1363 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1364 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1365 old_bm = SelectObject(memdc, mono_ds);
1366
1367 /* black border, white interior */
1368 Rectangle(memdc, 0, 0, 10, 10);
1369 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
1370 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
1371
1372 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
1373
1374 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1375 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1376
1377 /* SetDIBitsToDevice with an inverted bmi -> normal dib section */
1378
1379 colors[0].rgbRed = 0xff;
1380 colors[0].rgbGreen = 0xff;
1381 colors[0].rgbBlue = 0xff;
1382 colors[1].rgbRed = 0x0;
1383 colors[1].rgbGreen = 0x0;
1384 colors[1].rgbBlue = 0x0;
1385
1386 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1387 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1388
1389 /*
1390 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
1391 */
1392
1393 colors[0].rgbRed = 0xff;
1394 colors[0].rgbGreen = 0xff;
1395 colors[0].rgbBlue = 0xff;
1396 colors[1].rgbRed = 0x0;
1397 colors[1].rgbGreen = 0x0;
1398 colors[1].rgbBlue = 0x0;
1399 num = SetDIBColorTable(memdc, 0, 2, colors);
1400 ok(num == 2, "num = %d\n", num);
1401
1402 /* black border, white interior */
1403 Rectangle(memdc, 0, 0, 10, 10);
1404 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1405 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1406
1407 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1408
1409 memset(bits, 0, sizeof(bits));
1410 bits[0] = 0xaa;
1411
1412 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1413 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1414
1415 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1416
1417 colors[0].rgbRed = 0x0;
1418 colors[0].rgbGreen = 0x0;
1419 colors[0].rgbBlue = 0x0;
1420 colors[1].rgbRed = 0xff;
1421 colors[1].rgbGreen = 0xff;
1422 colors[1].rgbBlue = 0xff;
1423
1424 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1425 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1426
1427 SelectObject(memdc, old_bm);
1428 DeleteObject(mono_ds);
1429
1430 /*
1431 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
1432 */
1433
1434 colors[0].rgbRed = 0xff;
1435 colors[0].rgbGreen = 0x0;
1436 colors[0].rgbBlue = 0x0;
1437 colors[1].rgbRed = 0xfe;
1438 colors[1].rgbGreen = 0x0;
1439 colors[1].rgbBlue = 0x0;
1440
1441 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1442 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1443 old_bm = SelectObject(memdc, mono_ds);
1444
1445 /* black border, white interior */
1446 Rectangle(memdc, 0, 0, 10, 10);
1447 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1448 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1449
1450 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1451
1452 colors[0].rgbRed = 0x0;
1453 colors[0].rgbGreen = 0x0;
1454 colors[0].rgbBlue = 0x0;
1455 colors[1].rgbRed = 0xff;
1456 colors[1].rgbGreen = 0xff;
1457 colors[1].rgbBlue = 0xff;
1458
1459 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1460 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1461
1462 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1463
1464 colors[0].rgbRed = 0xff;
1465 colors[0].rgbGreen = 0xff;
1466 colors[0].rgbBlue = 0xff;
1467 colors[1].rgbRed = 0x0;
1468 colors[1].rgbGreen = 0x0;
1469 colors[1].rgbBlue = 0x0;
1470
1471 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1472 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1473
1474 SelectObject(memdc, old_bm);
1475 DeleteObject(mono_ds);
1476
1477 DeleteDC(memdc);
1478 ReleaseDC(0, hdc);
1479 }
1480
1481 static void test_bitmap(void)
1482 {
1483 char buf[256], buf_cmp[256];
1484 HBITMAP hbmp, hbmp_old;
1485 HDC hdc;
1486 BITMAP bm;
1487 BITMAP bma[2];
1488 INT ret;
1489
1490 hdc = CreateCompatibleDC(0);
1491 assert(hdc != 0);
1492
1493 SetLastError(0xdeadbeef);
1494 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1495 if (!hbmp)
1496 {
1497 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1498 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1499 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1500 }
1501 else
1502 DeleteObject(hbmp);
1503
1504 SetLastError(0xdeadbeef);
1505 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1506 if (!hbmp)
1507 {
1508 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1509 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1510 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1511 }
1512 else
1513 DeleteObject(hbmp);
1514
1515 SetLastError(0xdeadbeef);
1516 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1517 ok(!hbmp, "CreateBitmap should fail\n");
1518 if (!hbmp)
1519 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1520 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1521 else
1522 DeleteObject(hbmp);
1523
1524 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1525 assert(hbmp != NULL);
1526
1527 ret = GetObjectW(hbmp, sizeof(bm), &bm);
1528 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1529
1530 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1531 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1532 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1533 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1534 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1535 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1536 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1537
1538 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1539 assert(sizeof(buf) == sizeof(buf_cmp));
1540
1541 ret = GetBitmapBits(hbmp, 0, NULL);
1542 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1543
1544 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1545 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1546
1547 memset(buf, 0xAA, sizeof(buf));
1548 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1549 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1550 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1551
1552 hbmp_old = SelectObject(hdc, hbmp);
1553
1554 ret = GetObjectW(hbmp, sizeof(bm), &bm);
1555 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1556
1557 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1558 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1559 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1560 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1561 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1562 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1563 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1564
1565 memset(buf, 0xAA, sizeof(buf));
1566 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1567 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1568 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1569
1570 hbmp_old = SelectObject(hdc, hbmp_old);
1571 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1572
1573 /* test various buffer sizes for GetObject */
1574 ret = GetObjectW(hbmp, sizeof(*bma) * 2, bma);
1575 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1576
1577 ret = GetObjectW(hbmp, sizeof(bm) / 2, &bm);
1578 ok(ret == 0, "%d != 0\n", ret);
1579
1580 ret = GetObjectW(hbmp, 0, &bm);
1581 ok(ret == 0, "%d != 0\n", ret);
1582
1583 ret = GetObjectW(hbmp, 1, &bm);
1584 ok(ret == 0, "%d != 0\n", ret);
1585
1586 DeleteObject(hbmp);
1587 DeleteDC(hdc);
1588 }
1589
1590 static COLORREF get_nearest( int r, int g, int b )
1591 {
1592 return (r*r + g*g + b*b < (255-r)*(255-r) + (255-g)*(255-g) + (255-b)*(255-b)) ? 0x000000 : 0xffffff;
1593 }
1594
1595 static BOOL is_black_pen( COLORREF fg, COLORREF bg, int r, int g, int b )
1596 {
1597 if (fg == 0 || bg == 0xffffff) return RGB(r,g,b) != 0xffffff && RGB(r,g,b) != bg;
1598 return RGB(r,g,b) == 0x000000 || RGB(r,g,b) == bg;
1599 }
1600
1601 static void test_bitmap_colors( HDC hdc, COLORREF fg, COLORREF bg, int r, int g, int b )
1602 {
1603 static const WORD pattern_bits[] = { 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa };
1604 char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors ) + 256 * sizeof(RGBQUAD)];
1605 BITMAPINFO *info = (BITMAPINFO *)buffer;
1606 RGBQUAD *colors = info->bmiColors;
1607 WORD bits[16];
1608 void *bits_ptr;
1609 COLORREF res;
1610 HBRUSH old_brush;
1611 HPEN old_pen;
1612 HBITMAP bitmap;
1613 HDC memdc;
1614
1615 res = SetPixel( hdc, 0, 0, RGB(r,g,b) );
1616 ok( res == get_nearest( r, g, b ),
1617 "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg );
1618 res = GetPixel( hdc, 0, 0 );
1619 ok( res == get_nearest( r, g, b ),
1620 "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg );
1621 res = GetNearestColor( hdc, RGB(r,g,b) );
1622 ok( res == get_nearest( r, g, b ),
1623 "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg );
1624
1625 /* solid pen */
1626 old_pen = SelectObject( hdc, CreatePen( PS_SOLID, 1, RGB(r,g,b) ));
1627 MoveToEx( hdc, 0, 0, NULL );
1628 LineTo( hdc, 16, 0 );
1629 res = GetPixel( hdc, 0, 0 );
1630 ok( res == (is_black_pen( fg, bg, r, g, b ) ? 0 : 0xffffff),
1631 "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg );
1632 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1633 ok( bits[0] == (is_black_pen( fg, bg, r, g, b ) ? 0x00 : 0xffff),
1634 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1635 DeleteObject( SelectObject( hdc, old_pen ));
1636
1637 /* mono DDB pattern brush */
1638 bitmap = CreateBitmap( 16, 8, 1, 1, pattern_bits );
1639 old_brush = SelectObject( hdc, CreatePatternBrush( bitmap ));
1640 PatBlt( hdc, 0, 0, 16, 16, PATCOPY );
1641 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1642 ok( bits[0] == 0x5555 || broken(bits[0] == 0xaada) /* XP SP1 & 2003 SP0 */,
1643 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1644 DeleteObject( SelectObject( hdc, old_brush ));
1645
1646 /* mono DDB bitmap */
1647 memdc = CreateCompatibleDC( hdc );
1648 SelectObject( memdc, bitmap );
1649 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1650 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1651 ok( bits[0] == 0x5555,
1652 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1653 SetTextColor( memdc, RGB(255,255,255) );
1654 SetBkColor( memdc, RGB(0,0,0) );
1655 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1656 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1657 ok( bits[0] == 0x5555,
1658 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1659
1660 /* mono DIB section */
1661 memset( buffer, 0, sizeof(buffer) );
1662 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1663 info->bmiHeader.biHeight = -16;
1664 info->bmiHeader.biWidth = 16;
1665 info->bmiHeader.biBitCount = 1;
1666 info->bmiHeader.biPlanes = 1;
1667 info->bmiHeader.biCompression = BI_RGB;
1668 colors[0].rgbRed = 0xff;
1669 colors[0].rgbGreen = 0xff;
1670 colors[0].rgbBlue = 0xf0;
1671 colors[1].rgbRed = 0x20;
1672 colors[1].rgbGreen = 0x0;
1673 colors[1].rgbBlue = 0x0;
1674 bitmap = CreateDIBSection( 0, info, DIB_RGB_COLORS, &bits_ptr, NULL, 0 );
1675 memset( bits_ptr, 0x55, 64 );
1676 DeleteObject( SelectObject( memdc, bitmap ));
1677 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1678 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1679 ok( bits[0] == 0x5555,
1680 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1681
1682 colors[0].rgbRed = 0x0;
1683 colors[0].rgbGreen = 0x0;
1684 colors[0].rgbBlue = 0x10;
1685 colors[1].rgbRed = 0xff;
1686 colors[1].rgbGreen = 0xf0;
1687 colors[1].rgbBlue = 0xff;
1688 bitmap = CreateDIBSection( 0, info, DIB_RGB_COLORS, &bits_ptr, NULL, 0 );
1689 memset( bits_ptr, 0x55, 64 );
1690 DeleteObject( SelectObject( memdc, bitmap ));
1691 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1692 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1693 ok( bits[0] == 0xaaaa,
1694 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1695
1696 SetTextColor( memdc, RGB(0,20,0) );
1697 SetBkColor( memdc, RGB(240,240,240) );
1698 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1699 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1700 ok( bits[0] == 0x5555,
1701 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1702
1703 SetTextColor( memdc, RGB(250,250,250) );
1704 SetBkColor( memdc, RGB(10,10,10) );
1705 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1706 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1707 ok( bits[0] == 0xaaaa,
1708 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1709 DeleteDC( memdc );
1710 DeleteObject( bitmap );
1711 }
1712
1713 static void test_mono_bitmap(void)
1714 {
1715 static const COLORREF colors[][2] =
1716 {
1717 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff) },
1718 { RGB(0xff,0xff,0xff), RGB(0x00,0x00,0x00) },
1719 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xfe) },
1720 { RGB(0x00,0x01,0x00), RGB(0xff,0xff,0xff) },
1721 { RGB(0x00,0x00,0x00), RGB(0x80,0x80,0x80) },
1722 { RGB(0x80,0x80,0x80), RGB(0xff,0xff,0xff) },
1723 { RGB(0x30,0x40,0x50), RGB(0x60,0x70,0x80) },
1724 { RGB(0xa0,0xa0,0xa0), RGB(0x20,0x30,0x10) },
1725 { PALETTEINDEX(0), PALETTEINDEX(255) },
1726 { PALETTEINDEX(1), PALETTEINDEX(2) },
1727 };
1728
1729 HBITMAP hbmp;
1730 HDC hdc;
1731 DWORD col;
1732 int i, r, g, b;
1733
1734 if (!winetest_interactive)
1735 {
1736 skip("ROSTESTS-153: Skipping test_mono_bitmap because it causes too many failures and takes too long\n");
1737 return;
1738 }
1739
1740 hdc = CreateCompatibleDC(0);
1741 assert(hdc != 0);
1742
1743 hbmp = CreateBitmap(16, 16, 1, 1, NULL);
1744 assert(hbmp != NULL);
1745
1746 SelectObject( hdc, hbmp );
1747
1748 for (col = 0; col < sizeof(colors) / sizeof(colors[0]); col++)
1749 {
1750 SetTextColor( hdc, colors[col][0] );
1751 SetBkColor( hdc, colors[col][1] );
1752
1753 for (i = 0; i < 256; i++)
1754 {
1755 HPALETTE pal = GetCurrentObject( hdc, OBJ_PAL );
1756 PALETTEENTRY ent;
1757
1758 if (!GetPaletteEntries( pal, i, 1, &ent )) GetPaletteEntries( pal, 0, 1, &ent );
1759 test_color( hdc, PALETTEINDEX(i), get_nearest( ent.peRed, ent.peGreen, ent.peBlue ));
1760 test_color( hdc, DIBINDEX(i), (i == 1) ? 0xffffff : 0x000000 );
1761 }
1762
1763 for (r = 0; r < 256; r += 15)
1764 for (g = 0; g < 256; g += 15)
1765 for (b = 0; b < 256; b += 15)
1766 test_bitmap_colors( hdc, colors[col][0], colors[col][1], r, g, b );
1767 }
1768
1769 DeleteDC(hdc);
1770 DeleteObject(hbmp);
1771 }
1772
1773 static void test_bmBits(void)
1774 {
1775 BYTE bits[4];
1776 HBITMAP hbmp;
1777 BITMAP bmp;
1778
1779 memset(bits, 0, sizeof(bits));
1780 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1781 ok(hbmp != NULL, "CreateBitmap failed\n");
1782
1783 memset(&bmp, 0xFF, sizeof(bmp));
1784 ok(GetObjectW(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1785 "GetObject failed or returned a wrong structure size\n");
1786 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1787
1788 DeleteObject(hbmp);
1789 }
1790
1791 static void test_GetDIBits_selected_DIB(UINT bpp)
1792 {
1793 HBITMAP dib;
1794 BITMAPINFO *info;
1795 BITMAPINFO *info2;
1796 void * bits;
1797 void * bits2;
1798 UINT dib_size, dib32_size;
1799 DWORD pixel;
1800 HDC dib_dc, dc;
1801 HBITMAP old_bmp;
1802 UINT i;
1803 int res;
1804
1805 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1806 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1807
1808 /* Create a DIB section with a color table */
1809
1810 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1811 info->bmiHeader.biWidth = 32;
1812 info->bmiHeader.biHeight = 32;
1813 info->bmiHeader.biPlanes = 1;
1814 info->bmiHeader.biBitCount = bpp;
1815 info->bmiHeader.biCompression = BI_RGB;
1816 info->bmiHeader.biXPelsPerMeter = 0;
1817 info->bmiHeader.biYPelsPerMeter = 0;
1818 info->bmiHeader.biClrUsed = 0;
1819 info->bmiHeader.biClrImportant = 0;
1820
1821 for (i=0; i < (1u << bpp); i++)
1822 {
1823 BYTE c = i * (1 << (8 - bpp));
1824 info->bmiColors[i].rgbRed = c;
1825 info->bmiColors[i].rgbGreen = c;
1826 info->bmiColors[i].rgbBlue = c;
1827 info->bmiColors[i].rgbReserved = 0;
1828 }
1829
1830 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1831 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1832 dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1833
1834 /* Set the bits of the DIB section */
1835 for (i=0; i < dib_size; i++)
1836 {
1837 ((BYTE *)bits)[i] = i % 256;
1838 }
1839
1840 /* Select the DIB into a DC */
1841 dib_dc = CreateCompatibleDC(NULL);
1842 old_bmp = SelectObject(dib_dc, dib);
1843 dc = CreateCompatibleDC(NULL);
1844 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
1845
1846 /* Copy the DIB attributes but not the color table */
1847 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1848
1849 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1850 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1851
1852 /* Compare the color table and the bits */
1853 for (i=0; i < (1u << bpp); i++)
1854 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1855 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1856 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1857 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1858 "color table entry %d differs (bpp %d)\n", i, bpp );
1859
1860 ok( !memcmp( bits, bits2, dib_size ), "bit mismatch (bpp %d)\n", bpp );
1861
1862 /* Test various combinations of lines = 0 and bits2 = NULL */
1863 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1864 res = GetDIBits( dc, dib, 0, 0, bits2, info2, DIB_RGB_COLORS );
1865 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1866 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1867 "color table mismatch (bpp %d)\n", bpp );
1868
1869 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1870 res = GetDIBits( dc, dib, 0, 0, NULL, info2, DIB_RGB_COLORS );
1871 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1872 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1873 "color table mismatch (bpp %d)\n", bpp );
1874
1875 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1876 res = GetDIBits( dc, dib, 0, info->bmiHeader.biHeight, NULL, 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 /* Map into a 32bit-DIB */
1882 info2->bmiHeader.biBitCount = 32;
1883 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1884 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1885
1886 /* Check if last pixel was set */
1887 pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
1888 ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
1889
1890 HeapFree(GetProcessHeap(), 0, bits2);
1891 DeleteDC(dc);
1892
1893 SelectObject(dib_dc, old_bmp);
1894 DeleteDC(dib_dc);
1895 DeleteObject(dib);
1896 HeapFree(GetProcessHeap(), 0, info2);
1897 HeapFree(GetProcessHeap(), 0, info);
1898 }
1899
1900 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1901 {
1902 HBITMAP ddb;
1903 BITMAPINFO *info;
1904 BITMAPINFO *info2;
1905 void * bits;
1906 void * bits2;
1907 HDC ddb_dc, dc;
1908 HBITMAP old_bmp;
1909 UINT width, height;
1910 UINT bpp;
1911 UINT i, j;
1912 int res;
1913
1914 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1915 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1916
1917 width = height = 16;
1918
1919 /* Create a DDB (device-dependent bitmap) */
1920 if (monochrome)
1921 {
1922 bpp = 1;
1923 ddb = CreateBitmap(width, height, 1, 1, NULL);
1924 }
1925 else
1926 {
1927 HDC screen_dc = GetDC(NULL);
1928 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1929 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1930 ReleaseDC(NULL, screen_dc);
1931 }
1932
1933 /* Set the pixels */
1934 ddb_dc = CreateCompatibleDC(NULL);
1935 old_bmp = SelectObject(ddb_dc, ddb);
1936 for (i = 0; i < width; i++)
1937 {
1938 for (j=0; j < height; j++)
1939 {
1940 BYTE c = (i * width + j) % 256;
1941 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1942 }
1943 }
1944 SelectObject(ddb_dc, old_bmp);
1945
1946 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1947 info->bmiHeader.biWidth = width;
1948 info->bmiHeader.biHeight = height;
1949 info->bmiHeader.biPlanes = 1;
1950 info->bmiHeader.biBitCount = bpp;
1951 info->bmiHeader.biCompression = BI_RGB;
1952
1953 dc = CreateCompatibleDC(NULL);
1954
1955 /* Fill in biSizeImage */
1956 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1957 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1958
1959 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1960 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1961
1962 /* Get the bits */
1963 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1964 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1965
1966 /* Copy the DIB attributes but not the color table */
1967 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1968
1969 /* Select the DDB into another DC */
1970 old_bmp = SelectObject(ddb_dc, ddb);
1971
1972 /* Get the bits */
1973 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1974 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1975
1976 /* Compare the color table and the bits */
1977 if (bpp <= 8)
1978 {
1979 for (i=0; i < (1u << bpp); i++)
1980 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1981 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1982 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1983 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1984 "color table entry %d differs (bpp %d)\n", i, bpp );
1985 }
1986
1987 ok( !memcmp( bits, bits2, info->bmiHeader.biSizeImage ), "bit mismatch (bpp %d)\n", bpp );
1988
1989 /* Test the palette */
1990 if (info2->bmiHeader.biBitCount <= 8)
1991 {
1992 WORD *colors = (WORD*)info2->bmiColors;
1993
1994 /* Get the palette indices */
1995 res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1996 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1997
1998 for (i = 0; i < (1 << info->bmiHeader.biBitCount); i++)
1999 ok( colors[i] == i, "%d: got %d (bpp %d)\n", i, colors[i], bpp );
2000 }
2001
2002 HeapFree(GetProcessHeap(), 0, bits2);
2003 HeapFree(GetProcessHeap(), 0, bits);
2004 DeleteDC(dc);
2005
2006 SelectObject(ddb_dc, old_bmp);
2007 DeleteDC(ddb_dc);
2008 DeleteObject(ddb);
2009 HeapFree(GetProcessHeap(), 0, info2);
2010 HeapFree(GetProcessHeap(), 0, info);
2011 }
2012
2013 static void test_GetDIBits(void)
2014 {
2015 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
2016 static const BYTE bmp_bits_1[16 * 2] =
2017 {
2018 0xff,0xff, 0,0, 0xff,0xff, 0,0,
2019 0xff,0xff, 0,0, 0xff,0xff, 0,0,
2020 0xff,0xff, 0,0, 0xff,0xff, 0,0,
2021 0xff,0xff, 0,0, 0xff,0xff, 0,0
2022 };
2023 /* 4-bytes aligned 1-bit DIB data: 16x16 */
2024 static const BYTE dib_bits_1[16 * 4] =
2025 {
2026 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
2027 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
2028 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
2029 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
2030 };
2031 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
2032 static const BYTE bmp_bits_24[16 * 16*3] =
2033 {
2034 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2035 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2036 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2037 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2038 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2039 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2040 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2041 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2042 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2043 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2044 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2045 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 };
2067 /* 4-bytes aligned 24-bit DIB data: 16x16 */
2068 static const BYTE dib_bits_24[16 * 16*3] =
2069 {
2070 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2071 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2072 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2073 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2074 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2075 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2076 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2077 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2078 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2079 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2080 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2081 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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 };
2103 HBITMAP hbmp;
2104 BITMAP bm;
2105 HDC hdc;
2106 int i, bytes, lines;
2107 BYTE buf[1024];
2108 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
2109 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
2110 RGBQUAD *colors = bi->bmiColors;
2111 PALETTEENTRY pal_ents[20];
2112
2113 hdc = GetDC(0);
2114
2115 /* 1-bit source bitmap data */
2116 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
2117 ok(hbmp != 0, "CreateBitmap failed\n");
2118
2119 memset(&bm, 0xAA, sizeof(bm));
2120 bytes = GetObjectW(hbmp, sizeof(bm), &bm);
2121 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2122 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2123 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
2124 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
2125 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2126 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
2127 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2128 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2129
2130 bytes = GetBitmapBits(hbmp, 0, NULL);
2131 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
2132 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
2133 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
2134 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
2135
2136 /* retrieve 1-bit DIB data */
2137 memset(bi, 0, sizeof(*bi));
2138 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2139 bi->bmiHeader.biWidth = bm.bmWidth;
2140 bi->bmiHeader.biHeight = bm.bmHeight;
2141 bi->bmiHeader.biPlanes = 1;
2142 bi->bmiHeader.biBitCount = 1;
2143 bi->bmiHeader.biCompression = BI_RGB;
2144 bi->bmiHeader.biClrUsed = 37;
2145 bi->bmiHeader.biSizeImage = 0;
2146 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2147 SetLastError(0xdeadbeef);
2148 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2149 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
2150 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
2151 broken(GetLastError() == 0xdeadbeef), /* winnt */
2152 "wrong error %u\n", GetLastError());
2153 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
2154 ok(bi->bmiHeader.biClrUsed == 37 || broken(bi->bmiHeader.biClrUsed == 0),
2155 "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2156
2157 memset(buf, 0xAA, sizeof(buf));
2158 SetLastError(0xdeadbeef);
2159 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2160 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2161 lines, bm.bmHeight, GetLastError());
2162 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
2163 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2164
2165 /* the color table consists of black and white */
2166 ok(colors[0].rgbRed == 0 && colors[0].rgbGreen == 0 &&
2167 colors[0].rgbBlue == 0 && colors[0].rgbReserved == 0,
2168 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
2169 colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue, colors[0].rgbReserved);
2170 ok(colors[1].rgbRed == 0xff && colors[1].rgbGreen == 0xff &&
2171 colors[1].rgbBlue == 0xff && colors[1].rgbReserved == 0,
2172 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
2173 colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue, colors[1].rgbReserved);
2174 for (i = 2; i < 256; i++)
2175 {
2176 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2177 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2178 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2179 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2180 }
2181
2182 /* returned bits are DWORD aligned and upside down */
2183 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
2184
2185 /* Test the palette indices */
2186 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2187 SetLastError(0xdeadbeef);
2188 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
2189 ok(((WORD*)colors)[0] == 0, "Color 0 is %d\n", ((WORD*)colors)[0]);
2190 ok(((WORD*)colors)[1] == 1, "Color 1 is %d\n", ((WORD*)colors)[1]);
2191 for (i = 2; i < 256; i++)
2192 ok(((WORD*)colors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)colors)[1]);
2193
2194 /* retrieve 24-bit DIB data */
2195 memset(bi, 0, sizeof(*bi));
2196 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2197 bi->bmiHeader.biWidth = bm.bmWidth;
2198 bi->bmiHeader.biHeight = bm.bmHeight;
2199 bi->bmiHeader.biPlanes = 1;
2200 bi->bmiHeader.biBitCount = 24;
2201 bi->bmiHeader.biCompression = BI_RGB;
2202 bi->bmiHeader.biClrUsed = 37;
2203 bi->bmiHeader.biSizeImage = 0;
2204 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2205 memset(buf, 0xAA, sizeof(buf));
2206 SetLastError(0xdeadbeef);
2207 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2208 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2209 lines, bm.bmHeight, GetLastError());
2210 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2211 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2212
2213 /* the color table doesn't exist for 24-bit images */
2214 for (i = 0; i < 256; i++)
2215 {
2216 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2217 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2218 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2219 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2220 }
2221
2222 /* returned bits are DWORD aligned and upside down */
2223 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2224 DeleteObject(hbmp);
2225
2226 /* 24-bit source bitmap data */
2227 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
2228 ok(hbmp != 0, "CreateBitmap failed\n");
2229 SetLastError(0xdeadbeef);
2230 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
2231 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
2232 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
2233 lines, bm.bmHeight, GetLastError());
2234
2235 memset(&bm, 0xAA, sizeof(bm));
2236 bytes = GetObjectW(hbmp, sizeof(bm), &bm);
2237 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2238 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2239 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
2240 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
2241 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2242 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
2243 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2244 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2245
2246 bytes = GetBitmapBits(hbmp, 0, NULL);
2247 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
2248 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
2249 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
2250 bm.bmWidthBytes * bm.bmHeight, bytes);
2251
2252 /* retrieve 1-bit DIB data */
2253 memset(bi, 0, sizeof(*bi));
2254 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2255 bi->bmiHeader.biWidth = bm.bmWidth;
2256 bi->bmiHeader.biHeight = bm.bmHeight;
2257 bi->bmiHeader.biPlanes = 1;
2258 bi->bmiHeader.biBitCount = 1;
2259 bi->bmiHeader.biCompression = BI_RGB;
2260 bi->bmiHeader.biClrUsed = 37;
2261 bi->bmiHeader.biSizeImage = 0;
2262 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2263 memset(buf, 0xAA, sizeof(buf));
2264 SetLastError(0xdeadbeef);
2265 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2266 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2267 lines, bm.bmHeight, GetLastError());
2268 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
2269 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2270
2271 /* the color table consists of black and white */
2272 ok(colors[0].rgbRed == 0 && colors[0].rgbGreen == 0 &&
2273 colors[0].rgbBlue == 0 && colors[0].rgbReserved == 0,
2274 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
2275 colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue, colors[0].rgbReserved);
2276 ok(colors[1].rgbRed == 0xff && colors[1].rgbGreen == 0xff &&
2277 colors[1].rgbBlue == 0xff && colors[1].rgbReserved == 0,
2278 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
2279 colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue, colors[1].rgbReserved);
2280 for (i = 2; i < 256; i++)
2281 {
2282 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2283 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2284 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2285 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2286 }
2287
2288 /* returned bits are DWORD aligned and upside down */
2289 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
2290
2291 /* Test the palette indices */
2292 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2293 SetLastError(0xdeadbeef);
2294 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
2295 ok(((WORD*)colors)[0] == 0, "Color 0 is %d\n", ((WORD*)colors)[0]);
2296 ok(((WORD*)colors)[1] == 1, "Color 1 is %d\n", ((WORD*)colors)[1]);
2297 for (i = 2; i < 256; i++)
2298 ok(((WORD*)colors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)colors)[i]);
2299
2300 /* retrieve 4-bit DIB data */
2301 memset(bi, 0, sizeof(*bi));
2302 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2303 bi->bmiHeader.biWidth = bm.bmWidth;
2304 bi->bmiHeader.biHeight = bm.bmHeight;
2305 bi->bmiHeader.biPlanes = 1;
2306 bi->bmiHeader.biBitCount = 4;
2307 bi->bmiHeader.biCompression = BI_RGB;
2308 bi->bmiHeader.biClrUsed = 37;
2309 bi->bmiHeader.biSizeImage = 0;
2310 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2311 memset(buf, 0xAA, sizeof(buf));
2312 SetLastError(0xdeadbeef);
2313 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2314 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2315 lines, bm.bmHeight, GetLastError());
2316 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2317
2318 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2319
2320 for (i = 0; i < 16; i++)
2321 {
2322 RGBQUAD expect;
2323 int entry = i < 8 ? i : i + 4;
2324
2325 if(entry == 7) entry = 12;
2326 else if(entry == 12) entry = 7;
2327
2328 expect.rgbRed = pal_ents[entry].peRed;
2329 expect.rgbGreen = pal_ents[entry].peGreen;
2330 expect.rgbBlue = pal_ents[entry].peBlue;
2331 expect.rgbReserved = 0;
2332
2333 ok(!memcmp(colors + i, &expect, sizeof(expect)),
2334 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2335 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2336 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2337 }
2338
2339 /* retrieve 8-bit DIB data */
2340 memset(bi, 0, sizeof(*bi));
2341 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2342 bi->bmiHeader.biWidth = bm.bmWidth;
2343 bi->bmiHeader.biHeight = bm.bmHeight;
2344 bi->bmiHeader.biPlanes = 1;
2345 bi->bmiHeader.biBitCount = 8;
2346 bi->bmiHeader.biCompression = BI_RGB;
2347 bi->bmiHeader.biClrUsed = 37;
2348 bi->bmiHeader.biSizeImage = 0;
2349 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2350 memset(buf, 0xAA, sizeof(buf));
2351 SetLastError(0xdeadbeef);
2352 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2353 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2354 lines, bm.bmHeight, GetLastError());
2355 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2356
2357 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2358
2359 for (i = 0; i < 256; i++)
2360 {
2361 RGBQUAD expect;
2362
2363 if (i < 10 || i >= 246)
2364 {
2365 int entry = i < 10 ? i : i - 236;
2366 expect.rgbRed = pal_ents[entry].peRed;
2367 expect.rgbGreen = pal_ents[entry].peGreen;
2368 expect.rgbBlue = pal_ents[entry].peBlue;
2369 }
2370 else
2371 {
2372 expect.rgbRed = (i & 0x07) << 5;
2373 expect.rgbGreen = (i & 0x38) << 2;
2374 expect.rgbBlue = i & 0xc0;
2375 }
2376 expect.rgbReserved = 0;
2377
2378 ok(!memcmp(colors + i, &expect, sizeof(expect)),
2379 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2380 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2381 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2382 }
2383
2384 /* retrieve 24-bit DIB data */
2385 memset(bi, 0, sizeof(*bi));
2386 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2387 bi->bmiHeader.biWidth = bm.bmWidth;
2388 bi->bmiHeader.biHeight = bm.bmHeight;
2389 bi->bmiHeader.biPlanes = 1;
2390 bi->bmiHeader.biBitCount = 24;
2391 bi->bmiHeader.biCompression = BI_RGB;
2392 bi->bmiHeader.biClrUsed = 37;
2393 bi->bmiHeader.biSizeImage = 0;
2394 memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2395 memset(buf, 0xAA, sizeof(buf));
2396 SetLastError(0xdeadbeef);
2397 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2398 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2399 lines, bm.bmHeight, GetLastError());
2400 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2401 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2402
2403 /* the color table doesn't exist for 24-bit images */
2404 for (i = 0; i < 256; i++)
2405 {
2406 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2407 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2408 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2409 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2410 }
2411
2412 /* returned bits are DWORD aligned and upside down */
2413 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2414 DeleteObject(hbmp);
2415
2416 ReleaseDC(0, hdc);
2417 }
2418
2419 static void test_GetDIBits_BI_BITFIELDS(void)
2420 {
2421 /* Try a screen resolution detection technique
2422 * from the September 1999 issue of Windows Developer's Journal
2423 * which seems to be in widespread use.
2424 * http://www.lesher.ws/highcolor.html
2425 * http://www.lesher.ws/vidfmt.c
2426 * It hinges on being able to retrieve the bitmaps
2427 * for the three primary colors in non-paletted 16 bit mode.