Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / vcl / qa / cppunit / BitmapTest.cxx
blob4136dce65c01399faa84eac8acddf83a9c5dd1b9
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <cppunit/TestAssert.h>
11 #include <cppunit/TestFixture.h>
12 #include <cppunit/extensions/HelperMacros.h>
13 #include <cppunit/plugin/TestPlugIn.h>
15 #include <unordered_map>
17 #include <vcl/bitmap.hxx>
18 #include <vcl/bitmapaccess.hxx>
19 #include <vcl/virdev.hxx>
21 #include <rtl/strbuf.hxx>
22 #include <config_features.h>
23 #if HAVE_FEATURE_OPENGL
24 #include <vcl/opengl/OpenGLHelper.hxx>
25 #endif
26 #include <vcl/BitmapMonochromeFilter.hxx>
28 #include <bitmapwriteaccess.hxx>
30 #include <svdata.hxx>
31 #include <salinst.hxx>
32 #include <bitmap/Octree.hxx>
34 namespace
36 class BitmapTest : public CppUnit::TestFixture
38 void testCreation();
39 void testEmpty();
40 void testMonochrome();
41 void testN4Greyscale();
42 void testN8Greyscale();
43 void testConvert();
44 void testCRC();
45 void testGreyPalette();
46 void testCustom8BitPalette();
47 void testErase();
48 void testBitmap32();
49 void testOctree();
51 CPPUNIT_TEST_SUITE(BitmapTest);
52 CPPUNIT_TEST(testCreation);
53 CPPUNIT_TEST(testEmpty);
54 CPPUNIT_TEST(testMonochrome);
55 CPPUNIT_TEST(testConvert);
56 CPPUNIT_TEST(testN4Greyscale);
57 CPPUNIT_TEST(testN8Greyscale);
58 CPPUNIT_TEST(testCRC);
59 CPPUNIT_TEST(testGreyPalette);
60 CPPUNIT_TEST(testCustom8BitPalette);
61 CPPUNIT_TEST(testErase);
62 CPPUNIT_TEST(testBitmap32);
63 CPPUNIT_TEST(testOctree);
64 CPPUNIT_TEST_SUITE_END();
67 void assertColorsAreSimilar(int maxDifference, const std::string& message,
68 const BitmapColor& expected, const BitmapColor& actual)
70 // Check that the two colors match or are reasonably similar.
71 if (expected == actual)
72 return;
73 if (abs(expected.GetRed() - actual.GetRed()) <= maxDifference
74 && abs(expected.GetGreen() - actual.GetGreen()) <= maxDifference
75 && abs(expected.GetBlue() - actual.GetBlue()) <= maxDifference
76 && abs(expected.GetAlpha() - actual.GetAlpha()) <= maxDifference)
78 return;
80 CPPUNIT_ASSERT_EQUAL_MESSAGE(message, expected, actual);
83 void BitmapTest::testCreation()
86 Bitmap aBmp;
87 Size aSize = aBmp.GetSizePixel();
88 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong width", static_cast<long>(0), aSize.Width());
89 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong height", static_cast<long>(0), aSize.Height());
90 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong pref size", Size(), aBmp.GetPrefSize());
91 CPPUNIT_ASSERT_MESSAGE("Not empty", aBmp.IsEmpty());
92 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong bit count", static_cast<sal_uInt16>(0),
93 aBmp.GetBitCount());
94 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong color count", sal_Int64(1), aBmp.GetColorCount());
95 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong byte size", static_cast<sal_uLong>(0),
96 aBmp.GetSizeBytes());
100 Bitmap aBmp(Size(10, 10), 1);
101 Size aSize = aBmp.GetSizePixel();
102 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong width", static_cast<long>(10), aSize.Width());
103 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong height", static_cast<long>(10), aSize.Height());
104 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong pref size", Size(), aBmp.GetPrefSize());
105 CPPUNIT_ASSERT_MESSAGE("Empty bitmap", !aBmp.IsEmpty());
106 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong bit count", static_cast<sal_uInt16>(1),
107 aBmp.GetBitCount());
108 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong color count", sal_Int64(2), aBmp.GetColorCount());
109 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong byte size", static_cast<sal_uLong>(12),
110 aBmp.GetSizeBytes());
114 Bitmap aBmp(Size(10, 10), 4);
115 Size aSize = aBmp.GetSizePixel();
116 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong width", static_cast<long>(10), aSize.Width());
117 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong height", static_cast<long>(10), aSize.Height());
118 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong pref size", Size(), aBmp.GetPrefSize());
119 CPPUNIT_ASSERT_MESSAGE("Empty bitmap", !aBmp.IsEmpty());
120 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong bit count", static_cast<sal_uInt16>(4),
121 aBmp.GetBitCount());
122 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong color count", sal_Int64(16), aBmp.GetColorCount());
123 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong byte size", static_cast<sal_uLong>(50),
124 aBmp.GetSizeBytes());
128 Bitmap aBmp(Size(10, 10), 8);
129 Size aSize = aBmp.GetSizePixel();
130 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong width", static_cast<long>(10), aSize.Width());
131 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong height", static_cast<long>(10), aSize.Height());
132 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong pref size", Size(), aBmp.GetPrefSize());
133 CPPUNIT_ASSERT_MESSAGE("Empty bitmap", !aBmp.IsEmpty());
134 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong bit count", static_cast<sal_uInt16>(8),
135 aBmp.GetBitCount());
136 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong color count", sal_Int64(256), aBmp.GetColorCount());
137 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong byte size", static_cast<sal_uLong>(100),
138 aBmp.GetSizeBytes());
142 Bitmap aBmp(Size(10, 10), 24);
143 Size aSize = aBmp.GetSizePixel();
144 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong width", static_cast<long>(10), aSize.Width());
145 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong height", static_cast<long>(10), aSize.Height());
146 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong pref size", Size(), aBmp.GetPrefSize());
147 CPPUNIT_ASSERT_MESSAGE("Empty bitmap", !aBmp.IsEmpty());
148 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong bit count", static_cast<sal_uInt16>(24),
149 aBmp.GetBitCount());
150 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong color count", sal_Int64(16777216),
151 aBmp.GetColorCount());
152 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong byte size", static_cast<sal_uLong>(300),
153 aBmp.GetSizeBytes());
156 // Check backend capabilities and return from the test successfully
157 // if the backend doesn't support 32-bit bitmap
158 auto pBackendCapabilities = ImplGetSVData()->mpDefInst->GetBackendCapabilities();
159 if (pBackendCapabilities->mbSupportsBitmap32)
161 Bitmap aBmp(Size(10, 10), 32);
162 Size aSize = aBmp.GetSizePixel();
163 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong width", static_cast<long>(10), aSize.Width());
164 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong height", static_cast<long>(10), aSize.Height());
165 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong pref size", Size(), aBmp.GetPrefSize());
166 CPPUNIT_ASSERT_MESSAGE("Empty bitmap", !aBmp.IsEmpty());
168 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong bit count", sal_uInt16(32), aBmp.GetBitCount());
169 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong color count", sal_Int64(4294967296ull),
170 aBmp.GetColorCount());
171 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong byte size", sal_uLong(400), aBmp.GetSizeBytes());
175 void BitmapTest::testEmpty()
177 Bitmap aBitmap(Size(10, 10), 8);
178 aBitmap.Erase(COL_LIGHTGRAYBLUE);
180 CPPUNIT_ASSERT(!aBitmap.IsEmpty());
182 aBitmap.SetEmpty();
183 CPPUNIT_ASSERT(aBitmap.IsEmpty());
186 Bitmap createTestBitmap()
188 Bitmap aBmp(Size(4, 4), 24);
189 BitmapWriteAccess aBmpAccess(aBmp);
191 // row 1
192 aBmpAccess.SetPixel(0, 0, BitmapColor(COL_BLACK));
193 aBmpAccess.SetPixel(0, 1, BitmapColor(COL_BLUE));
194 aBmpAccess.SetPixel(0, 2, BitmapColor(COL_GREEN));
195 aBmpAccess.SetPixel(0, 3, BitmapColor(COL_CYAN));
197 // row 2
198 aBmpAccess.SetPixel(1, 0, BitmapColor(COL_RED));
199 aBmpAccess.SetPixel(1, 1, BitmapColor(COL_MAGENTA));
200 aBmpAccess.SetPixel(1, 2, BitmapColor(COL_BROWN));
201 aBmpAccess.SetPixel(1, 3, BitmapColor(COL_GRAY));
203 // row 3
204 aBmpAccess.SetPixel(2, 0, BitmapColor(COL_LIGHTGRAY));
205 aBmpAccess.SetPixel(2, 1, BitmapColor(COL_LIGHTBLUE));
206 aBmpAccess.SetPixel(2, 2, BitmapColor(COL_LIGHTGREEN));
207 aBmpAccess.SetPixel(2, 3, BitmapColor(COL_LIGHTCYAN));
209 // row 4
210 aBmpAccess.SetPixel(3, 0, BitmapColor(COL_LIGHTRED));
211 aBmpAccess.SetPixel(3, 1, BitmapColor(COL_LIGHTMAGENTA));
212 aBmpAccess.SetPixel(3, 2, BitmapColor(COL_YELLOW));
213 aBmpAccess.SetPixel(3, 3, BitmapColor(COL_WHITE));
215 return aBmp;
218 void BitmapTest::testMonochrome()
220 Bitmap aBmp = createTestBitmap();
222 BitmapEx aBmpEx(aBmp);
223 BitmapFilter::Filter(aBmpEx, BitmapMonochromeFilter(63));
224 aBmp = aBmpEx.GetBitmap();
225 BitmapReadAccess aBmpReadAccess(aBmp);
227 CPPUNIT_ASSERT_EQUAL_MESSAGE("Black pixel wrong monochrome value", BitmapColor(COL_BLACK),
228 aBmpReadAccess.GetColor(0, 0));
229 CPPUNIT_ASSERT_EQUAL_MESSAGE("Blue pixel wrong monochrome value", BitmapColor(COL_BLACK),
230 aBmpReadAccess.GetColor(0, 1));
231 CPPUNIT_ASSERT_EQUAL_MESSAGE("Green pixel wrong monochrome value", BitmapColor(COL_WHITE),
232 aBmpReadAccess.GetColor(0, 2));
233 CPPUNIT_ASSERT_EQUAL_MESSAGE("Cyan pixel wrong monochrome value", BitmapColor(COL_WHITE),
234 aBmpReadAccess.GetColor(0, 3));
235 CPPUNIT_ASSERT_EQUAL_MESSAGE("Red pixel wrong monochrome value", BitmapColor(COL_BLACK),
236 aBmpReadAccess.GetColor(1, 0));
237 CPPUNIT_ASSERT_EQUAL_MESSAGE("Magenta pixel wrong monochrome value", BitmapColor(COL_BLACK),
238 aBmpReadAccess.GetColor(1, 1));
239 CPPUNIT_ASSERT_EQUAL_MESSAGE("Brown pixel wrong monochrome value", BitmapColor(COL_WHITE),
240 aBmpReadAccess.GetColor(1, 2));
241 CPPUNIT_ASSERT_EQUAL_MESSAGE("Gray pixel wrong monochrome value", BitmapColor(COL_WHITE),
242 aBmpReadAccess.GetColor(1, 3));
243 CPPUNIT_ASSERT_EQUAL_MESSAGE("Light gray pixel wrong monochrome value", BitmapColor(COL_WHITE),
244 aBmpReadAccess.GetColor(2, 0));
245 CPPUNIT_ASSERT_EQUAL_MESSAGE("Light blue pixel wrong monochrome value", BitmapColor(COL_BLACK),
246 aBmpReadAccess.GetColor(2, 1));
247 CPPUNIT_ASSERT_EQUAL_MESSAGE("Light green pixel wrong monochrome value", BitmapColor(COL_WHITE),
248 aBmpReadAccess.GetColor(2, 2));
249 CPPUNIT_ASSERT_EQUAL_MESSAGE("Light cyan pixel wrong monochrome value", BitmapColor(COL_WHITE),
250 aBmpReadAccess.GetColor(2, 3));
251 CPPUNIT_ASSERT_EQUAL_MESSAGE("Light red pixel wrong monochrome value", BitmapColor(COL_WHITE),
252 aBmpReadAccess.GetColor(3, 0));
253 CPPUNIT_ASSERT_EQUAL_MESSAGE("Light magenta pixel wrong monochrome value",
254 BitmapColor(COL_WHITE), aBmpReadAccess.GetColor(3, 1));
255 CPPUNIT_ASSERT_EQUAL_MESSAGE("Yellow pixel wrong monochrome value", BitmapColor(COL_WHITE),
256 aBmpReadAccess.GetColor(3, 2));
257 CPPUNIT_ASSERT_EQUAL_MESSAGE("White pixel wrong monochrome value", BitmapColor(COL_WHITE),
258 aBmpReadAccess.GetColor(3, 3));
261 void BitmapTest::testN4Greyscale()
263 Bitmap aBmp = createTestBitmap();
264 BitmapPalette aGreyscalePalette = Bitmap::GetGreyPalette(16);
266 aBmp.Convert(BmpConversion::N4BitGreys);
267 BitmapReadAccess aBmpReadAccess(aBmp);
269 CPPUNIT_ASSERT_EQUAL_MESSAGE("Black pixel wrong 8-bit greyscale value", aGreyscalePalette[0],
270 aBmpReadAccess.GetColor(0, 0));
271 CPPUNIT_ASSERT_EQUAL_MESSAGE("Blue pixel wrong 8-bit greyscale value", aGreyscalePalette[0],
272 aBmpReadAccess.GetColor(0, 1));
273 CPPUNIT_ASSERT_EQUAL_MESSAGE("Green pixel wrong 8-bit greyscale value", aGreyscalePalette[4],
274 aBmpReadAccess.GetColor(0, 2));
275 CPPUNIT_ASSERT_EQUAL_MESSAGE("Cyan pixel wrong 8-bit greyscale value", aGreyscalePalette[5],
276 aBmpReadAccess.GetColor(0, 3));
277 CPPUNIT_ASSERT_EQUAL_MESSAGE("Red pixel wrong 8-bit greyscale value", aGreyscalePalette[2],
278 aBmpReadAccess.GetColor(1, 0));
279 CPPUNIT_ASSERT_EQUAL_MESSAGE("Magenta pixel wrong 8-bit greyscale value", aGreyscalePalette[3],
280 aBmpReadAccess.GetColor(1, 1));
281 CPPUNIT_ASSERT_EQUAL_MESSAGE("Brown pixel wrong 8-bit greyscale value", aGreyscalePalette[7],
282 aBmpReadAccess.GetColor(1, 2));
283 CPPUNIT_ASSERT_EQUAL_MESSAGE("Gray pixel wrong 8-bit greyscale value", aGreyscalePalette[8],
284 aBmpReadAccess.GetColor(1, 3));
285 CPPUNIT_ASSERT_EQUAL_MESSAGE("Light gray pixel wrong 8-bit greyscale value",
286 aGreyscalePalette[12], aBmpReadAccess.GetColor(2, 0));
287 CPPUNIT_ASSERT_EQUAL_MESSAGE("Light blue pixel wrong 8-bit greyscale value",
288 aGreyscalePalette[1], aBmpReadAccess.GetColor(2, 1));
289 CPPUNIT_ASSERT_EQUAL_MESSAGE("Light green pixel wrong 8-bit greyscale value",
290 aGreyscalePalette[9], aBmpReadAccess.GetColor(2, 2));
291 CPPUNIT_ASSERT_EQUAL_MESSAGE("Light cyan pixel wrong 8-bit greyscale value",
292 aGreyscalePalette[11], aBmpReadAccess.GetColor(2, 3));
293 CPPUNIT_ASSERT_EQUAL_MESSAGE("Light red pixel wrong 8-bit greyscale value",
294 aGreyscalePalette[4], aBmpReadAccess.GetColor(3, 0));
295 CPPUNIT_ASSERT_EQUAL_MESSAGE("Light magenta pixel wrong 8-bit greyscale value",
296 aGreyscalePalette[6], aBmpReadAccess.GetColor(3, 1));
297 CPPUNIT_ASSERT_EQUAL_MESSAGE("Yellow pixel wrong 8-bit greyscale value", aGreyscalePalette[14],
298 aBmpReadAccess.GetColor(3, 2));
299 CPPUNIT_ASSERT_EQUAL_MESSAGE("White pixel wrong 8-bit greyscale value", aGreyscalePalette[15],
300 aBmpReadAccess.GetColor(3, 3));
303 void BitmapTest::testN8Greyscale()
305 Bitmap aBmp = createTestBitmap();
306 BitmapPalette aGreyscalePalette = Bitmap::GetGreyPalette(256);
308 aBmp.Convert(BmpConversion::N8BitGreys);
309 BitmapReadAccess aBmpReadAccess(aBmp);
311 assertColorsAreSimilar(1, "Black pixel wrong 8-bit greyscale value", aGreyscalePalette[0],
312 aBmpReadAccess.GetColor(0, 0));
313 assertColorsAreSimilar(1, "Blue pixel wrong 8-bit greyscale value", aGreyscalePalette[14],
314 aBmpReadAccess.GetColor(0, 1));
315 assertColorsAreSimilar(1, "Green pixel wrong 8-bit greyscale value", aGreyscalePalette[75],
316 aBmpReadAccess.GetColor(0, 2));
317 assertColorsAreSimilar(1, "Cyan pixel wrong 8-bit greyscale value", aGreyscalePalette[89],
318 aBmpReadAccess.GetColor(0, 3));
319 assertColorsAreSimilar(1, "Red pixel wrong 8-bit greyscale value", aGreyscalePalette[38],
320 aBmpReadAccess.GetColor(1, 0));
321 assertColorsAreSimilar(1, "Magenta pixel wrong 8-bit greyscale value", aGreyscalePalette[52],
322 aBmpReadAccess.GetColor(1, 1));
323 assertColorsAreSimilar(1, "Brown pixel wrong 8-bit greyscale value", aGreyscalePalette[114],
324 aBmpReadAccess.GetColor(1, 2));
325 assertColorsAreSimilar(1, "Gray pixel wrong 8-bit greyscale value", aGreyscalePalette[128],
326 aBmpReadAccess.GetColor(1, 3));
327 assertColorsAreSimilar(1, "Light gray pixel wrong 8-bit greyscale value",
328 aGreyscalePalette[192], aBmpReadAccess.GetColor(2, 0));
329 assertColorsAreSimilar(1, "Light blue pixel wrong 8-bit greyscale value", aGreyscalePalette[27],
330 aBmpReadAccess.GetColor(2, 1));
331 assertColorsAreSimilar(1, "Light green pixel wrong 8-bit greyscale value",
332 aGreyscalePalette[150], aBmpReadAccess.GetColor(2, 2));
333 assertColorsAreSimilar(1, "Light cyan pixel wrong 8-bit greyscale value",
334 aGreyscalePalette[178], aBmpReadAccess.GetColor(2, 3));
335 assertColorsAreSimilar(1, "Light red pixel wrong 8-bit greyscale value", aGreyscalePalette[76],
336 aBmpReadAccess.GetColor(3, 0));
337 assertColorsAreSimilar(1, "Light magenta pixel wrong 8-bit greyscale value",
338 aGreyscalePalette[104], aBmpReadAccess.GetColor(3, 1));
339 assertColorsAreSimilar(1, "Yellow pixel wrong 8-bit greyscale value", aGreyscalePalette[227],
340 aBmpReadAccess.GetColor(3, 2));
341 assertColorsAreSimilar(1, "White pixel wrong 8-bit greyscale value", aGreyscalePalette[255],
342 aBmpReadAccess.GetColor(3, 3));
345 void BitmapTest::testConvert()
347 Bitmap aBitmap(Size(10, 10), 8);
349 aBitmap.Erase(COL_LIGHTGRAYBLUE);
351 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(8), aBitmap.GetBitCount());
353 Bitmap::ScopedReadAccess pReadAccess(aBitmap);
354 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(8), pReadAccess->GetBitCount());
355 #if defined MACOSX || defined IOS
356 //it would be nice to find and change the stride for quartz to be the same as everyone else
357 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(10), pReadAccess->GetScanlineSize());
358 #else
359 #if HAVE_FEATURE_OPENGL
360 if (!OpenGLHelper::isVCLOpenGLEnabled())
361 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(12), pReadAccess->GetScanlineSize());
362 #endif
363 #endif
364 CPPUNIT_ASSERT(pReadAccess->HasPalette());
365 const BitmapColor& rColor = pReadAccess->GetPaletteColor(pReadAccess->GetPixelIndex(1, 1));
366 CPPUNIT_ASSERT_EQUAL(sal_Int32(204), sal_Int32(rColor.GetRed()));
367 CPPUNIT_ASSERT_EQUAL(sal_Int32(204), sal_Int32(rColor.GetGreen()));
368 CPPUNIT_ASSERT_EQUAL(sal_Int32(255), sal_Int32(rColor.GetBlue()));
371 aBitmap.Convert(BmpConversion::N24Bit);
373 CPPUNIT_ASSERT_EQUAL(sal_uInt16(24), aBitmap.GetBitCount());
375 Bitmap::ScopedReadAccess pReadAccess(aBitmap);
376 // 24 bit Bitmap on SVP backend can now use 24bit RGB everywhere.
377 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(24), pReadAccess->GetBitCount());
379 #if defined LINUX || defined FREEBSD
380 #if HAVE_FEATURE_OPENGL
381 if (OpenGLHelper::isVCLOpenGLEnabled())
382 CPPUNIT_ASSERT_EQUAL(sal_uInt32(30), pReadAccess->GetScanlineSize());
383 else
384 #endif
385 CPPUNIT_ASSERT_EQUAL(sal_uInt32(32), pReadAccess->GetScanlineSize());
386 #else
387 #if defined(_WIN32)
388 if (!OpenGLHelper::isVCLOpenGLEnabled())
390 // GDI Scanlines padded to DWORD multiples, it seems
391 CPPUNIT_ASSERT_EQUAL(sal_uInt32(32), pReadAccess->GetScanlineSize());
393 else
394 #endif
396 CPPUNIT_ASSERT_EQUAL(sal_uInt32(30), pReadAccess->GetScanlineSize());
398 #endif
400 CPPUNIT_ASSERT(!pReadAccess->HasPalette());
401 Color aColor = pReadAccess->GetPixel(0, 0);
402 CPPUNIT_ASSERT_EQUAL(sal_Int32(204), sal_Int32(aColor.GetRed()));
403 CPPUNIT_ASSERT_EQUAL(sal_Int32(204), sal_Int32(aColor.GetGreen()));
404 CPPUNIT_ASSERT_EQUAL(sal_Int32(255), sal_Int32(aColor.GetBlue()));
408 typedef std::unordered_map<sal_uInt64, const char*> CRCHash;
410 void checkAndInsert(CRCHash& rHash, sal_uInt64 nCRC, const char* pLocation)
412 auto it = rHash.find(nCRC);
413 if (it != rHash.end())
415 OStringBuffer aBuf("CRC collision between ");
416 aBuf.append(pLocation);
417 aBuf.append(" and ");
418 aBuf.append(it->second);
419 aBuf.append(" hash is 0x");
420 aBuf.append(static_cast<sal_Int64>(nCRC), 16);
421 CPPUNIT_FAIL(aBuf.toString().getStr());
423 rHash[nCRC] = pLocation;
426 void checkAndInsert(CRCHash& rHash, Bitmap const& rBmp, const char* pLocation)
428 checkAndInsert(rHash, rBmp.GetChecksum(), pLocation);
431 Bitmap getAsBitmap(VclPtr<OutputDevice> const& pOut)
433 return pOut->GetBitmap(Point(), pOut->GetOutputSizePixel());
436 void BitmapTest::testCRC()
438 CRCHash aCRCs;
440 Bitmap aBitmap(Size(1023, 759), 24, nullptr);
441 aBitmap.Erase(COL_BLACK);
442 checkAndInsert(aCRCs, aBitmap, "black bitmap");
443 aBitmap.Invert();
444 checkAndInsert(aCRCs, aBitmap, "white bitmap");
446 ScopedVclPtrInstance<VirtualDevice> aVDev;
447 aVDev->SetBackground(Wallpaper(COL_WHITE));
448 aVDev->SetOutputSizePixel(Size(1023, 759));
450 #if 0 // disabled for now - oddly breaks on OS/X - but why ?
451 Bitmap aWhiteCheck = getAsBitmap(aVDev);
452 CPPUNIT_ASSERT(aCRCs.find(aWhiteCheck.GetChecksum()) != aCRCs.end());
453 #endif
455 // a 1x1 black & white checkerboard
456 aVDev->DrawCheckered(Point(), aVDev->GetOutputSizePixel(), 1, Color(0, 0, 1));
457 Bitmap aChecker = getAsBitmap(aVDev);
458 checkAndInsert(aCRCs, aChecker, "checkerboard");
459 aChecker.Invert();
460 checkAndInsert(aCRCs, aChecker, "inverted checkerboard");
463 void BitmapTest::testGreyPalette()
466 BitmapPalette aPalette = Bitmap::GetGreyPalette(2);
467 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong number of palette entries", static_cast<sal_uInt16>(2),
468 aPalette.GetEntryCount());
469 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 1 wrong", BitmapColor(0, 0, 0), aPalette[0]);
470 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 2 wrong", BitmapColor(255, 255, 255), aPalette[1]);
474 BitmapPalette aPalette = Bitmap::GetGreyPalette(4);
475 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong number of palette entries", static_cast<sal_uInt16>(4),
476 aPalette.GetEntryCount());
477 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 1 wrong", BitmapColor(0, 0, 0), aPalette[0]);
478 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 2 wrong", BitmapColor(85, 85, 85), aPalette[1]);
479 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 3 wrong", BitmapColor(170, 170, 170), aPalette[2]);
480 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 4 wrong", BitmapColor(255, 255, 255), aPalette[3]);
484 BitmapPalette aPalette = Bitmap::GetGreyPalette(16);
485 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong number of palette entries", static_cast<sal_uInt16>(16),
486 aPalette.GetEntryCount());
487 // this is a *real* specific number of greys, incremented in units of 17 so may
488 // as well test them all...
489 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 1 wrong", BitmapColor(0, 0, 0), aPalette[0]);
490 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 2 wrong", BitmapColor(17, 17, 17), aPalette[1]);
491 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 3 wrong", BitmapColor(34, 34, 34), aPalette[2]);
492 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 4 wrong", BitmapColor(51, 51, 51), aPalette[3]);
493 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 5 wrong", BitmapColor(68, 68, 68), aPalette[4]);
494 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 6 wrong", BitmapColor(85, 85, 85), aPalette[5]);
495 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 7 wrong", BitmapColor(102, 102, 102), aPalette[6]);
496 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 8 wrong", BitmapColor(119, 119, 119), aPalette[7]);
497 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 9 wrong", BitmapColor(136, 136, 136), aPalette[8]);
498 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 10 wrong", BitmapColor(153, 153, 153), aPalette[9]);
499 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 11 wrong", BitmapColor(170, 170, 170), aPalette[10]);
500 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 12 wrong", BitmapColor(187, 187, 187), aPalette[11]);
501 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 13 wrong", BitmapColor(204, 204, 204), aPalette[12]);
502 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 14 wrong", BitmapColor(221, 221, 221), aPalette[13]);
503 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 15 wrong", BitmapColor(238, 238, 238), aPalette[14]);
504 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 16 wrong", BitmapColor(255, 255, 255), aPalette[15]);
508 BitmapPalette aPalette = Bitmap::GetGreyPalette(256);
509 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong number of palette entries",
510 static_cast<sal_uInt16>(256), aPalette.GetEntryCount());
511 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 1 wrong", BitmapColor(0, 0, 0), aPalette[0]);
512 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 127 wrong", BitmapColor(127, 127, 127), aPalette[127]);
513 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 255 wrong", BitmapColor(255, 255, 255), aPalette[255]);
517 void BitmapTest::testCustom8BitPalette()
519 BitmapPalette aCustomPalette;
520 aCustomPalette.SetEntryCount(256);
521 for (sal_uInt16 i = 0; i < 256; i++)
523 aCustomPalette[i] = BitmapColor(sal_uInt8(i), sal_uInt8(0xCC), sal_uInt8(0x22));
525 Bitmap aBitmap(Size(3, 2), 8, &aCustomPalette);
528 BitmapScopedWriteAccess pAccess(aBitmap);
529 pAccess->SetPixelIndex(0, 0, 0);
530 pAccess->SetPixelIndex(0, 1, 1);
531 pAccess->SetPixelIndex(0, 2, 2);
533 pAccess->SetPixelIndex(1, 0, 253);
534 pAccess->SetPixelIndex(1, 1, 254);
535 pAccess->SetPixelIndex(1, 2, 255);
539 Bitmap::ScopedReadAccess pAccess(aBitmap);
540 CPPUNIT_ASSERT_EQUAL(0, int(pAccess->GetPixelIndex(0, 0)));
541 CPPUNIT_ASSERT_EQUAL(BitmapColor(0x00, 0xCC, 0x22), pAccess->GetColor(0, 0));
543 CPPUNIT_ASSERT_EQUAL(1, int(pAccess->GetPixelIndex(0, 1)));
544 CPPUNIT_ASSERT_EQUAL(BitmapColor(0x01, 0xCC, 0x22), pAccess->GetColor(0, 1));
546 CPPUNIT_ASSERT_EQUAL(2, int(pAccess->GetPixelIndex(0, 2)));
547 CPPUNIT_ASSERT_EQUAL(BitmapColor(0x02, 0xCC, 0x22), pAccess->GetColor(0, 2));
549 CPPUNIT_ASSERT_EQUAL(253, int(pAccess->GetPixelIndex(1, 0)));
550 CPPUNIT_ASSERT_EQUAL(BitmapColor(0xFD, 0xCC, 0x22), pAccess->GetColor(1, 0));
552 CPPUNIT_ASSERT_EQUAL(254, int(pAccess->GetPixelIndex(1, 1)));
553 CPPUNIT_ASSERT_EQUAL(BitmapColor(0xFE, 0xCC, 0x22), pAccess->GetColor(1, 1));
555 CPPUNIT_ASSERT_EQUAL(255, int(pAccess->GetPixelIndex(1, 2)));
556 CPPUNIT_ASSERT_EQUAL(BitmapColor(0xFF, 0xCC, 0x22), pAccess->GetColor(1, 2));
560 void BitmapTest::testErase()
562 Bitmap aBitmap(Size(3, 3), 24);
564 BitmapScopedWriteAccess pWriteAccess(aBitmap);
565 pWriteAccess->Erase(Color(0x11, 0x22, 0x33));
568 Bitmap::ScopedReadAccess pReadAccess(aBitmap);
569 BitmapColor aColor(pReadAccess->GetPixel(0, 0));
570 CPPUNIT_ASSERT_EQUAL(BitmapColor(0x11, 0x22, 0x33, 0x00), aColor);
574 void BitmapTest::testBitmap32()
576 // Check backend capabilities and return from the test successfully
577 // if the backend doesn't support 32-bit bitmap
578 auto pBackendCapabilities = ImplGetSVData()->mpDefInst->GetBackendCapabilities();
579 if (!pBackendCapabilities->mbSupportsBitmap32)
580 return;
582 Bitmap aBitmap(Size(3, 3), 32);
584 BitmapScopedWriteAccess pWriteAccess(aBitmap);
585 pWriteAccess->Erase(Color(0xFF, 0x11, 0x22, 0x33));
586 pWriteAccess->SetPixel(1, 1, BitmapColor(0x44, 0xFF, 0xBB, 0x00));
587 pWriteAccess->SetPixel(2, 2, BitmapColor(0x99, 0x77, 0x66, 0x55));
590 Bitmap::ScopedReadAccess pReadAccess(aBitmap);
591 BitmapColor aColor = pReadAccess->GetPixel(0, 0);
592 CPPUNIT_ASSERT_EQUAL(BitmapColor(0x00, 0x00, 0x00, 0xFF), aColor);
594 aColor = pReadAccess->GetPixel(1, 1);
595 CPPUNIT_ASSERT_EQUAL(BitmapColor(0x44, 0xFF, 0xBB, 0x00), aColor);
597 aColor = pReadAccess->GetPixel(2, 2);
598 CPPUNIT_ASSERT_EQUAL(BitmapColor(0x99, 0x77, 0x66, 0x55), aColor);
602 void BitmapTest::testOctree()
604 Size aSize(1000, 100);
605 Bitmap aBitmap(aSize, 24);
607 BitmapScopedWriteAccess pWriteAccess(aBitmap);
608 for (long y = 0; y < aSize.Height(); ++y)
610 for (long x = 0; x < aSize.Width(); ++x)
612 double fPercent = double(x) / double(aSize.Width());
613 pWriteAccess->SetPixel(y, x,
614 BitmapColor(255.0 * fPercent, 64.0 + (128.0 * fPercent),
615 255.0 - 255.0 * fPercent));
621 // Reduce to 1 color
622 Bitmap::ScopedReadAccess pAccess(aBitmap);
623 Octree aOctree(*pAccess.get(), 1);
624 auto aBitmapPalette = aOctree.GetPalette();
625 CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), aBitmapPalette.GetEntryCount());
626 CPPUNIT_ASSERT_EQUAL(BitmapColor(0x7e, 0x7f, 0x7f), aBitmapPalette[0]);
630 // Reduce to 4 color
631 Bitmap::ScopedReadAccess pAccess(aBitmap);
632 Octree aOctree(*pAccess.get(), 4);
633 auto aBitmapPalette = aOctree.GetPalette();
634 CPPUNIT_ASSERT_EQUAL(sal_uInt16(4), aBitmapPalette.GetEntryCount());
635 CPPUNIT_ASSERT_EQUAL(BitmapColor(0x7f, 0x7f, 0x7f), aBitmapPalette[0]);
636 CPPUNIT_ASSERT_EQUAL(BitmapColor(0x3e, 0x5f, 0xbf), aBitmapPalette[1]);
637 CPPUNIT_ASSERT_EQUAL(BitmapColor(0x7f, 0x80, 0x7f), aBitmapPalette[2]);
638 CPPUNIT_ASSERT_EQUAL(BitmapColor(0xbe, 0x9f, 0x3f), aBitmapPalette[3]);
642 // Reduce to 256 color
643 Bitmap::ScopedReadAccess pAccess(aBitmap);
644 Octree aOctree(*pAccess.get(), 256);
645 auto aBitmapPalette = aOctree.GetPalette();
646 CPPUNIT_ASSERT_EQUAL(sal_uInt16(74), aBitmapPalette.GetEntryCount());
650 } // namespace
652 CPPUNIT_TEST_SUITE_REGISTRATION(BitmapTest);
654 CPPUNIT_PLUGIN_IMPLEMENT();
656 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */