2 * Unit test suite for bitmaps
4 * Copyright 2004 Huw Davies
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 #include "wine/test.h"
34 static void test_createdibitmap(void)
37 BITMAPINFOHEADER bmih;
39 HBITMAP hbm, hbm_colour, hbm_old;
43 screen_depth = GetDeviceCaps(hdc, BITSPIXEL);
44 memset(&bmih, 0, sizeof(bmih));
45 bmih.biSize = sizeof(bmih);
50 bmih.biCompression = BI_RGB;
52 /* First create an un-initialised bitmap. The depth of the bitmap
53 should match that of the hdc and not that supplied in bmih.
56 /* First try 32 bits */
57 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
58 ok(hbm != NULL, "CreateDIBitmap failed\n");
59 ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n");
61 ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth);
66 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
67 ok(hbm != NULL, "CreateDIBitmap failed\n");
68 ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n");
70 ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth);
75 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
76 ok(hbm != NULL, "CreateDIBitmap failed\n");
77 ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n");
79 ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth);
82 /* Now with a monochrome dc we expect a monochrome bitmap */
83 hdcmem = CreateCompatibleDC(hdc);
85 /* First try 32 bits */
87 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
88 ok(hbm != NULL, "CreateDIBitmap failed\n");
89 ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n");
91 ok(bm.bmBitsPixel == 1, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, 1);
96 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
97 ok(hbm != NULL, "CreateDIBitmap failed\n");
98 ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n");
100 ok(bm.bmBitsPixel == 1, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, 1);
105 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
106 ok(hbm != NULL, "CreateDIBitmap failed\n");
107 ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n");
109 ok(bm.bmBitsPixel == 1, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, 1);
112 /* Now select a polychrome bitmap into the dc and we expect
113 screen_depth bitmaps again */
114 hbm_colour = CreateCompatibleBitmap(hdc, 1, 1);
115 hbm_old = SelectObject(hdcmem, hbm_colour);
117 /* First try 32 bits */
118 bmih.biBitCount = 32;
119 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
120 ok(hbm != NULL, "CreateDIBitmap failed\n");
121 ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n");
123 ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth);
127 bmih.biBitCount = 16;
128 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
129 ok(hbm != NULL, "CreateDIBitmap failed\n");
130 ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n");
132 ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth);
137 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
138 ok(hbm != NULL, "CreateDIBitmap failed\n");
139 ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n");
141 ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth);
144 SelectObject(hdcmem, hbm_old);
145 DeleteObject(hbm_colour);
148 /* If hdc == 0 then we get a 1 bpp bitmap */
150 bmih.biBitCount = 32;
151 hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0);
152 ok(hbm != NULL, "CreateDIBitmap failed\n");
153 ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n");
155 ok(bm.bmBitsPixel == 1, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, 1);
162 #define test_color_todo(got, exp, txt, todo) \
163 if (todo) todo_wine { ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp); } \
164 else ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp)
166 #define test_color(hdc, color, exp, todo_setp, todo_getp) \
169 c = SetPixel(hdc, 0, 0, color); \
170 if (!is_win9x) { test_color_todo(c, exp, SetPixel, todo_setp); } \
171 c = GetPixel(hdc, 0, 0); \
172 test_color_todo(c, exp, GetPixel, todo_getp); \
175 static void test_dibsections(void)
177 HDC hdc, hdcmem, hdcmem2;
178 HBITMAP hdib, oldbm, hdib2, oldbm2;
179 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
180 char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
181 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
182 BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
188 char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
189 LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
192 HPALETTE hpal, oldpal;
197 memset(pbmi, 0, sizeof(bmibuf));
198 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
199 pbmi->bmiHeader.biHeight = 16;
200 pbmi->bmiHeader.biWidth = 16;
201 pbmi->bmiHeader.biBitCount = 1;
202 pbmi->bmiHeader.biPlanes = 1;
203 pbmi->bmiHeader.biCompression = BI_RGB;
204 pbmi->bmiColors[0].rgbRed = 0xff;
205 pbmi->bmiColors[0].rgbGreen = 0;
206 pbmi->bmiColors[0].rgbBlue = 0;
207 pbmi->bmiColors[1].rgbRed = 0;
208 pbmi->bmiColors[1].rgbGreen = 0;
209 pbmi->bmiColors[1].rgbBlue = 0xff;
211 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
212 ok(hdib != NULL, "CreateDIBSection failed\n");
214 /* Test if the old BITMAPCOREINFO structure is supported */
216 pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
217 pbci->bmciHeader.bcBitCount = 0;
220 ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
221 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
222 ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
223 && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
224 "GetDIBits did't fill in the BITMAPCOREHEADER structure properly\n");
226 ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
227 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
228 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
229 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
230 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
231 "The color table has not been translated to the old BITMAPCOREINFO format\n");
233 hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
234 ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
236 ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
237 ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
238 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
239 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
240 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
241 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
242 "The color table has not been translated to the old BITMAPCOREINFO format\n");
244 DeleteObject(hcoredib);
247 hdcmem = CreateCompatibleDC(hdc);
248 oldbm = SelectObject(hdcmem, hdib);
250 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
251 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
252 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
253 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
254 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
255 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
257 c0 = RGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen, pbmi->bmiColors[0].rgbBlue);
258 c1 = RGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen, pbmi->bmiColors[1].rgbBlue);
260 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
261 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
262 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
263 test_color(hdcmem, PALETTEINDEX(0), c0, 1, 1);
264 test_color(hdcmem, PALETTEINDEX(1), c0, 1, 1);
265 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
266 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen,
267 pbmi->bmiColors[0].rgbBlue), c0, 1, 1);
268 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen,
269 pbmi->bmiColors[1].rgbBlue), c1, 1, 1);
270 test_color(hdcmem, PALETTERGB(0, 0, 0), c0, 1, 1);
271 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
272 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1, 1, 1);
274 SelectObject(hdcmem, oldbm);
277 pbmi->bmiHeader.biBitCount = 8;
279 for (i = 0; i < 128; i++) {
280 pbmi->bmiColors[i].rgbRed = 255 - i * 2;
281 pbmi->bmiColors[i].rgbGreen = i * 2;
282 pbmi->bmiColors[i].rgbBlue = 0;
283 pbmi->bmiColors[255 - i].rgbRed = 0;
284 pbmi->bmiColors[255 - i].rgbGreen = i * 2;
285 pbmi->bmiColors[255 - i].rgbBlue = 255 - i * 2;
287 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
288 ok(hdib != NULL, "CreateDIBSection failed\n");
289 oldbm = SelectObject(hdcmem, hdib);
291 for (i = 0; i < 256; i++) {
292 test_color(hdcmem, DIBINDEX(i),
293 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
294 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue),
295 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
298 SelectObject(hdcmem, oldbm);
301 pbmi->bmiHeader.biBitCount = 1;
303 /* Now create a palette and a palette indexed dib section */
304 memset(plogpal, 0, sizeof(logpalbuf));
305 plogpal->palVersion = 0x300;
306 plogpal->palNumEntries = 2;
307 plogpal->palPalEntry[0].peRed = 0xff;
308 plogpal->palPalEntry[0].peBlue = 0xff;
309 plogpal->palPalEntry[1].peGreen = 0xff;
311 index = (WORD*)pbmi->bmiColors;
314 hpal = CreatePalette(plogpal);
315 ok(hpal != NULL, "CreatePalette failed\n");
316 oldpal = SelectPalette(hdc, hpal, TRUE);
317 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
318 ok(hdib != NULL, "CreateDIBSection failed\n");
320 /* The colour table has already been grabbed from the dc, so we select back the
323 SelectPalette(hdc, oldpal, TRUE);
324 oldbm = SelectObject(hdcmem, hdib);
325 oldpal = SelectPalette(hdcmem, hpal, TRUE);
327 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
328 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
329 ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
330 rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
331 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
332 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
333 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
335 c0 = RGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen, plogpal->palPalEntry[0].peBlue);
336 c1 = RGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen, plogpal->palPalEntry[1].peBlue);
338 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
339 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
340 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
341 test_color(hdcmem, PALETTEINDEX(0), c0, 0, 1);
342 test_color(hdcmem, PALETTEINDEX(1), c1, 0, 1);
343 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
344 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen,
345 plogpal->palPalEntry[0].peBlue), c0, 1, 1);
346 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen,
347 plogpal->palPalEntry[1].peBlue), c1, 1, 1);
348 test_color(hdcmem, PALETTERGB(0, 0, 0), c1, 1, 1);
349 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
350 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0, 1, 1);
351 test_color(hdcmem, PALETTERGB(0, 1, 0), c1, 1, 1);
352 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1, 1, 1);
353 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0, 1, 1);
355 /* Bottom and 2nd row from top green, everything else magenta */
356 bits[0] = bits[1] = 0xff;
357 bits[13 * 4] = bits[13*4 + 1] = 0xff;
360 pbmi->bmiHeader.biBitCount = 32;
362 hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
363 ok(hdib2 != NULL, "CreateDIBSection failed\n");
364 hdcmem2 = CreateCompatibleDC(hdc);
365 oldbm2 = SelectObject(hdcmem2, hdib2);
367 BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
369 ok(bits32[0] == 0xff00, "lower left pixel is %08lx\n", bits32[0]);
370 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08lx\n", bits32[17]);
372 SelectObject(hdcmem2, oldbm2);
375 SelectObject(hdcmem, oldbm);
376 SelectObject(hdcmem, oldpal);
381 pbmi->bmiHeader.biBitCount = 8;
383 memset(plogpal, 0, sizeof(logpalbuf));
384 plogpal->palVersion = 0x300;
385 plogpal->palNumEntries = 256;
387 for (i = 0; i < 128; i++) {
388 plogpal->palPalEntry[i].peRed = 255 - i * 2;
389 plogpal->palPalEntry[i].peBlue = i * 2;
390 plogpal->palPalEntry[i].peGreen = 0;
391 plogpal->palPalEntry[255 - i].peRed = 0;
392 plogpal->palPalEntry[255 - i].peGreen = i * 2;
393 plogpal->palPalEntry[255 - i].peBlue = 255 - i * 2;
396 index = (WORD*)pbmi->bmiColors;
397 for (i = 0; i < 256; i++) {
401 hpal = CreatePalette(plogpal);
402 ok(hpal != NULL, "CreatePalette failed\n");
403 oldpal = SelectPalette(hdc, hpal, TRUE);
404 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
405 ok(hdib != NULL, "CreateDIBSection failed\n");
407 SelectPalette(hdc, oldpal, TRUE);
408 oldbm = SelectObject(hdcmem, hdib);
409 oldpal = SelectPalette(hdcmem, hpal, TRUE);
411 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
412 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
413 for (i = 0; i < 256; i++) {
414 ok(rgb[i].rgbRed == plogpal->palPalEntry[i].peRed &&
415 rgb[i].rgbBlue == plogpal->palPalEntry[i].peBlue &&
416 rgb[i].rgbGreen == plogpal->palPalEntry[i].peGreen,
417 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
418 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
421 for (i = 0; i < 256; i++) {
422 test_color(hdcmem, DIBINDEX(i),
423 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
424 test_color(hdcmem, PALETTEINDEX(i),
425 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
426 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue),
427 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
430 SelectPalette(hdcmem, oldpal, TRUE);
431 SelectObject(hdcmem, oldbm);
444 hWnd = CreateWindowExA(0, "EDIT", NULL, 0,
446 NULL, NULL, NULL, NULL);
448 is_win9x = GetWindowLongW(hWnd, GWL_WNDPROC) == 0;
451 test_createdibitmap();